[med-svn] [libbpp-phyl] 01/02: Imported Upstream version 2.2.0

Andreas Tille tille at debian.org
Wed Apr 13 13:38:59 UTC 2016


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

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

commit 1c804a79a699cbea8ccbdbf0332152c6765679a7
Author: Andreas Tille <tille at debian.org>
Date:   Wed Apr 13 15:36:26 2016 +0200

    Imported Upstream version 2.2.0
---
 CMakeLists.txt                                     |   13 +-
 ChangeLog                                          |   15 +
 Doxyfile                                           |    8 +-
 bpp-phyl.spec                                      |    5 +-
 debian/changelog                                   |    7 +
 debian/control                                     |    8 +-
 debian/copyright                                   |    6 +-
 debian/postinst                                    |   22 +-
 debian/postrm                                      |   26 +-
 debian/prerm                                       |   22 +-
 debian/rules                                       |    4 +-
 debian/postinst => genIncludes.sh                  |   10 +-
 src/Bpp/Phyl/App/PhylogeneticsApplicationTools.cpp |  513 +++--
 src/Bpp/Phyl/App/PhylogeneticsApplicationTools.h   |  319 ++-
 src/Bpp/Phyl/BipartitionList.cpp                   |   20 +-
 src/Bpp/Phyl/BipartitionTools.cpp                  |   93 +-
 src/Bpp/Phyl/BipartitionTools.h                    |   12 +-
 .../AbstractAgglomerativeDistanceMethod.cpp        |    4 +-
 .../Distance/AbstractAgglomerativeDistanceMethod.h |    2 +-
 src/Bpp/Phyl/Distance/BioNJ.h                      |    2 +-
 src/Bpp/Phyl/Distance/DistanceEstimation.cpp       |   12 +-
 src/Bpp/Phyl/Distance/DistanceEstimation.h         |   10 +-
 src/Bpp/Phyl/Distance/DistanceMethod.h             |    4 +-
 src/Bpp/Phyl/Distance/NeighborJoining.h            |    2 +-
 src/Bpp/Phyl/Distance/PGMA.h                       |    2 +-
 .../Phyl/Graphics/TreeDrawingDisplayControler.h    |    8 +-
 src/Bpp/Phyl/Io/BppOFrequenciesSetFormat.cpp       |  235 +-
 src/Bpp/Phyl/Io/BppOFrequenciesSetFormat.h         |   63 +-
 src/Bpp/Phyl/Io/BppOSubstitutionModelFormat.cpp    |  214 +-
 src/Bpp/Phyl/Io/BppOSubstitutionModelFormat.h      |   47 +-
 src/Bpp/Phyl/Io/IoDistanceMatrixFactory.cpp        |    8 +-
 src/Bpp/Phyl/Io/IoDistanceMatrixFactory.h          |   12 +-
 src/Bpp/Phyl/Io/IoFrequenciesSetFactory.cpp        |    4 +-
 src/Bpp/Phyl/Io/IoPairedSiteLikelihoods.cpp        |    2 +-
 src/Bpp/Phyl/Io/IoSubstitutionModelFactory.cpp     |    6 +-
 ...bstractDiscreteRatesAcrossSitesTreeLikelihood.h |   94 +-
 .../AbstractHomogeneousTreeLikelihood.cpp          |    5 +-
 .../Likelihood/AbstractHomogeneousTreeLikelihood.h |  150 +-
 .../AbstractNonHomogeneousTreeLikelihood.cpp       |  401 ++--
 .../AbstractNonHomogeneousTreeLikelihood.h         |   16 +-
 src/Bpp/Phyl/Likelihood/AbstractTreeLikelihood.h   |   89 +-
 .../DRHomogeneousMixedTreeLikelihood.cpp           |   36 +-
 .../Likelihood/DRHomogeneousMixedTreeLikelihood.h  |   14 +-
 .../Likelihood/DRHomogeneousTreeLikelihood.cpp     |   92 +-
 .../Phyl/Likelihood/DRHomogeneousTreeLikelihood.h  |    2 +-
 .../Likelihood/DRNonHomogeneousTreeLikelihood.cpp  |    6 +-
 .../MarginalAncestralStateReconstruction.cpp       |   10 +-
 .../MarginalAncestralStateReconstruction.h         |    2 +-
 src/Bpp/Phyl/Likelihood/PairedSiteLikelihoods.cpp  |    2 +-
 .../Phyl/Likelihood/RHomogeneousTreeLikelihood.cpp |    4 +-
 .../RNonHomogeneousMixedTreeLikelihood.cpp         |   26 +-
 .../Likelihood/RNonHomogeneousTreeLikelihood.cpp   |    6 +-
 .../Likelihood/RNonHomogeneousTreeLikelihood.h     |    2 +-
 .../Phyl/Likelihood/SitePartitionTreeLikelihood.h  |   18 +-
 src/Bpp/Phyl/Likelihood/TreeLikelihood.h           |   19 +-
 src/Bpp/Phyl/Mapping/DecompositionReward.cpp       |  214 ++
 src/Bpp/Phyl/Mapping/DecompositionReward.h         |  144 ++
 .../Mapping/DecompositionSubstitutionCount.cpp     |   29 +-
 .../Phyl/Mapping/DecompositionSubstitutionCount.h  |    6 +-
 src/Bpp/Phyl/Mapping/LaplaceSubstitutionCount.cpp  |    8 +-
 src/Bpp/Phyl/Mapping/LaplaceSubstitutionCount.h    |   10 +-
 .../Mapping/{SubstitutionMapping.h => Mapping.h}   |  155 +-
 src/Bpp/Phyl/Mapping/NaiveSubstitutionCount.cpp    |   21 +-
 src/Bpp/Phyl/Mapping/NaiveSubstitutionCount.h      |   36 +-
 src/Bpp/Phyl/Mapping/OneJumpSubstitutionCount.h    |   30 +-
 .../ProbabilisticRewardMapping.cpp}                |   54 +-
 src/Bpp/Phyl/Mapping/ProbabilisticRewardMapping.h  |  177 ++
 .../Mapping/ProbabilisticSubstitutionMapping.h     |    6 +-
 src/Bpp/Phyl/Mapping/Reward.h                      |  205 ++
 .../RewardMapping.h}                               |   82 +-
 src/Bpp/Phyl/Mapping/RewardMappingTools.cpp        |  447 ++++
 src/Bpp/Phyl/Mapping/RewardMappingTools.h          |  136 ++
 src/Bpp/Phyl/Mapping/SubstitutionCount.h           |   35 +-
 src/Bpp/Phyl/Mapping/SubstitutionMapping.h         |  167 +-
 src/Bpp/Phyl/Mapping/SubstitutionMappingTools.cpp  | 1539 ++++++++++---
 src/Bpp/Phyl/Mapping/SubstitutionMappingTools.h    |  619 +++--
 .../SubstitutionRegister.cpp}                      |   28 +-
 src/Bpp/Phyl/Mapping/SubstitutionRegister.h        |  543 ++++-
 .../Mapping/UniformizationSubstitutionCount.cpp    |   75 +-
 .../Phyl/Mapping/UniformizationSubstitutionCount.h |    6 +-
 src/Bpp/Phyl/Mapping/WeightedSubstitutionCount.h   |   21 +-
 .../Model/AbstractBiblioMixedSubstitutionModel.h   |    3 +-
 .../Phyl/Model/AbstractBiblioSubstitutionModel.h   |   12 +-
 .../Phyl/Model/AbstractMixedSubstitutionModel.cpp  |  247 +-
 .../Phyl/Model/AbstractMixedSubstitutionModel.h    |  394 ++--
 src/Bpp/Phyl/Model/AbstractSubstitutionModel.cpp   |   19 +-
 src/Bpp/Phyl/Model/AbstractSubstitutionModel.h     |   52 +-
 .../Phyl/Model/AbstractWordSubstitutionModel.cpp   |  108 +-
 src/Bpp/Phyl/Model/AbstractWordSubstitutionModel.h |   20 +-
 src/Bpp/Phyl/Model/BinarySubstitutionModel.cpp     |    4 +-
 .../AbstractCodonDistanceSubstitutionModel.cpp     |    8 +-
 .../Codon/AbstractCodonDistanceSubstitutionModel.h |   29 +-
 .../AbstractCodonFitnessSubstitutionModel.cpp      |    4 +-
 .../Codon/AbstractCodonFitnessSubstitutionModel.h  |    2 +-
 .../AbstractCodonFrequenciesSubstitutionModel.cpp  |    2 +-
 ...tractCodonPhaseFrequenciesSubstitutionModel.cpp |   30 +-
 ...bstractCodonPhaseFrequenciesSubstitutionModel.h |   18 +-
 .../Model/Codon/AbstractCodonSubstitutionModel.cpp |   53 +-
 .../Model/Codon/AbstractCodonSubstitutionModel.h   |   53 +-
 ...nceFitnessPhaseFrequenciesSubstitutionModel.cpp |   56 +-
 ...tanceFitnessPhaseFrequenciesSubstitutionModel.h |   68 +-
 .../CodonDistanceFrequenciesSubstitutionModel.cpp  |   40 +-
 .../CodonDistanceFrequenciesSubstitutionModel.h    |   57 +-
 ...onDistancePhaseFrequenciesSubstitutionModel.cpp |   36 +-
 ...odonDistancePhaseFrequenciesSubstitutionModel.h |   51 +-
 .../Model/Codon/CodonDistanceSubstitutionModel.cpp |   38 +-
 .../Model/Codon/CodonDistanceSubstitutionModel.h   |   45 +-
 .../CodonRateFrequenciesSubstitutionModel.cpp      |   28 +-
 .../Codon/CodonRateFrequenciesSubstitutionModel.h  |   44 +-
 .../Model/Codon/CodonRateSubstitutionModel.cpp     |   24 +-
 .../Phyl/Model/Codon/CodonRateSubstitutionModel.h  |   37 +-
 src/Bpp/Phyl/Model/Codon/CodonSubstitutionModel.h  |   10 +-
 .../Phyl/Model/Codon/TripletSubstitutionModel.cpp  |    6 +-
 src/Bpp/Phyl/Model/Codon/YN98.cpp                  |    2 +-
 src/Bpp/Phyl/Model/Codon/YN98.h                    |    7 +-
 src/Bpp/Phyl/Model/Codon/YNGKP_M1.cpp              |   20 +-
 src/Bpp/Phyl/Model/Codon/YNGKP_M1.h                |    9 +-
 src/Bpp/Phyl/Model/Codon/YNGKP_M2.cpp              |   18 +-
 src/Bpp/Phyl/Model/Codon/YNGKP_M2.h                |   11 +-
 src/Bpp/Phyl/Model/Codon/YNGKP_M3.cpp              |   26 +-
 src/Bpp/Phyl/Model/Codon/YNGKP_M3.h                |   10 +-
 src/Bpp/Phyl/Model/Codon/YNGKP_M7.cpp              |   16 +-
 src/Bpp/Phyl/Model/Codon/YNGKP_M7.h                |    9 +-
 src/Bpp/Phyl/Model/Codon/YNGKP_M8.cpp              |   14 +-
 src/Bpp/Phyl/Model/Codon/YNGKP_M8.h                |    9 +-
 .../Model/FrequenciesSet/CodonFrequenciesSet.cpp   |  564 ++---
 .../Model/FrequenciesSet/CodonFrequenciesSet.h     |  680 +++---
 .../Phyl/Model/FrequenciesSet/FrequenciesSet.cpp   |  133 +-
 src/Bpp/Phyl/Model/FrequenciesSet/FrequenciesSet.h |  114 +-
 .../Model/FrequenciesSet/MvaFrequenciesSet.cpp     |   10 +-
 .../FrequenciesSet/NucleotideFrequenciesSet.cpp    |    4 +-
 .../FrequenciesSet/NucleotideFrequenciesSet.h      |   10 +-
 .../Model/FrequenciesSet/ProteinFrequenciesSet.h   |   23 +-
 .../Model/FrequenciesSet/WordFrequenciesSet.cpp    |   37 +-
 .../Phyl/Model/FrequenciesSet/WordFrequenciesSet.h |    2 +-
 src/Bpp/Phyl/Model/G2001.h                         |    5 +-
 .../Model/MarkovModulatedSubstitutionModel.cpp     |    9 +-
 .../Phyl/Model/MarkovModulatedSubstitutionModel.h  |   47 +-
 src/Bpp/Phyl/Model/MixedSubstitutionModel.h        |    2 +-
 src/Bpp/Phyl/Model/MixedSubstitutionModelSet.cpp   |   26 +-
 src/Bpp/Phyl/Model/MixedSubstitutionModelSet.h     |  622 +++--
 src/Bpp/Phyl/Model/MixtureOfASubstitutionModel.cpp |   20 +-
 src/Bpp/Phyl/Model/MixtureOfASubstitutionModel.h   |   38 +-
 src/Bpp/Phyl/Model/MixtureOfSubstitutionModels.cpp |   52 +-
 src/Bpp/Phyl/Model/MixtureOfSubstitutionModels.h   |  329 ++-
 src/Bpp/Phyl/Model/Nucleotide/F84.cpp              |    9 +-
 src/Bpp/Phyl/Model/Nucleotide/F84.h                |   14 +-
 src/Bpp/Phyl/Model/Nucleotide/GTR.cpp              |    3 +-
 src/Bpp/Phyl/Model/Nucleotide/HKY85.cpp            |  721 +++---
 src/Bpp/Phyl/Model/Nucleotide/HKY85.h              |    8 +-
 src/Bpp/Phyl/Model/Nucleotide/JCnuc.cpp            |    7 +-
 src/Bpp/Phyl/Model/Nucleotide/JCnuc.h              |    5 +-
 src/Bpp/Phyl/Model/Nucleotide/K80.cpp              |  641 +++---
 src/Bpp/Phyl/Model/Nucleotide/K80.h                |   21 +-
 src/Bpp/Phyl/Model/Nucleotide/L95.cpp              |    4 +-
 src/Bpp/Phyl/Model/Nucleotide/L95.h                |    4 +-
 .../Model/Nucleotide/NucleotideSubstitutionModel.h |   72 +-
 src/Bpp/Phyl/Model/Nucleotide/RN95.cpp             |   52 +-
 src/Bpp/Phyl/Model/Nucleotide/RN95.h               |    6 +-
 src/Bpp/Phyl/Model/Nucleotide/RN95s.cpp            |   52 +-
 src/Bpp/Phyl/Model/Nucleotide/RN95s.h              |    6 +-
 src/Bpp/Phyl/Model/Nucleotide/SSR.cpp              |   85 +-
 src/Bpp/Phyl/Model/Nucleotide/SSR.h                |   98 +-
 src/Bpp/Phyl/Model/Nucleotide/T92.cpp              |    9 +-
 src/Bpp/Phyl/Model/Nucleotide/T92.h                |    6 +-
 src/Bpp/Phyl/Model/Nucleotide/TN93.cpp             |   13 +-
 src/Bpp/Phyl/Model/Nucleotide/TN93.h               |   10 +-
 src/Bpp/Phyl/Model/Nucleotide/YpR.cpp              |  375 +--
 src/Bpp/Phyl/Model/Nucleotide/YpR.h                |   14 +-
 src/Bpp/Phyl/Model/Nucleotide/gBGC.cpp             |  241 +-
 src/Bpp/Phyl/Model/Nucleotide/gBGC.h               |  129 +-
 src/Bpp/Phyl/Model/Protein/Coala.cpp               |  412 ++--
 src/Bpp/Phyl/Model/Protein/Coala.h                 |  224 +-
 src/Bpp/Phyl/Model/Protein/CoalaCore.cpp           |   20 +-
 src/Bpp/Phyl/Model/Protein/CoalaCore.h             |   17 +-
 src/Bpp/Phyl/Model/Protein/DSO78.cpp               |   27 +-
 src/Bpp/Phyl/Model/Protein/DSO78.h                 |    6 +-
 src/Bpp/Phyl/Model/Protein/JCprot.cpp              |   30 +-
 src/Bpp/Phyl/Model/Protein/JCprot.h                |   12 +-
 src/Bpp/Phyl/Model/Protein/JTT92.cpp               |   26 +-
 src/Bpp/Phyl/Model/Protein/JTT92.h                 |    6 +-
 src/Bpp/Phyl/Model/Protein/LG08.cpp                |   26 +-
 src/Bpp/Phyl/Model/Protein/LG08.h                  |    4 +-
 src/Bpp/Phyl/Model/Protein/LG10_EX_EHO.cpp         |  119 +
 src/Bpp/Phyl/Model/Protein/LG10_EX_EHO.h           |  131 ++
 src/Bpp/Phyl/Model/Protein/LGL08_CAT.cpp           |    3 +-
 src/Bpp/Phyl/Model/Protein/LLG08_EHO.cpp           |    3 +-
 src/Bpp/Phyl/Model/Protein/LLG08_EX2.cpp           |    3 +-
 src/Bpp/Phyl/Model/Protein/LLG08_EX3.cpp           |    3 +-
 src/Bpp/Phyl/Model/Protein/LLG08_UL2.cpp           |    3 +-
 src/Bpp/Phyl/Model/Protein/LLG08_UL3.cpp           |    3 +-
 .../Model/Protein/UserProteinSubstitutionModel.cpp |   23 +-
 .../Model/Protein/UserProteinSubstitutionModel.h   |    4 +-
 src/Bpp/Phyl/Model/Protein/WAG01.cpp               |   21 +-
 src/Bpp/Phyl/Model/Protein/WAG01.h                 |    4 +-
 .../Model/Protein/__LG10_EX_EHOExchangeabilityCode | 2423 ++++++++++++++++++++
 .../Model/Protein/__LG10_EX_EHOFrequenciesCode     |  142 ++
 src/Bpp/Phyl/Model/Protein/__LG10_EX_EHORatesProps |   34 +
 src/Bpp/Phyl/Model/RE08.cpp                        |   10 +-
 src/Bpp/Phyl/Model/RE08.h                          |  102 +-
 src/Bpp/Phyl/Model/StateMap.cpp                    |   22 +-
 src/Bpp/Phyl/Model/StateMap.h                      |   73 +-
 src/Bpp/Phyl/Model/SubstitutionModel.h             |   64 +-
 src/Bpp/Phyl/Model/SubstitutionModelSet.cpp        |  295 +--
 src/Bpp/Phyl/Model/SubstitutionModelSet.h          |  220 +-
 src/Bpp/Phyl/Model/SubstitutionModelSetTools.cpp   |   16 +-
 src/Bpp/Phyl/Model/TS98.h                          |   10 +-
 src/Bpp/Phyl/Model/WordSubstitutionModel.cpp       |   32 +-
 src/Bpp/Phyl/Model/WordSubstitutionModel.h         |   14 +-
 src/Bpp/Phyl/NNITopologySearch.cpp                 |   28 +-
 src/Bpp/Phyl/Node.h                                |   13 +-
 src/Bpp/Phyl/OptimizationTools.cpp                 |   10 +-
 src/Bpp/Phyl/OptimizationTools.h                   |    8 +-
 .../Phyl/Parsimony/AbstractTreeParsimonyScore.cpp  |    4 +-
 src/Bpp/Phyl/Parsimony/DRTreeParsimonyData.cpp     |    6 +-
 src/Bpp/Phyl/Simulation/DetailedSiteSimulator.h    |   33 +-
 src/Bpp/Phyl/Simulation/MutationProcess.cpp        |   42 +-
 src/Bpp/Phyl/Simulation/MutationProcess.h          |  350 +--
 .../Simulation/NonHomogeneousSequenceSimulator.cpp |  158 +-
 .../Simulation/NonHomogeneousSequenceSimulator.h   |  249 +-
 .../Phyl/Simulation/SequenceSimulationTools.cpp    |   34 +-
 src/Bpp/Phyl/Simulation/SequenceSimulationTools.h  |   92 +-
 src/Bpp/Phyl/Simulation/SequenceSimulator.h        |    9 +-
 src/Bpp/Phyl/Simulation/SiteSimulator.h            |   12 +-
 src/Bpp/Phyl/TreeTemplate.h                        |    2 +-
 src/Bpp/Phyl/TreeTemplateTools.cpp                 |  321 ++-
 src/Bpp/Phyl/TreeTemplateTools.h                   | 2227 +++++++++---------
 src/Bpp/Phyl/TreeTools.cpp                         |   63 +-
 src/Bpp/Phyl/TreeTools.h                           |   36 +-
 src/CMakeLists.txt                                 |   12 +
 test/test_detailed_simulations.cpp                 |    2 +-
 test/test_likelihood.cpp                           |   57 +-
 test/test_likelihood_clock.cpp                     |    5 +-
 test/test_likelihood_nh.cpp                        |    5 +-
 test/test_mapping.cpp                              |   30 +-
 test/test_mapping_codon.cpp                        |   38 +-
 test/test_models.cpp                               |    6 +-
 test/test_simulations.cpp                          |   16 +-
 test/test_tree.cpp                                 |   23 +
 239 files changed, 14728 insertions(+), 8358 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 72d0254..054be2b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -64,13 +64,13 @@ MACRO(IMPROVED_FIND_LIBRARY OUTPUT_LIBS lib_name include_to_find)
   SET(${lib_name}_NAMES ${lib_name} ${lib_name}lib ${lib_name}dll)
   FIND_LIBRARY(${lib_name}_LIBRARY NAMES ${${lib_name}_NAMES} PATH_SUFFIXES lib${LIB_SUFFIX})
 
-  IF(${lib_name}_LIBRARY)
+  IF(${${lib_name}_INCLUDE_DIR} MATCHES ${lib_name}_INCLUDE_DIR-NOTFOUND)
+    MESSAGE(FATAL_ERROR "${lib_name} required but not found.")
+  ELSE(${${lib_name}_INCLUDE_DIR} MATCHES ${lib_name}_INCLUDE_DIR-NOTFOUND)
     MESSAGE("-- Library ${lib_name} found here:")
     MESSAGE("   includes : ${${lib_name}_INCLUDE_DIR}")
     MESSAGE("   libraries: ${${lib_name}_LIBRARY}")
-  ELSE(${lib_name}_LIBRARY)
-    MESSAGE(FATAL_ERROR "${lib_name} required but not found.")
-  ENDIF(${lib_name}_LIBRARY)
+  ENDIF(${${lib_name}_INCLUDE_DIR} MATCHES ${lib_name}_INCLUDE_DIR-NOTFOUND)
   
   #add the dependency:
   INCLUDE_DIRECTORIES(${${lib_name}_INCLUDE_DIR})
@@ -103,9 +103,9 @@ ENDIF(NO_DEP_CHECK)
 # Packager
 SET(CPACK_PACKAGE_NAME "libbpp-phyl")
 SET(CPACK_PACKAGE_VENDOR "Bio++ Development Team")
-SET(CPACK_PACKAGE_VERSION "2.1.0")
+SET(CPACK_PACKAGE_VERSION "2.2.0")
 SET(CPACK_PACKAGE_VERSION_MAJOR "2")
-SET(CPACK_PACKAGE_VERSION_MINOR "1")
+SET(CPACK_PACKAGE_VERSION_MINOR "2")
 SET(CPACK_PACKAGE_VERSION_PATCH "0")
 SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "The Bio++ Phylogenetics library")
 SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/COPYING.txt")
@@ -123,7 +123,6 @@ SET(CPACK_SOURCE_IGNORE_FILES
  ".*\\\\.deb"
  ".*\\\\.rpm"
  ".*\\\\.dmg"
- ".*\\\\.sh"
  ".*\\\\..*\\\\.swp"
  "src/\\\\..*"
  "src/libbpp*"
diff --git a/ChangeLog b/ChangeLog
index aa599bb..575a136 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+28/09/14 -*- Version 2.2.0 -*-
+
+26/09/14 Julien Dutheil
+* Likelihood classes now use the ModelState class to like alphabet and model states.
+
+17/09/14 Julien Dutheil
+* Bugs #55 and #89 fixed.
+
+28/08/14 Julien Dutheil
+* Improved derivatives in DRTreeLikelihood classes.
+
+25/07/13 Julien Dutheil
+* Added method in TreeTemplateTools to unresolve all nodes below a certain confidence threshold.
+* TreeTools::midpointRooting is deprecated in favour of TreeTemplateTools::midRoot.
+
 07/03/13 -*- Version 2.1.0 -*-
 
 06/03/13 Nicolas Rochette
diff --git a/Doxyfile b/Doxyfile
index 23d0c62..a07d8a0 100644
--- a/Doxyfile
+++ b/Doxyfile
@@ -32,7 +32,7 @@ PROJECT_NAME           = bpp-phyl
 # This could be handy for archiving the generated documentation or 
 # if some version control system is used.
 
-PROJECT_NUMBER         = 2.1.0
+PROJECT_NUMBER         = 2.2.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 
@@ -343,7 +343,7 @@ TYPEDEF_HIDES_STRUCT   = NO
 # 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
+# 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 
@@ -1713,7 +1713,7 @@ DOT_NUM_THREADS        = 0
 # the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the 
 # directory containing the font.
 
-DOT_FONTNAME           = FreeSans
+# 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.
@@ -1849,7 +1849,7 @@ MSCFILE_DIRS           =
 # 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
+DOT_GRAPH_MAX_NODES    = 100
 
 # 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 
diff --git a/bpp-phyl.spec b/bpp-phyl.spec
index ee686f8..c3ecea2 100644
--- a/bpp-phyl.spec
+++ b/bpp-phyl.spec
@@ -1,5 +1,5 @@
 %define _basename bpp-phyl
-%define _version 2.1.0
+%define _version 2.2.0
 %define _release 1
 %define _prefix /usr
 
@@ -180,6 +180,9 @@ exit 0
 %{_prefix}/include/*
 
 %changelog
+* Mon Sep 28 2014 Julien Dutheil <julien.dutheil at univ-montp2.fr> 2.2.0-1
+- Bugs fixed + code improvements
+- More efficient DR likelihood derivatives.
 * Thu Mar 07 2013 Julien Dutheil <julien.dutheil at univ-montp2.fr> 2.1.0-1
 - New RateDistribution classes
 - New models for protein sequences (COaLA)
diff --git a/debian/changelog b/debian/changelog
index 7855473..b315098 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+libbpp-phyl (2.2.0-1) unstable; urgency=low
+
+  * Bugs fixed + code improvements
+  * More efficient DR likelihood derivatives.
+
+ -- Julien Dutheil <julien.dutheil at univ-montp2.fr>  Mon, 28 Sep 2014 14:00:00 +0100
+
 libbpp-phyl (2.1.0-1) unstable; urgency=low
 
   * New RateDistribution classes
diff --git a/debian/control b/debian/control
index 5f74897..98880fb 100644
--- a/debian/control
+++ b/debian/control
@@ -4,14 +4,14 @@ 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),
-  libbpp-seq-dev (>= 2.1.0)
-Standards-Version: 3.9.1
+  libbpp-seq-dev (>= 2.2.0)
+Standards-Version: 3.9.4
 
 Package: libbpp-phyl-dev
 Section: libdevel
 Architecture: any
 Depends: libbpp-phyl9 (= ${binary:Version}), ${misc:Depends},
-  libbpp-seq-dev (>= 2.1.0)
+  libbpp-seq-dev (>= 2.2.0)
 Description: Bio++ Phylogenetic library development files.
  Contains the Bio++ classes for phylogenetics.
 
@@ -19,7 +19,7 @@ Package: libbpp-phyl9
 Section: libs
 Architecture: any
 Depends: ${shlibs:Depends}, ${misc:Depends},
-  libbpp-seq9 (>= 2.1.0)
+  libbpp-seq9 (>= 2.2.0)
 Description: Bio++ Phylogenetic library.
  Contains the Bio++ classes for phylogenetics.
 
diff --git a/debian/copyright b/debian/copyright
index 142fcfb..ced4d0e 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -1,5 +1,5 @@
 This package was debianized by Julien Dutheil <julien.dutheil at univ-montp2.fr> on
-Thu, 07 Mar 2013 15:58:00 +0100
+Mon, 28 Sep 2014 14:00:00 +0100
 
 It was downloaded from <http://biopp.univ-montp2.fr/Repositories/sources>
 
@@ -9,7 +9,7 @@ Upstream Author:
 
 Copyright: 
 
-    Copyright (C) 2013 Bio++ Development Team
+    Copyright (C) 2014 Bio++ Development Team
 
 License:
 
@@ -30,7 +30,7 @@ License:
 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
+The Debian packaging is (C) 2014, 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:
diff --git a/debian/postinst b/debian/postinst
index cf9e925..cff89b1 100755
--- a/debian/postinst
+++ b/debian/postinst
@@ -35,9 +35,23 @@ createGeneric() {
   done;
 }
 
-if [ "$1" = "configure" ]; then
-  # Actualize .all files
-  createGeneric /usr/include/Bpp
-fi
+case "$1" in
+  configure)
+    # Actualize .all files
+    createGeneric /usr/include/Bpp
+  ;;
+  abort-upgrade|abort-remove|abort-deconfigure)
+    echo "$1"
+  ;;
+  *)
+    echo "postinst called with unknown argument \`\$1'" >&2
+    exit 0
+  ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
 
 exit 0
diff --git a/debian/postrm b/debian/postrm
index 3931669..744f8b1 100755
--- a/debian/postrm
+++ b/debian/postrm
@@ -35,11 +35,25 @@ createGeneric() {
   done;
 }
 
-if [ "$1" = "remove" ]; then
-  # Automatically added by dh_makeshlibs
-  ldconfig
-  # Actualize .all files
-  createGeneric /usr/include/Bpp
-fi
+case "$1" in
+  remove)
+    # Automatically added by dh_makeshlibs
+    ldconfig
+    # Actualize .all files
+    createGeneric /usr/include/Bpp
+  ;;
+  purge|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
+    echo $1
+  ;;
+  *)
+    echo "postrm called with unknown argument \`\$1'" >&2
+    exit 0
+  ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
 
 exit 0
diff --git a/debian/prerm b/debian/prerm
index 5aefd24..8fab52e 100755
--- a/debian/prerm
+++ b/debian/prerm
@@ -19,9 +19,23 @@ removeGeneric() {
   done
 }
 
-if [ "$1" = "remove" ]; then
-  # Actualize .all files
-  removeGeneric /usr/include/Bpp
-fi
+case "$1" in
+  remove|upgrade|deconfigure)
+    # Actualize .all files
+    removeGeneric /usr/include/Bpp
+  ;;
+  failed-upgrade)
+    echo "$1"
+  ;;
+  *)
+    echo "prerm called with unknown argument \`$1'" >&2
+    exit 1
+  ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
 
 exit 0
diff --git a/debian/rules b/debian/rules
index 92c389e..34313ef 100755
--- a/debian/rules
+++ b/debian/rules
@@ -38,7 +38,9 @@ configure:
 config.status: configure
 	dh_testdir
 
-build: build-stamp
+build: build-arch build-indep
+build-arch: build-stamp
+build-indep: build-stamp
 build-stamp:  config.status
 	dh_testdir
 
diff --git a/debian/postinst b/genIncludes.sh
similarity index 80%
copy from debian/postinst
copy to genIncludes.sh
index cf9e925..56710e9 100755
--- a/debian/postinst
+++ b/genIncludes.sh
@@ -1,8 +1,5 @@
 #! /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:
@@ -35,9 +32,4 @@ createGeneric() {
   done;
 }
 
-if [ "$1" = "configure" ]; then
-  # Actualize .all files
-  createGeneric /usr/include/Bpp
-fi
-
-exit 0
+createGeneric $1
diff --git a/src/Bpp/Phyl/App/PhylogeneticsApplicationTools.cpp b/src/Bpp/Phyl/App/PhylogeneticsApplicationTools.cpp
index dbf3de9..096e8e8 100644
--- a/src/Bpp/Phyl/App/PhylogeneticsApplicationTools.cpp
+++ b/src/Bpp/Phyl/App/PhylogeneticsApplicationTools.cpp
@@ -98,10 +98,11 @@ Tree* PhylogeneticsApplicationTools::getTree(
   const string& prefix,
   const string& suffix,
   bool suffixIsOptional,
-  bool verbose) throw (Exception)
+  bool verbose,
+  int warn) throw (Exception)
 {
-  string format = ApplicationTools::getStringParameter(prefix + "tree.format", params, "Newick", suffix, suffixIsOptional, true);
-  string treeFilePath = ApplicationTools::getAFilePath(prefix + "tree.file", params, true, true, suffix, suffixIsOptional);
+  string format = ApplicationTools::getStringParameter(prefix + "tree.format", params, "Newick", suffix, suffixIsOptional, warn);
+  string treeFilePath = ApplicationTools::getAFilePath(prefix + "tree.file", params, true, true, suffix, suffixIsOptional, "none", warn);
 
   ITree* treeReader;
   if (format == "Newick")
@@ -127,10 +128,11 @@ vector<Tree*> PhylogeneticsApplicationTools::getTrees(
   const string& prefix,
   const string& suffix,
   bool suffixIsOptional,
-  bool verbose) throw (Exception)
+  bool verbose,
+  int warn) throw (Exception)
 {
-  string format = ApplicationTools::getStringParameter(prefix + "trees.format", params, "Newick", suffix, suffixIsOptional, true);
-  string treeFilePath = ApplicationTools::getAFilePath(prefix + "trees.file", params, true, true, suffix, suffixIsOptional);
+  string format = ApplicationTools::getStringParameter(prefix + "trees.format", params, "Newick", suffix, suffixIsOptional, warn);
+  string treeFilePath = ApplicationTools::getAFilePath(prefix + "trees.file", params, true, true, suffix, suffixIsOptional, "none", warn);
 
   IMultiTree* treeReader;
   if (format == "Newick")
@@ -162,25 +164,28 @@ vector<Tree*> PhylogeneticsApplicationTools::getTrees(
 
 SubstitutionModel* PhylogeneticsApplicationTools::getSubstitutionModel(
   const Alphabet* alphabet,
+  const GeneticCode* gCode,
   const SiteContainer* data,
   std::map<std::string, std::string>& params,
   const string& suffix,
   bool suffixIsOptional,
-  bool verbose) throw (Exception)
+  bool verbose,
+  int warn) throw (Exception)
 {
+  BppOSubstitutionModelFormat bIO(BppOSubstitutionModelFormat::ALL, true, true, true, verbose, warn + 1);
   string modelDescription;
-  if (AlphabetTools::isCodonAlphabet(alphabet))
-    modelDescription = ApplicationTools::getStringParameter("model", params, "CodonRate(model=JC69)", suffix, suffixIsOptional, verbose);
-  else if (AlphabetTools::isWordAlphabet(alphabet))
-    modelDescription = ApplicationTools::getStringParameter("model", params, "Word(model=JC69)", suffix, suffixIsOptional, verbose);
+  const CodonAlphabet* ca = dynamic_cast<const CodonAlphabet*>(alphabet);
+  if (ca) {
+    modelDescription = ApplicationTools::getStringParameter("model", params, "CodonRate(model=JC69)", suffix, suffixIsOptional, warn);
+    if (!gCode)
+      throw Exception("PhylogeneticsApplicationTools::getSubstitutionModel(): a GeneticCode instance is required for instanciating a codon model.");
+    bIO.setGeneticCode(gCode);
+  } else if (AlphabetTools::isWordAlphabet(alphabet))
+    modelDescription = ApplicationTools::getStringParameter("model", params, "Word(model=JC69)", suffix, suffixIsOptional, warn);
   else
-    modelDescription = ApplicationTools::getStringParameter("model", params, "JC69", suffix, suffixIsOptional, verbose);
-
-  map<string, string> unparsedParameterValues;
+    modelDescription = ApplicationTools::getStringParameter("model", params, "JC69", suffix, suffixIsOptional, warn);
 
-  BppOSubstitutionModelFormat bIO(BppOSubstitutionModelFormat::ALL, true, true, true, verbose);
   SubstitutionModel* model = bIO.read(alphabet, modelDescription, data, true);
-
   return model;
 }
 
@@ -189,11 +194,10 @@ SubstitutionModel* PhylogeneticsApplicationTools::getSubstitutionModel(
 void PhylogeneticsApplicationTools::setSubstitutionModelParametersInitialValuesWithAliases(
   SubstitutionModel& model,
   std::map<std::string, std::string>& unparsedParameterValues,
-  const std::string& modelPrefix,
+  size_t modelNumber,
   const SiteContainer* data,
   std::map<std::string, double>& existingParams,
-  std::vector<std::string>& specificParams,
-  std::vector<std::string>& sharedParams,
+  std::map<std::string, std::string>& sharedParams,
   bool verbose) throw (Exception)
 {
   string initFreqs = ApplicationTools::getStringParameter(model.getNamespace() + "initFreqs", unparsedParameterValues, "", "", true, false);
@@ -226,6 +230,8 @@ void PhylogeneticsApplicationTools::setSubstitutionModelParametersInitialValuesW
       throw Exception("Unknown initFreqs argument");
   }
 
+
+  
   ParameterList pl = model.getIndependentParameters();
   for (size_t i = 0; i < pl.size(); ++i)
   {
@@ -247,32 +253,26 @@ void PhylogeneticsApplicationTools::setSubstitutionModelParametersInitialValuesW
       if (!test1 && !test2 && test3)
         ApplicationTools::displayWarning("Warning, initFreqs argument is set and a value is set for parameter " + pName);
       value = ApplicationTools::getStringParameter(pName, unparsedParameterValues, TextTools::toString(pl[i].getValue()));
-      if (value.size() > 5 && value.substr(0, 5) == "model")
+      if (value.rfind("_")!=string::npos)
       {
         if (existingParams.find(value) != existingParams.end())
-        {
-          pl[i].setValue(existingParams[value]);
-          sharedParams.push_back(value);
-        }
+          {
+            pl[i].setValue(existingParams[value]);
+            sharedParams[pl[i].getName()+"_"+TextTools::toString(modelNumber)]=value;
+          }
         else
           throw Exception("Error, unknown parameter " + value);
       }
       else
-      {
-        double value2 = TextTools::toDouble(value);
-        existingParams[modelPrefix + pName] = value2;
-        specificParams.push_back(pName);
-        pl[i].setValue(value2);
-      }
-    }
-    else
-    {
-      existingParams[modelPrefix + pName] = pl[i].getValue();
-      specificParams.push_back(pName);
+        pl[i].setValue(TextTools::toDouble(value));
     }
+
+    existingParams[pName+"_"+TextTools::toString(modelNumber)] = pl[i].getValue();
+    
     if (verbose)
-      ApplicationTools::displayResult("Parameter found", modelPrefix + pName + "=" + TextTools::toString(pl[i].getValue()));
+      ApplicationTools::displayResult("Parameter found", pName + +"_"+TextTools::toString(modelNumber) + "=" + TextTools::toString(pl[i].getValue()));
   }
+  
   model.matchParametersValues(pl);
 }
 
@@ -285,21 +285,23 @@ void PhylogeneticsApplicationTools::setSubstitutionModelParametersInitialValuesW
 
 FrequenciesSet* PhylogeneticsApplicationTools::getRootFrequenciesSet(
   const Alphabet* alphabet,
+  const GeneticCode* gCode,
   const SiteContainer* data,
   std::map<std::string, std::string>& params,
   const std::vector<double>& rateFreqs,
   const std::string& suffix,
   bool suffixIsOptional,
-  bool verbose) throw (Exception)
+  bool verbose,
+  int warn) throw (Exception)
 {
-  string freqDescription = ApplicationTools::getStringParameter("nonhomogeneous.root_freq", params, "Full(init=observed)", suffix, suffixIsOptional);
+  string freqDescription = ApplicationTools::getStringParameter("nonhomogeneous.root_freq", params, "Full(init=observed)", suffix, suffixIsOptional, warn);
   if (freqDescription == "None")
   {
     return 0;
   }
   else
   {
-    FrequenciesSet* freq = getFrequenciesSet(alphabet, freqDescription, data, rateFreqs, verbose);
+    FrequenciesSet* freq = getFrequenciesSet(alphabet, gCode, freqDescription, data, rateFreqs, verbose, warn + 1);
     if (verbose)
       ApplicationTools::displayResult("Root frequencies ", freq->getName());
     return freq;
@@ -310,15 +312,22 @@ FrequenciesSet* PhylogeneticsApplicationTools::getRootFrequenciesSet(
 
 FrequenciesSet* PhylogeneticsApplicationTools::getFrequenciesSet(
   const Alphabet* alphabet,
+  const GeneticCode* gCode,
   const std::string& freqDescription,
   const SiteContainer* data,
   const std::vector<double>& rateFreqs,
-  bool verbose) throw (Exception)
+  bool verbose,
+  int warn) throw (Exception)
 {
   map<string, string> unparsedParameterValues;
-  BppOFrequenciesSetFormat bIO(BppOFrequenciesSetFormat::ALL, verbose);
+  BppOFrequenciesSetFormat bIO(BppOFrequenciesSetFormat::ALL, verbose, warn);
+  if (AlphabetTools::isCodonAlphabet(alphabet)) {
+    if (!gCode)
+      throw Exception("PhylogeneticsApplicationTools::getFrequenciesSet(): a GeneticCode instance is required for instanciating a codon frequencies set.");
+    bIO.setGeneticCode(gCode);
+  }
   auto_ptr<FrequenciesSet> pFS(bIO.read(alphabet, freqDescription, data, true));
-
+  
   // /////// To be changed for input normalization
   if (rateFreqs.size() > 0)
   {
@@ -336,15 +345,17 @@ FrequenciesSet* PhylogeneticsApplicationTools::getFrequenciesSet(
 
 SubstitutionModelSet* PhylogeneticsApplicationTools::getSubstitutionModelSet(
   const Alphabet* alphabet,
+  const GeneticCode* gCode,
   const SiteContainer* data,
   std::map<std::string, std::string>& params,
   const std::string& suffix,
   bool suffixIsOptional,
-  bool verbose)
+  bool verbose,
+  int warn)
 {
   if (!ApplicationTools::parameterExists("nonhomogeneous.number_of_models", params))
-    throw Exception("You must specify this parameter: nonhomogeneous.number_of_models .");
-  size_t nbModels = ApplicationTools::getParameter<size_t>("nonhomogeneous.number_of_models", params, 1, suffix, suffixIsOptional, false);
+    throw Exception("A value is needed for this parameter: nonhomogeneous.number_of_models .");
+  size_t nbModels = ApplicationTools::getParameter<size_t>("nonhomogeneous.number_of_models", params, 1, suffix, suffixIsOptional, warn);
   if (nbModels == 0)
     throw Exception("The number of models can't be 0 !");
 
@@ -353,7 +364,7 @@ SubstitutionModelSet* PhylogeneticsApplicationTools::getSubstitutionModelSet(
   {
     string prefix = "model" + TextTools::toString(i + 1);
     string modelDesc;
-    modelDesc = ApplicationTools::getStringParameter(prefix, params, "", suffix, suffixIsOptional, verbose);
+    modelDesc = ApplicationTools::getStringParameter(prefix, params, "", suffix, suffixIsOptional, warn);
 
     if (modelDesc.find("Mixed") != string::npos)
       nomix = false;
@@ -361,7 +372,7 @@ SubstitutionModelSet* PhylogeneticsApplicationTools::getSubstitutionModelSet(
 
   SubstitutionModelSet* modelSet, * modelSet1 = 0;
   modelSet1 = new SubstitutionModelSet(alphabet);
-  setSubstitutionModelSet(*modelSet1, alphabet, data, params, suffix, suffixIsOptional, verbose);
+  setSubstitutionModelSet(*modelSet1, alphabet, gCode, data, params, suffix, suffixIsOptional, verbose, warn);
 
   if (modelSet1->hasMixedSubstitutionModel())
   {
@@ -379,38 +390,43 @@ SubstitutionModelSet* PhylogeneticsApplicationTools::getSubstitutionModelSet(
 void PhylogeneticsApplicationTools::setSubstitutionModelSet(
   SubstitutionModelSet& modelSet,
   const Alphabet* alphabet,
+  const GeneticCode* gCode,
   const SiteContainer* data,
   map<string, string>& params,
   const string& suffix,
   bool suffixIsOptional,
-  bool verbose)
+  bool verbose,
+  int warn)
 {
   modelSet.clear();
   if (!ApplicationTools::parameterExists("nonhomogeneous.number_of_models", params))
-    throw Exception("You must specify this parameter: nonhomogeneous.number_of_models .");
-  size_t nbModels = ApplicationTools::getParameter<size_t>("nonhomogeneous.number_of_models", params, 1, suffix, suffixIsOptional, false);
+    throw Exception("You must specify this parameter: 'nonhomogeneous.number_of_models'.");
+  size_t nbModels = ApplicationTools::getParameter<size_t>("nonhomogeneous.number_of_models", params, 1, suffix, suffixIsOptional, warn);
   if (nbModels == 0)
     throw Exception("The number of models can't be 0 !");
 
   if (verbose)
     ApplicationTools::displayResult("Number of distinct models", TextTools::toString(nbModels));
 
-  BppOSubstitutionModelFormat bIO(BppOSubstitutionModelFormat::ALL, true, true, true, verbose);
+  BppOSubstitutionModelFormat bIO(BppOSubstitutionModelFormat::ALL, true, true, true, false, warn);
 
   // ///////////////////////////////////////////
   // Build a new model set object:
 
   vector<double> rateFreqs;
   string tmpDesc;
-  if (AlphabetTools::isCodonAlphabet(alphabet))
-    tmpDesc = ApplicationTools::getStringParameter("model1", params, "CodonRate(model=JC69)", suffix, suffixIsOptional, false);
-  else if (AlphabetTools::isWordAlphabet(alphabet))
-    tmpDesc = ApplicationTools::getStringParameter("model1", params, "Word(model=JC69)", suffix, suffixIsOptional, false);
+  if (AlphabetTools::isCodonAlphabet(alphabet)) {
+    if (!gCode)
+      throw Exception("PhylogeneticsApplicationTools::setSubstitutionModelSet(): a GeneticCode instance is required for instanciating a codon model.");
+    bIO.setGeneticCode(gCode);
+    tmpDesc = ApplicationTools::getStringParameter("model1", params, "CodonRate(model=JC69)", suffix, suffixIsOptional, warn);
+  } else if (AlphabetTools::isWordAlphabet(alphabet))
+    tmpDesc = ApplicationTools::getStringParameter("model1", params, "Word(model=JC69)", suffix, suffixIsOptional, warn);
   else
-    tmpDesc = ApplicationTools::getStringParameter("model1", params, "JC69", suffix, suffixIsOptional, false);
+    tmpDesc = ApplicationTools::getStringParameter("model1", params, "JC69", suffix, suffixIsOptional, warn);
 
   auto_ptr<SubstitutionModel> tmp(bIO.read(alphabet, tmpDesc, data, false));
-  map<string, string> tmpUnparsedParameterValues(bIO.getUnparsedArguments());
+  //  map<string, string> tmpUnparsedParameterValues(bIO.getUnparsedArguments());
 
   if (tmp->getNumberOfStates() != alphabet->getSize())
   {
@@ -422,19 +438,19 @@ void PhylogeneticsApplicationTools::setSubstitutionModelSet(
   // ////////////////////////////////////
   // Deal with root frequencies
 
-  bool stationarity = ApplicationTools::getBooleanParameter("nonhomogeneous.stationarity", params, false, "", false, false);
+  bool stationarity = ApplicationTools::getBooleanParameter("nonhomogeneous.stationarity", params, false, "", true, warn);
   FrequenciesSet* rootFrequencies = 0;
   if (!stationarity)
   {
-    rootFrequencies = getRootFrequenciesSet(alphabet, data, params, rateFreqs, suffix, suffixIsOptional, verbose);
+    rootFrequencies = getRootFrequenciesSet(alphabet, gCode, data, params, rateFreqs, suffix, suffixIsOptional, verbose);
     stationarity = !rootFrequencies;
-    string freqDescription = ApplicationTools::getStringParameter("nonhomogeneous.root_freq", params, "", suffix, suffixIsOptional);
+    string freqDescription = ApplicationTools::getStringParameter("nonhomogeneous.root_freq", params, "", suffix, suffixIsOptional, warn);
     if (freqDescription.substr(0, 10) == "MVAprotein")
     {
       if (dynamic_cast<Coala*>(tmp.get()))
         dynamic_cast<MvaFrequenciesSet*>(rootFrequencies)->initSet(dynamic_cast<CoalaCore*>(tmp.get()));
       else
-        throw Exception("The MVAprotein frequencies set at the root can only be used if a COaLA model is used on branches.");
+        throw Exception("The MVAprotein frequencies set at the root can only be used if a Coala model is used on branches.");
     }
   }
   ApplicationTools::displayBooleanResult("Stationarity assumed", stationarity);
@@ -445,6 +461,8 @@ void PhylogeneticsApplicationTools::setSubstitutionModelSet(
   // //////////////////////////////////////
   // Now parse all models:
 
+  bIO.setVerbose(true);
+  
   map<string, double> existingParameters;
 
   for (size_t i = 0; i < nbModels; i++)
@@ -452,53 +470,39 @@ void PhylogeneticsApplicationTools::setSubstitutionModelSet(
     string prefix = "model" + TextTools::toString(i + 1);
     string modelDesc;
     if (AlphabetTools::isCodonAlphabet(alphabet))
-      modelDesc = ApplicationTools::getStringParameter(prefix, params, "CodonRate(model=JC69)", suffix, suffixIsOptional, verbose);
+      modelDesc = ApplicationTools::getStringParameter(prefix, params, "CodonRate(model=JC69)", suffix, suffixIsOptional, warn);
     else if (AlphabetTools::isWordAlphabet(alphabet))
-      modelDesc = ApplicationTools::getStringParameter(prefix, params, "Word(model=JC69)", suffix, suffixIsOptional, verbose);
+      modelDesc = ApplicationTools::getStringParameter(prefix, params, "Word(model=JC69)", suffix, suffixIsOptional, warn);
     else
-      modelDesc = ApplicationTools::getStringParameter(prefix, params, "JC69", suffix, suffixIsOptional, verbose);
+      modelDesc = ApplicationTools::getStringParameter(prefix, params, "JC69", suffix, suffixIsOptional, warn);
 
     auto_ptr<SubstitutionModel> model(bIO.read(alphabet, modelDesc, data, false));
     map<string, string> unparsedParameterValues(bIO.getUnparsedArguments());
-    prefix += ".";
 
-    vector<string> specificParameters, sharedParameters;
+    map<string, string> sharedParameters;
     setSubstitutionModelParametersInitialValuesWithAliases(
       *model,
-      unparsedParameterValues, prefix, data,
-      existingParameters, specificParameters, sharedParameters,
+      unparsedParameterValues, i+1, data,
+      existingParameters, sharedParameters,
       verbose);
-    vector<int> nodesId = ApplicationTools::getVectorParameter<int>(prefix + "nodes_id", params, ',', ':', TextTools::toString(i), suffix, suffixIsOptional, true);
+
+    vector<int> nodesId = ApplicationTools::getVectorParameter<int>(prefix + ".nodes_id", params, ',', ':', TextTools::toString(i), suffix, suffixIsOptional, warn);
+
     if (verbose)
       ApplicationTools::displayResult("Model" + TextTools::toString(i + 1) + " is associated to", TextTools::toString(nodesId.size()) + " node(s).");
-    // Add model and specific parameters:
-    // DEBUG: cout << "Specific parameters:" << endl;
-    // DEBUG: VectorTools::print(specificParameters);
-    modelSet.addModel(model.get(), nodesId, specificParameters);
+
+    modelSet.addModel(model.get(), nodesId);
+
     // Now set shared parameters:
-    for (size_t j = 0; j < sharedParameters.size(); j++)
-    {
-      string pName = sharedParameters[j];
-      // DEBUG: cout << "Shared parameter found: " << pName << endl;
-      string::size_type index = pName.find(".");
-      if (index == string::npos)
-        throw Exception("PhylogeneticsApplicationTools::getSubstitutionModelSet. Bad parameter name: " + pName);
-      string name = pName.substr(index + 1) + "_" + pName.substr(5, index - 5);
-      // namespace checking:
-      vector<size_t> models = modelSet.getModelsWithParameter(name);
-      if (models.size() == 0)
-        throw Exception("PhylogeneticsApplicationTools::getSubstitutionModelSet. Parameter `" + name + "' is not associated to any model.");
-      if (model->getNamespace() == modelSet.getModel(models[0])->getNamespace())
-        modelSet.setParameterToModel(modelSet.getParameterIndex(name), modelSet.getNumberOfModels() - 1);
-      else
-      {
-        throw Exception("Assigning a value to a parameter with a distinct namespace is not (yet) allowed. Consider using parameter aliasing instead.");
-      }
-    }
+    map<string, string>::const_iterator it;
+    for (it=sharedParameters.begin(); it!=sharedParameters.end(); it++)
+      modelSet.aliasParameters(it->second, it->first);
+    
     model.release();
   }
+  
   // Finally check parameter aliasing:
-  string aliasDesc = ApplicationTools::getStringParameter("nonhomogeneous.alias", params, "", suffix, suffixIsOptional, verbose);
+  string aliasDesc = ApplicationTools::getStringParameter("nonhomogeneous.alias", params, "", suffix, suffixIsOptional, warn);
   StringTokenizer st(aliasDesc, ",");
   while (st.hasMoreToken())
   {
@@ -521,7 +525,8 @@ void PhylogeneticsApplicationTools::completeMixedSubstitutionModelSet(
   map<string, string>& params,
   const string& suffix,
   bool suffixIsOptional,
-  bool verbose)
+  bool verbose,
+  int warn)
 {
   // /////////////////////////////////////////
   // Looks for the allowed paths
@@ -530,7 +535,7 @@ void PhylogeneticsApplicationTools::completeMixedSubstitutionModelSet(
   if (!ApplicationTools::parameterExists("site.number_of_paths", params))
     numd = 0;
   else
-    numd = ApplicationTools::getParameter<size_t>("site.number_of_paths", params, 1, suffix, suffixIsOptional, false);
+    numd = ApplicationTools::getParameter<size_t>("site.number_of_paths", params, 1, suffix, suffixIsOptional, warn);
 
   if (verbose)
     ApplicationTools::displayResult("Number of distinct paths", TextTools::toString(numd));
@@ -538,7 +543,7 @@ void PhylogeneticsApplicationTools::completeMixedSubstitutionModelSet(
   vector<string> vdesc;
   while (numd)
   {
-    string desc = ApplicationTools::getStringParameter("site.path" + TextTools::toString(numd), params, "",  suffix, suffixIsOptional, verbose);
+    string desc = ApplicationTools::getStringParameter("site.path" + TextTools::toString(numd), params, "",  suffix, suffixIsOptional, warn);
     if (desc.size() == 0)
       break;
     else
@@ -564,12 +569,12 @@ void PhylogeneticsApplicationTools::completeMixedSubstitutionModelSet(
       string::size_type indexf = submodel.find("]");
       if ((indexo == string::npos) | (indexf == string::npos))
         throw Exception("PhylogeneticsApplicationTools::setMixedSubstitutionModelSet. Bad path syntax, should contain `[]' symbols: " + submodel);
-      int num = TextTools::toInt(submodel.substr(5, indexo - 5));
+      size_t num = TextTools::to<size_t>(submodel.substr(5, indexo - 5));
       string p2 = submodel.substr(indexo + 1, indexf - indexo - 1);
 
       const MixedSubstitutionModel* pSM = dynamic_cast<const MixedSubstitutionModel*>(mixedModelSet.getModel(num - 1));
-      if (pSM == NULL)
-        throw BadIntegerException("PhylogeneticsApplicationTools::setMixedSubstitutionModelSet: Wron gmodel for number", num - 1);
+      if (!pSM)
+        throw BadIntegerException("PhylogeneticsApplicationTools::setMixedSubstitutionModelSet: Wrong model for number", static_cast<int>(num - 1));
       Vint submodnb = pSM->getSubmodelNumbers(p2);
 
       mixedModelSet.addToHyperNode(num - 1, submodnb);
@@ -635,7 +640,7 @@ MultipleDiscreteDistribution* PhylogeneticsApplicationTools::getMultipleDistribu
     rf = args["classes"];
     StringTokenizer strtok2(rf.substr(1, rf.length() - 2), ",");
     while (strtok2.hasMoreToken())
-      classes.push_back(TextTools::toInt(strtok2.nextToken()));
+      classes.push_back(TextTools::to<size_t>(strtok2.nextToken()));
 
     pMDD = new DirichletDiscreteDistribution(classes, alphas);
     vector<string> v = pMDD->getParameters().getParameterNames();
@@ -690,19 +695,20 @@ TreeLikelihood* PhylogeneticsApplicationTools::optimizeParameters(
   std::map<std::string, std::string>& params,
   const std::string& suffix,
   bool suffixIsOptional,
-  bool verbose)
+  bool verbose,
+  int warn)
 throw (Exception)
 {
-  string optimization = ApplicationTools::getStringParameter("optimization", params, "FullD(derivatives=Newton)", suffix, suffixIsOptional, false);
+  string optimization = ApplicationTools::getStringParameter("optimization", params, "FullD(derivatives=Newton)", suffix, suffixIsOptional, warn);
   if (optimization == "None")
     return tl;
   string optName;
   map<string, string> optArgs;
   KeyvalTools::parseProcedure(optimization, optName, optArgs);
 
-  unsigned int optVerbose = ApplicationTools::getParameter<unsigned int>("optimization.verbose", params, 2, suffix, suffixIsOptional);
+  unsigned int optVerbose = ApplicationTools::getParameter<unsigned int>("optimization.verbose", params, 2, suffix, suffixIsOptional, warn + 1);
 
-  string mhPath = ApplicationTools::getAFilePath("optimization.message_handler", params, false, false, suffix, suffixIsOptional);
+  string mhPath = ApplicationTools::getAFilePath("optimization.message_handler", params, false, false, suffix, suffixIsOptional, "none", warn + 1);
   OutputStream* messageHandler =
     (mhPath == "none") ? 0 :
     (mhPath == "std") ? ApplicationTools::message :
@@ -710,7 +716,7 @@ throw (Exception)
   if (verbose)
     ApplicationTools::displayResult("Message handler", mhPath);
 
-  string prPath = ApplicationTools::getAFilePath("optimization.profiler", params, false, false, suffix, suffixIsOptional);
+  string prPath = ApplicationTools::getAFilePath("optimization.profiler", params, false, false, suffix, suffixIsOptional, "none", warn + 1);
   OutputStream* profiler =
     (prPath == "none") ? 0 :
     (prPath == "std") ? ApplicationTools::message :
@@ -720,16 +726,16 @@ throw (Exception)
   if (verbose)
     ApplicationTools::displayResult("Profiler", prPath);
 
-  bool scaleFirst = ApplicationTools::getBooleanParameter("optimization.scale_first", params, false, suffix, suffixIsOptional, false);
+  bool scaleFirst = ApplicationTools::getBooleanParameter("optimization.scale_first", params, false, suffix, suffixIsOptional, warn + 1);
   if (scaleFirst)
   {
     // We scale the tree before optimizing each branch length separately:
     if (verbose)
       ApplicationTools::displayMessage("Scaling the tree before optimizing each branch length separately.");
-    double tolerance = ApplicationTools::getDoubleParameter("optimization.scale_first.tolerance", params, .0001, suffix, suffixIsOptional, true);
+    double tolerance = ApplicationTools::getDoubleParameter("optimization.scale_first.tolerance", params, .0001, suffix, suffixIsOptional, warn + 1);
     if (verbose)
       ApplicationTools::displayResult("Scaling tolerance", TextTools::toString(tolerance));
-    int nbEvalMax = ApplicationTools::getIntParameter("optimization.scale_first.max_number_f_eval", params, 1000000, suffix, suffixIsOptional, true);
+    unsigned int nbEvalMax = ApplicationTools::getParameter<unsigned int>("optimization.scale_first.max_number_f_eval", params, 1000000, suffix, suffixIsOptional, warn + 1);
     if (verbose)
       ApplicationTools::displayResult("Scaling max # f eval", TextTools::toString(nbEvalMax));
     OptimizationTools::optimizeTreeScale(
@@ -744,9 +750,11 @@ throw (Exception)
 
   // Should I ignore some parameters?
   ParameterList parametersToEstimate = parameters;
-  string paramListDesc = ApplicationTools::getStringParameter("optimization.ignore_parameter", params, "", suffix, suffixIsOptional, false);
-  if (paramListDesc.length() == 0)
-    paramListDesc = ApplicationTools::getStringParameter("optimization.ignore_parameters", params, "", suffix, suffixIsOptional, false);
+  vector<string> parNames = parametersToEstimate.getParameterNames();
+  
+  if (params.find("optimization.ignore_parameter") != params.end())
+    throw Exception("optimization.ignore_parameter is deprecated, use optimization.ignore_parameters instead!");
+  string paramListDesc = ApplicationTools::getStringParameter("optimization.ignore_parameters", params, "", suffix, suffixIsOptional, warn + 1);
   StringTokenizer st(paramListDesc, ",");
   while (st.hasMoreToken())
   {
@@ -773,36 +781,26 @@ throw (Exception)
         if (verbose)
           ApplicationTools::displayResult("Parameter ignored", string("Root frequencies"));
       }
-      else if (param.find("*") != string::npos)
-      {
-        vector<string> vs;
-        for (size_t j = 0; j < parametersToEstimate.size(); j++)
+      else if (param == "Model")
         {
-          StringTokenizer stj(param, "*", true, false);
-          size_t pos1, pos2;
-          string parn = parametersToEstimate[j].getName();
-          bool flag(true);
-          string g = stj.nextToken();
-          pos1 = parn.find(g);
-          if (pos1 != 0)
-            flag = false;
-          pos1 += g.length();
-          while (flag && stj.hasMoreToken())
-          {
-            g = stj.nextToken();
-            pos2 = parn.find(g, pos1);
-            if (pos2 == string::npos)
-            {
-              flag = false;
-              break;
+          vector<string> vs;
+          vector<string> vs1 = tl->getSubstitutionModelParameters().getParameterNames();
+          NonHomogeneousTreeLikelihood* nhtl = dynamic_cast<NonHomogeneousTreeLikelihood*>(tl);
+          if (nhtl!=NULL){
+            vector<string> vs2 = nhtl->getRootFrequenciesParameters().getParameterNames();
+            VectorTools::diff(vs1,vs2,vs);
             }
-            pos1 = pos2 + g.length();
-          }
-          if (flag &&
-              ((g.length() == 0) || (pos1 == parn.length()) || (parn.rfind(g) == parn.length() - g.length())))
-            vs.push_back(parn);
-        }
+          else
+            vs=vs1;
 
+          parametersToEstimate.deleteParameters(vs);
+          if (verbose)
+            ApplicationTools::displayResult("Parameter ignored", string("Model"));          
+        }
+      else if (param.find("*") != string::npos)
+      {
+        vector<string> vs=ApplicationTools::matchingParameters(param,parNames);
+        
         for (vector<string>::iterator it = vs.begin(); it != vs.end(); it++)
         {
           parametersToEstimate.deleteParameter(*it);
@@ -823,17 +821,100 @@ throw (Exception)
     }
   }
 
-  unsigned int nbEvalMax = ApplicationTools::getParameter<unsigned int>("optimization.max_number_f_eval", params, 1000000, suffix, suffixIsOptional);
+  // Should I constrain some parameters?
+  vector<string> parToEstNames = parametersToEstimate.getParameterNames();
+  
+  if (params.find("optimization.constrain_parameter") != params.end())
+    throw Exception("optimization.constrain_parameter is deprecated, use optimization.constrain_parameters instead!");
+  paramListDesc = ApplicationTools::getStringParameter("optimization.constrain_parameters", params, "", suffix, suffixIsOptional, warn + 1);
+
+  string constraint="";
+  string pc, param="";
+  
+  StringTokenizer st2(paramListDesc, ",");
+  while (st2.hasMoreToken())
+  {
+    try
+    {
+      pc = st2.nextToken();
+      string::size_type index = pc.find("=");
+      if (index == string::npos)
+        throw Exception("PhylogeneticsApplicationTools::optimizeParamaters. Bad constrain syntax, should contain `=' symbol: " + pc);
+      param = pc.substr(0, index);
+      constraint = pc.substr(index + 1);
+      IntervalConstraint ic(constraint);
+      
+      vector<string> parNames2;
+      
+      if (param == "BrLen")
+        parNames2  = tl->getBranchLengthsParameters().getParameterNames();
+      else if (param == "Ancient"){
+        NonHomogeneousTreeLikelihood* nhtl = dynamic_cast<NonHomogeneousTreeLikelihood*>(tl);
+        if (!nhtl)
+          ApplicationTools::displayWarning("The 'Ancient' parameters do not exist in homogeneous models, and will be ignored.");
+        else
+        {
+          parNames2 = nhtl->getRootFrequenciesParameters().getParameterNames();
+          ApplicationTools::displayResult("Parameter ignored", string("Root frequencies"));
+        }
+      }
+      else if (param == "Model")
+      {
+        vector<string> vs1 = tl->getSubstitutionModelParameters().getParameterNames();
+        NonHomogeneousTreeLikelihood* nhtl = dynamic_cast<NonHomogeneousTreeLikelihood*>(tl);
+        if (nhtl!=NULL){
+          vector<string> vs2 = nhtl->getRootFrequenciesParameters().getParameterNames();
+          VectorTools::diff(vs1,vs2,parNames2);
+        }
+        else
+          parNames2=vs1;
+      }
+      else if (param.find("*") != string::npos)
+        parNames2=ApplicationTools::matchingParameters(param,parToEstNames);
+      else
+        parNames2.push_back(param);
+
+      
+      for (size_t i=0; i<parNames2.size(); i++)
+      {
+        Parameter& par=parametersToEstimate.getParameter(parNames2[i]);
+        if (par.hasConstraint()){
+          par.setConstraint(ic & (*par.getConstraint()), true);
+          if (par.getConstraint()->isEmpty())
+            throw Exception("Empty interval for parameter " + parNames[i] + par.getConstraint()->getDescription());
+        }
+        else
+          par.setConstraint(ic.clone(), true);
+
+        if (verbose)
+          ApplicationTools::displayResult("Parameter constrained " + par.getName(), par.getConstraint()->getDescription());
+      }
+    }
+    catch (ParameterNotFoundException& pnfe)
+    {
+      ApplicationTools::displayWarning("Parameter '" + pnfe.getParameter() + "' not found, and so can't be constrained!");
+    }
+    catch (ConstraintException& pnfe)
+    {
+      throw Exception("Parameter '" + param + "' does not fit the constraint " + constraint);
+    }
+  }
+
+  
+  ///////
+  /// optimization options
+  
+  unsigned int nbEvalMax = ApplicationTools::getParameter<unsigned int>("optimization.max_number_f_eval", params, 1000000, suffix, suffixIsOptional, warn + 1);
   if (verbose)
     ApplicationTools::displayResult("Max # ML evaluations", TextTools::toString(nbEvalMax));
 
-  double tolerance = ApplicationTools::getDoubleParameter("optimization.tolerance", params, .000001, suffix, suffixIsOptional);
+  double tolerance = ApplicationTools::getDoubleParameter("optimization.tolerance", params, .000001, suffix, suffixIsOptional, warn + 1);
   if (verbose)
     ApplicationTools::displayResult("Tolerance", TextTools::toString(tolerance));
 
   // Backing up or restoring?
   auto_ptr<BackupListener> backupListener;
-  string backupFile = ApplicationTools::getAFilePath("optimization.backup.file", params, false, false);
+  string backupFile = ApplicationTools::getAFilePath("optimization.backup.file", params, false, false, suffix, suffixIsOptional, "none", warn + 1);
   if (backupFile != "none")
   {
     ApplicationTools::displayResult("Parameters will be backup to", backupFile);
@@ -871,10 +952,10 @@ throw (Exception)
   }
 
   // There it goes...
-  bool optimizeTopo = ApplicationTools::getBooleanParameter("optimization.topology", params, false, suffix, suffixIsOptional, false);
+  bool optimizeTopo = ApplicationTools::getBooleanParameter("optimization.topology", params, false, suffix, suffixIsOptional, warn + 1);
   if (verbose)
     ApplicationTools::displayResult("Optimize topology", optimizeTopo ? "yes" : "no");
-  string nniMethod = ApplicationTools::getStringParameter("optimization.topology.algorithm_nni.method", params, "phyml", suffix, suffixIsOptional, false);
+  string nniMethod = ApplicationTools::getStringParameter("optimization.topology.algorithm_nni.method", params, "phyml", suffix, suffixIsOptional, warn + 1);
   string nniAlgo;
   if (nniMethod == "fast")
   {
@@ -892,7 +973,7 @@ throw (Exception)
     throw Exception("Unknown NNI algorithm: '" + nniMethod + "'.");
 
 
-  string order = ApplicationTools::getStringParameter("derivatives", optArgs, "Newton", "", true, false);
+  string order = ApplicationTools::getStringParameter("derivatives", optArgs, "Newton", "", true, warn + 1);
   string optMethodDeriv;
   if (order == "Gradient")
   {
@@ -914,12 +995,12 @@ throw (Exception)
     ApplicationTools::displayResult("Algorithm used for derivable parameters", order);
 
   // See if we should reparametrize:
-  bool reparam = ApplicationTools::getBooleanParameter("optimization.reparametrization", params, false);
+  bool reparam = ApplicationTools::getBooleanParameter("optimization.reparametrization", params, false, suffix, suffixIsOptional, warn + 1);
   if (verbose)
     ApplicationTools::displayResult("Reparametrization", (reparam ? "yes" : "no"));
 
   // See if we should use a molecular clock constraint:
-  string clock = ApplicationTools::getStringParameter("optimization.clock", params, "None", "", true, false);
+  string clock = ApplicationTools::getStringParameter("optimization.clock", params, "None", suffix, suffixIsOptional, warn + 1);
   if (clock != "None" && clock != "Global")
     throw Exception("Molecular clock option not recognized, should be one of 'Global' or 'None'.");
   bool useClock = (clock == "Global");
@@ -938,14 +1019,14 @@ throw (Exception)
     else
       optMethodModel = OptimizationTools::OPTIMIZATION_BFGS;
 
-    unsigned int nstep = ApplicationTools::getParameter<unsigned int>("nstep", optArgs, 1, "", true, false);
+    unsigned int nstep = ApplicationTools::getParameter<unsigned int>("nstep", optArgs, 1, "", true, warn + 1);
 
     if (optimizeTopo)
     {
-      bool optNumFirst = ApplicationTools::getBooleanParameter("optimization.topology.numfirst", params, true, suffix, suffixIsOptional, false);
-      unsigned int topoNbStep = ApplicationTools::getParameter<unsigned int>("optimization.topology.nstep", params, 1, "", true, false);
-      double tolBefore = ApplicationTools::getDoubleParameter("optimization.topology.tolerance.before", params, 100, suffix, suffixIsOptional);
-      double tolDuring = ApplicationTools::getDoubleParameter("optimization.topology.tolerance.during", params, 100, suffix, suffixIsOptional);
+      bool optNumFirst = ApplicationTools::getBooleanParameter("optimization.topology.numfirst", params, true, suffix, suffixIsOptional, warn + 1);
+      unsigned int topoNbStep = ApplicationTools::getParameter<unsigned int>("optimization.topology.nstep", params, 1, suffix, suffixIsOptional, warn + 1);
+      double tolBefore = ApplicationTools::getDoubleParameter("optimization.topology.tolerance.before", params, 100, suffix, suffixIsOptional, warn + 1);
+      double tolDuring = ApplicationTools::getDoubleParameter("optimization.topology.tolerance.during", params, 100, suffix, suffixIsOptional, warn + 1);
       tl = OptimizationTools::optimizeTreeNNI(
         dynamic_cast<NNIHomogeneousTreeLikelihood*>(tl), parametersToEstimate,
         optNumFirst, tolBefore, tolDuring, nbEvalMax, topoNbStep, messageHandler, profiler,
@@ -965,10 +1046,10 @@ throw (Exception)
 
     if (optimizeTopo)
     {
-      bool optNumFirst = ApplicationTools::getBooleanParameter("optimization.topology.numfirst", params, true, suffix, suffixIsOptional, false);
-      unsigned int topoNbStep = ApplicationTools::getParameter<unsigned int>("optimization.topology.nstep", params, 1, "", true, false);
-      double tolBefore = ApplicationTools::getDoubleParameter("optimization.topology.tolerance.before", params, 100, suffix, suffixIsOptional);
-      double tolDuring = ApplicationTools::getDoubleParameter("optimization.topology.tolerance.during", params, 100, suffix, suffixIsOptional);
+      bool optNumFirst = ApplicationTools::getBooleanParameter("optimization.topology.numfirst", params, true, suffix, suffixIsOptional, warn + 1);
+      unsigned int topoNbStep = ApplicationTools::getParameter<unsigned int>("optimization.topology.nstep", params, 1, suffix, suffixIsOptional, warn + 1);
+      double tolBefore = ApplicationTools::getDoubleParameter("optimization.topology.tolerance.before", params, 100, suffix, suffixIsOptional, warn + 1);
+      double tolDuring = ApplicationTools::getDoubleParameter("optimization.topology.tolerance.during", params, 100, suffix, suffixIsOptional, warn + 1);
       tl = OptimizationTools::optimizeTreeNNI2(
         dynamic_cast<NNIHomogeneousTreeLikelihood*>(tl), parametersToEstimate,
         optNumFirst, tolBefore, tolDuring, nbEvalMax, topoNbStep, messageHandler, profiler,
@@ -983,7 +1064,7 @@ throw (Exception)
   else
     throw Exception("Unknown optimization method: " + optName);
 
-  string finalMethod = ApplicationTools::getStringParameter("optimization.final", params, "none", suffix, suffixIsOptional, true);
+  string finalMethod = ApplicationTools::getStringParameter("optimization.final", params, "none", suffix, suffixIsOptional, warn + 1);
   Optimizer* finalOptimizer  = 0;
   if (finalMethod == "none")
   {}
@@ -1032,19 +1113,20 @@ void PhylogeneticsApplicationTools::optimizeParameters(
   map<string, string>& params,
   const string& suffix,
   bool suffixIsOptional,
-  bool verbose)
+  bool verbose,
+  int warn)
 throw (Exception)
 {
-  string optimization = ApplicationTools::getStringParameter("optimization", params, "FullD(derivatives=Newton)", suffix, suffixIsOptional, false);
+  string optimization = ApplicationTools::getStringParameter("optimization", params, "FullD(derivatives=Newton)", suffix, suffixIsOptional, warn);
   if (optimization == "None")
     return;
   string optName;
   map<string, string> optArgs;
   KeyvalTools::parseProcedure(optimization, optName, optArgs);
 
-  unsigned int optVerbose = ApplicationTools::getParameter<unsigned int>("optimization.verbose", params, 2, suffix, suffixIsOptional);
+  unsigned int optVerbose = ApplicationTools::getParameter<unsigned int>("optimization.verbose", params, 2, suffix, suffixIsOptional, warn + 1);
 
-  string mhPath = ApplicationTools::getAFilePath("optimization.message_handler", params, false, false, suffix, suffixIsOptional);
+  string mhPath = ApplicationTools::getAFilePath("optimization.message_handler", params, false, false, suffix, suffixIsOptional, "none", warn + 1);
   OutputStream* messageHandler =
     (mhPath == "none") ? 0 :
     (mhPath == "std") ? ApplicationTools::message :
@@ -1052,7 +1134,7 @@ throw (Exception)
   if (verbose)
     ApplicationTools::displayResult("Message handler", mhPath);
 
-  string prPath = ApplicationTools::getAFilePath("optimization.profiler", params, false, false, suffix, suffixIsOptional);
+  string prPath = ApplicationTools::getAFilePath("optimization.profiler", params, false, false, suffix, suffixIsOptional, "none", warn + 1);
   OutputStream* profiler =
     (prPath == "none") ? 0 :
     (prPath == "std") ? ApplicationTools::message :
@@ -1065,7 +1147,9 @@ throw (Exception)
   ParameterList parametersToEstimate = parameters;
 
   // Should I ignore some parameters?
-  string paramListDesc = ApplicationTools::getStringParameter("optimization.ignore_parameter", params, "", suffix, suffixIsOptional, false);
+  if (params.find("optimization.ignore_parameter") != params.end())
+    throw Exception("optimization.ignore_parameter is deprecated, use optimization.ignore_parameters instead!");
+  string paramListDesc = ApplicationTools::getStringParameter("optimization.ignore_parameters", params, "", suffix, suffixIsOptional, warn + 1);
   StringTokenizer st(paramListDesc, ",");
   while (st.hasMoreToken())
   {
@@ -1105,15 +1189,15 @@ throw (Exception)
     }
   }
 
-  unsigned int nbEvalMax = ApplicationTools::getParameter<unsigned int>("optimization.max_number_f_eval", params, 1000000, suffix, suffixIsOptional);
+  unsigned int nbEvalMax = ApplicationTools::getParameter<unsigned int>("optimization.max_number_f_eval", params, 1000000, suffix, suffixIsOptional, warn + 1);
   if (verbose)
     ApplicationTools::displayResult("Max # ML evaluations", TextTools::toString(nbEvalMax));
 
-  double tolerance = ApplicationTools::getDoubleParameter("optimization.tolerance", params, .000001, suffix, suffixIsOptional);
+  double tolerance = ApplicationTools::getDoubleParameter("optimization.tolerance", params, .000001, suffix, suffixIsOptional, warn + 1);
   if (verbose)
     ApplicationTools::displayResult("Tolerance", TextTools::toString(tolerance));
 
-  string order  = ApplicationTools::getStringParameter("derivatives", optArgs, "Gradient", "", true, false);
+  string order  = ApplicationTools::getStringParameter("derivatives", optArgs, "Gradient", "", true, warn + 1);
   string optMethod, derMethod;
   if (order == "Gradient")
   {
@@ -1132,7 +1216,7 @@ throw (Exception)
 
   // Backing up or restoring?
   auto_ptr<BackupListener> backupListener;
-  string backupFile = ApplicationTools::getAFilePath("optimization.backup.file", params, false, false);
+  string backupFile = ApplicationTools::getAFilePath("optimization.backup.file", params, false, false, suffix, suffixIsOptional, "none", warn + 1);
   if (backupFile != "none")
   {
     ApplicationTools::displayResult("Parameters will be backup to", backupFile);
@@ -1173,7 +1257,7 @@ throw (Exception)
   if (optName == "D-Brent")
   {
     // Uses Newton-Brent method:
-    unsigned int nstep = ApplicationTools::getParameter<unsigned int>("nstep", optArgs, 1, "", true, false);
+    unsigned int nstep = ApplicationTools::getParameter<unsigned int>("nstep", optArgs, 1, "", true, warn + 1);
     if (verbose && nstep > 1)
       ApplicationTools::displayResult("# of precision steps", TextTools::toString(nstep));
     n = OptimizationTools::optimizeNumericalParametersWithGlobalClock(
@@ -1205,7 +1289,7 @@ throw (Exception)
   else
     throw Exception("Unknown optimization method: " + optName);
 
-  string finalMethod = ApplicationTools::getStringParameter("optimization.final", params, "none", suffix, suffixIsOptional, false);
+  string finalMethod = ApplicationTools::getStringParameter("optimization.final", params, "none", suffix, suffixIsOptional, warn + 1);
   Optimizer* finalOptimizer  = 0;
   if (finalMethod == "none")
   {}
@@ -1262,11 +1346,6 @@ void PhylogeneticsApplicationTools::checkEstimatedParameters(const ParameterList
   }
 }
 
-
-/*************************************************************/
-/**************  OUTPUT **************************************/
-/*************************************************************/
-
 /******************************************************************************/
 
 void PhylogeneticsApplicationTools::writeTree(
@@ -1276,10 +1355,11 @@ void PhylogeneticsApplicationTools::writeTree(
   const string& suffix,
   bool suffixIsOptional,
   bool verbose,
-  bool checkOnly) throw (Exception)
+  bool checkOnly,
+  int warn) throw (Exception)
 {
-  string format = ApplicationTools::getStringParameter(prefix + "tree.format", params, "Newick", suffix, suffixIsOptional, false);
-  string file = ApplicationTools::getAFilePath(prefix + "tree.file", params, true, false, suffix, suffixIsOptional);
+  string format = ApplicationTools::getStringParameter(prefix + "tree.format", params, "Newick", suffix, suffixIsOptional, warn);
+  string file = ApplicationTools::getAFilePath(prefix + "tree.file", params, true, false, suffix, suffixIsOptional, "none", warn);
   OTree* treeWriter;
   if (format == "Newick")
     treeWriter = new Newick();
@@ -1305,10 +1385,11 @@ void PhylogeneticsApplicationTools::writeTrees(
   const string& suffix,
   bool suffixIsOptional,
   bool verbose,
-  bool checkOnly) throw (Exception)
+  bool checkOnly,
+  int warn) throw (Exception)
 {
-  string format = ApplicationTools::getStringParameter(prefix + "trees.format", params, "Newick", suffix, suffixIsOptional, false);
-  string file = ApplicationTools::getAFilePath(prefix + "trees.file", params, true, false, suffix, suffixIsOptional);
+  string format = ApplicationTools::getStringParameter(prefix + "trees.format", params, "Newick", suffix, suffixIsOptional, warn);
+  string file = ApplicationTools::getAFilePath(prefix + "trees.file", params, true, false, suffix, suffixIsOptional, "none", warn);
   OMultiTree* treeWriter;
   if (format == "Newick")
     treeWriter = new Newick();
@@ -1327,19 +1408,19 @@ void PhylogeneticsApplicationTools::writeTrees(
 
 /******************************************************************************/
 
-void PhylogeneticsApplicationTools::printParameters(const SubstitutionModel* model, OutputStream& out)
+void PhylogeneticsApplicationTools::printParameters(const SubstitutionModel* model, OutputStream& out, int warn)
 {
   out << "model=";
   map<string, string> globalAliases;
   vector<string> writtenNames;
-  BppOSubstitutionModelFormat bIO(BppOSubstitutionModelFormat::ALL, true, true, true, false);
+  BppOSubstitutionModelFormat bIO(BppOSubstitutionModelFormat::ALL, true, true, true, false, warn);
   bIO.write(*model, out, globalAliases, writtenNames);
   out.endLine();
 }
 
 /******************************************************************************/
 
-void PhylogeneticsApplicationTools::printParameters(const SubstitutionModelSet* modelSet, OutputStream& out)
+void PhylogeneticsApplicationTools::printParameters(const SubstitutionModelSet* modelSet, OutputStream& out, int warn)
 {
   (out << "nonhomogeneous=general").endLine();
   (out << "nonhomogeneous.number_of_models=" << modelSet->getNumberOfModels()).endLine();
@@ -1348,48 +1429,30 @@ void PhylogeneticsApplicationTools::printParameters(const SubstitutionModelSet*
   map< size_t, vector<string> > modelLinks; // for each model index, stores the list of global parameters.
   map< string, set<size_t> > parameterLinks; // for each parameter name, stores the list of model indices, wich should be sorted.
   vector<string> writtenNames;
-  ParameterList pl = modelSet->getParameters();
-  ParameterList plroot = modelSet->getRootFrequenciesParameters();
-  for (size_t i = 0; i < pl.size(); i++)
-  {
-    if (!plroot.hasParameter(pl[i].getName()))
-    {
-      string name = pl[i].getName();
-      vector<size_t> models = modelSet->getModelsWithParameter(name);
-      for (size_t j = 0; j < models.size(); ++j)
-      {
-        modelLinks[models[j]].push_back(name);
-        parameterLinks[name].insert(models[j]);
-      }
-    }
-  }
 
   // Loop over all models:
   for (size_t i = 0; i < modelSet->getNumberOfModels(); i++)
   {
     const SubstitutionModel* model = modelSet->getModel(i);
 
-    // First get the global aliases for this model:
-    map<string, string> globalAliases;
-    vector<string> names = modelLinks[i];
-    for (size_t j = 0; j < names.size(); j++)
-    {
-      const string name = names[j];
-      if (parameterLinks[name].size() > 1)
+    // First get the aliases for this model:
+    map<string, string> aliases;
+
+    ParameterList pl=model->getParameters();
+
+    for (size_t np = 0 ; np< pl.size() ; np++)
       {
-        // there is a global alias here
-        if (*parameterLinks[name].begin() != i) // Otherwise, this is the 'reference' value
-        {
-          globalAliases[modelSet->getParameterModelName(name)] = "model" + TextTools::toString((*parameterLinks[name].begin()) + 1) + "." + modelSet->getParameterModelName(name);
-        }
+        string nfrom = modelSet->getFrom(pl[np].getName() + "_" + TextTools::toString(i + 1));
+        if (nfrom != "")
+          aliases[pl[np].getName()] = nfrom;
       }
-    }
 
     // Now print it:
     writtenNames.clear();
     out.endLine() << "model" << (i + 1) << "=";
-    BppOSubstitutionModelFormat bIOsm(BppOSubstitutionModelFormat::ALL, true, true, true, false);
-    bIOsm.write(*model, out, globalAliases, writtenNames);
+    BppOSubstitutionModelFormat bIOsm(BppOSubstitutionModelFormat::ALL, true, true, true, false, warn);
+    map<string, string>::iterator it;
+    bIOsm.write(*model, out, aliases, writtenNames);
     out.endLine();
     vector<int> ids = modelSet->getNodesWithModel(i);
     out << "model" << (i + 1) << ".nodes_id=" << ids[0];
@@ -1405,7 +1468,7 @@ void PhylogeneticsApplicationTools::printParameters(const SubstitutionModelSet*
   (out << "# Root frequencies:").endLine();
   out << "nonhomogeneous.root_freq=";
 
-  BppOFrequenciesSetFormat bIO(BppOFrequenciesSetFormat::ALL, false);
+  BppOFrequenciesSetFormat bIO(BppOFrequenciesSetFormat::ALL, false, warn);
   bIO.write(modelSet->getRootFrequenciesSet(), out, writtenNames);
 }
 
@@ -1431,48 +1494,50 @@ SubstitutionCount* PhylogeneticsApplicationTools::getSubstitutionCount(
   const Alphabet* alphabet,
   const SubstitutionModel* model,
   map<string, string>& params,
-  string suffix)
+  string suffix,
+  bool verbose,
+  int warn)
 {
   SubstitutionCount* substitutionCount = 0;
   string nijtOption;
   map<string, string> nijtParams;
-  string nijtText = ApplicationTools::getStringParameter("nijt", params, "Uniformization", suffix, true);
+  string nijtText = ApplicationTools::getStringParameter("nijt", params, "Uniformization", suffix, true, warn);
   KeyvalTools::parseProcedure(nijtText, nijtOption, nijtParams);
 
   if (nijtOption == "Laplace")
   {
-    int trunc = ApplicationTools::getIntParameter("trunc", nijtParams, 10, suffix, true);
+    size_t trunc = ApplicationTools::getParameter<size_t>("trunc", nijtParams, 10, suffix, true, warn + 1);
     substitutionCount = new LaplaceSubstitutionCount(model, trunc);
   }
   else if (nijtOption == "Uniformization")
   {
-    string weightOption = ApplicationTools::getStringParameter("weight", nijtParams, "None", "", true, false);
+    string weightOption = ApplicationTools::getStringParameter("weight", nijtParams, "None", "", true, warn + 1);
     AlphabetIndex2* weights = SequenceApplicationTools::getAlphabetIndex2(alphabet, weightOption, "Substitution weight scheme:");
-    substitutionCount = new UniformizationSubstitutionCount(model, new TotalSubstitutionRegister(alphabet), weights);
+    substitutionCount = new UniformizationSubstitutionCount(model, new TotalSubstitutionRegister(model), weights);
   }
   else if (nijtOption == "Decomposition")
   {
-    string weightOption = ApplicationTools::getStringParameter("weight", nijtParams, "None", "", true, false);
+    string weightOption = ApplicationTools::getStringParameter("weight", nijtParams, "None", "", true, warn + 1);
     AlphabetIndex2* weights = SequenceApplicationTools::getAlphabetIndex2(alphabet, weightOption, "Substitution weight scheme:");
     const ReversibleSubstitutionModel* revModel = dynamic_cast<const ReversibleSubstitutionModel*>(model);
     if (revModel)
-      substitutionCount = new DecompositionSubstitutionCount(revModel, new TotalSubstitutionRegister(alphabet), weights);
+      substitutionCount = new DecompositionSubstitutionCount(revModel, new TotalSubstitutionRegister(model), weights);
     else
       throw Exception("Decomposition method can only be used with reversible substitution models.");
   }
   else if (nijtOption == "Naive")
   {
-    string weightOption = ApplicationTools::getStringParameter("weight", nijtParams, "None", "", true, false);
+    string weightOption = ApplicationTools::getStringParameter("weight", nijtParams, "None", "", true, warn + 1);
     AlphabetIndex2* weights = SequenceApplicationTools::getAlphabetIndex2(alphabet, weightOption, "Substitution weight scheme:");
-    substitutionCount = new NaiveSubstitutionCount(new TotalSubstitutionRegister(alphabet), false, weights);
+    substitutionCount = new NaiveSubstitutionCount(model, new TotalSubstitutionRegister(model), false, weights);
   }
   else if (nijtOption == "Label")
   {
-    substitutionCount = reinterpret_cast<SubstitutionCount*>(new LabelSubstitutionCount(alphabet));
+    substitutionCount = new LabelSubstitutionCount(model);
   }
   else if (nijtOption == "ProbOneJump")
   {
-    substitutionCount = reinterpret_cast<SubstitutionCount*>(new OneJumpSubstitutionCount(model));
+    substitutionCount = new OneJumpSubstitutionCount(model);
   }
   else
   {
diff --git a/src/Bpp/Phyl/App/PhylogeneticsApplicationTools.h b/src/Bpp/Phyl/App/PhylogeneticsApplicationTools.h
index 7872ee9..73957e3 100644
--- a/src/Bpp/Phyl/App/PhylogeneticsApplicationTools.h
+++ b/src/Bpp/Phyl/App/PhylogeneticsApplicationTools.h
@@ -95,40 +95,44 @@ namespace bpp
      *
      * See the Bio++ Program Suite manual for a description of available options.
      *
-     * @param params  The attribute map where options may be found.
-     * @param prefix  A prefix to be applied to each attribute name.
-     * @param suffix  A suffix to be applied to each attribute name.
+     * @param params           The attribute map where options may be found.
+     * @param prefix           A prefix to be applied to each attribute name.
+     * @param suffix           A suffix to be applied to each attribute name.
      * @param suffixIsOptional Tell if the suffix is absolutely required.
-     * @param verbose Print some info to the 'message' output stream.
+     * @param verbose          Print some info to the 'message' output stream.
+     * @param warn             Set the warning level (0: always display warnings, >0 display warnings on demand).
      * @return A new Tree object according to the specified options.
      * @throw Exception if an error occured.
      */
     static Tree* getTree(
-                         std::map<std::string, std::string>& params,
-                         const std::string& prefix = "input.",
-                         const std::string& suffix = "",
-                         bool suffixIsOptional = true,
-                         bool verbose = true) throw (Exception);
+        std::map<std::string, std::string>& params,
+        const std::string& prefix = "input.",
+        const std::string& suffix = "",
+        bool suffixIsOptional = true,
+        bool verbose = true,
+        int warn = 1) throw (Exception);
  
     /**
      * @brief Build a list ofTree objects according to options.
      *
      * See the Bio++ Program Suite manual for a description of available options.
      *
-     * @param params  The attribute map where options may be found.
-     * @param prefix  A prefix to be applied to each attribute name.
-     * @param suffix  A suffix to be applied to each attribute name.
+     * @param params           The attribute map where options may be found.
+     * @param prefix           A prefix to be applied to each attribute name.
+     * @param suffix           A suffix to be applied to each attribute name.
      * @param suffixIsOptional Tell if the suffix is absolutely required.
-     * @param verbose Print some info to the 'message' output stream.
+     * @param verbose          Print some info to the 'message' output stream.
+     * @param warn             Set the warning level (0: always display warnings, >0 display warnings on demand).
      * @return A new vector of Tree objects according to the specified options.
      * @throw Exception if an error occured.
      */
     static std::vector<Tree*> getTrees(
-                                       std::map<std::string, std::string>& params,
-                                       const std::string& prefix = "input.",
-                                       const std::string& suffix = "",
-                                       bool suffixIsOptional = true,
-                                       bool verbose = true) throw (Exception);
+        std::map<std::string, std::string>& params,
+        const std::string& prefix = "input.",
+        const std::string& suffix = "",
+        bool suffixIsOptional = true,
+        bool verbose = true,
+        int warn = 1) throw (Exception);
   
     /**
      * @brief Build a SubstitutionModel object according to options.
@@ -137,24 +141,29 @@ namespace bpp
      * (see the Bio++ Progam Suite manual for a detailed description of this syntax). The
      * function also parses the parameter values and set them accordingly.
      *
-     * @param alphabet The alphabet to use in the model.
-     * @param data     A pointer toward the SiteContainer for which the substitution model is designed.
-     *                 The alphabet associated to the data must be of the same type as the one specified for the model.
-     *                 May be equal to NULL, but in this case use_observed_freq option will be unavailable.
-     * @param params   The attribute map where options may be found.
-     * @param suffix   A suffix to be applied to each attribute name.
+     * @param alphabet         The alphabet to use in the model.
+     * @param gCode            The genetic code to use (only for codon models, otherwise can be set to 0).
+     *                         If set to NULL and a codon model is requested, an Exception will be thrown.
+     * @param data             A pointer toward the SiteContainer for which the substitution model is designed.
+     *                         The alphabet associated to the data must be of the same type as the one specified for the model.
+     *                         May be equal to NULL, but in this case use_observed_freq option will be unavailable.
+     * @param params           The attribute map where options may be found.
+     * @param suffix           A suffix to be applied to each attribute name.
      * @param suffixIsOptional Tell if the suffix is absolutely required.
-     * @param verbose Print some info to the 'message' output stream.
+     * @param verbose          Print some info to the 'message' output stream.
+     * @param warn             Set the warning level (0: always display warnings, >0 display warnings on demand).
      * @return A new SubstitutionModel object according to options specified.
      * @throw Exception if an error occured.
      */
     static SubstitutionModel* getSubstitutionModel(
-                                                   const Alphabet* alphabet,
-                                                   const SiteContainer* data, 
-                                                   std::map<std::string, std::string>& params,
-                                                   const std::string& suffix = "",
-                                                   bool suffixIsOptional = true,
-                                                   bool verbose = true) throw (Exception);
+        const Alphabet* alphabet,
+        const GeneticCode* gCode,
+        const SiteContainer* data, 
+        std::map<std::string, std::string>& params,
+        const std::string& suffix = "",
+        bool suffixIsOptional = true,
+        bool verbose = true,
+        int warn = 1) throw (Exception);
   
 
     /**
@@ -168,73 +177,81 @@ namespace bpp
      * @param model                   The model to set.
      * @param unparsedParameterValues A map that contains all the model parameters
      *                                names and their corresponding unparsed value, if they were found.
-     * @param modelPrefix The prefix to use to record prameters from this model.
+     * @param modelNumber The number of this model in the SubstitutionModelSet.
      * @param data   A pointer toward the SiteContainer for which the substitution model is designed.
      *               The alphabet associated to the data must be of the same type as the one specified for the model.
      *               May be equal to NULL, but in this case use_observed_freq option will be unavailable.
      * @param existingParams (in/out) A map with already existing value that have been found in previous calls, and may be recalled here.
      *                       New parameters found here will be added.
-     * @param specificParams (out) Parameters specific to this model will be recorded here.
      * @param sharedParams (out) remote parameters will be recorded here.
      * @param verbose Print some info to the 'message' output stream.
      * @throw Exception if an error occured.
      */
     static void setSubstitutionModelParametersInitialValuesWithAliases(
-        SubstitutionModel& model,
-        std::map<std::string, std::string>& unparsedParameterValues,
-        const std::string& modelPrefix,
-        const SiteContainer* data,
-        std::map<std::string, double>& existingParams,
-        std::vector<std::string>& specificParams,
-        std::vector<std::string>& sharedParams,
-        bool verbose) throw (Exception);
+                                                                       SubstitutionModel& model,
+                                                                       std::map<std::string, std::string>& unparsedParameterValues,
+                                                                       size_t modelNumber,
+                                                                       const SiteContainer* data,
+                                                                       std::map<std::string, double>& existingParams,
+                                                                       std::map<std::string, std::string>& sharedParams,
+                                                                       bool verbose) throw (Exception);
 
     /**
      * @brief Get A FrequenciesSet object for root frequencies (NH models) according to options.
      *
-     * @param alphabet The alpabet to use.
-     * @param data      A pointer toward the SiteContainer for which the substitution model is designed.
-     *                  The alphabet associated to the data must be of the same type as the one specified for the model.
-     *                  May be equal to NULL, but in this cas use_observed_freq option will be unavailable.
-     * @param params    The attribute map where options may be found.
-     * @param rateFreqs A vector of rate catégories frequencies in case of a Markov Modulated Markov Model.
-     *                  Ignored if a vector with size 0 is passed.
-     * @param suffix    A suffix to be applied to each attribute name.
+     * @param alphabet         The alpabet to use.
+     * @param gCode            The genetic code to use (only for codon alphabets, otherwise can be set to 0).
+     *                         If set to NULL and a codon frequencies set is requested, an Exception will be thrown.
+     * @param data             A pointer toward the SiteContainer for which the substitution model is designed.
+     *                         The alphabet associated to the data must be of the same type as the one specified for the model.
+     *                         May be equal to NULL, but in this cas use_observed_freq option will be unavailable.
+     * @param params           The attribute map where options may be found.
+     * @param rateFreqs        A vector of rate catégories frequencies in case of a Markov Modulated Markov Model.
+     *                         Ignored if a vector with size 0 is passed.
+     * @param suffix           A suffix to be applied to each attribute name.
      * @param suffixIsOptional Tell if the suffix is absolutely required.
-     * @param verbose   Print some info to the 'message' output stream.
+     * @param verbose          Print some info to the 'message' output stream.
+     * @param warn             Set the warning level (0: always display warnings, >0 display warnings on demand).
      * @return A new FrequenciesSet object according to options specified.
      * @throw Exception if an error occured.
      */
     static FrequenciesSet* getRootFrequenciesSet(
         const Alphabet* alphabet,
+        const GeneticCode* gCode,
         const SiteContainer* data, 
         std::map<std::string, std::string>& params,
         const std::vector<double>& rateFreqs,
         const std::string& suffix = "",
         bool suffixIsOptional = true,
-        bool verbose = true) throw (Exception);
+        bool verbose = true,
+        int warn = 1) throw (Exception);
 
     /**
      * @brief Get A FrequenciesSet object according to options.
      *
-     * @param alphabet The alpabet to use.
-     * @param freqDescription A string in the keyval syntaxe describing the frequency set to use.:if expand("%") == ""|browse confirm w|else|confirm w|endif
+     * @param alphabet         The alpabet to use.
+     * @param gCode            The genetic code to use (only for codon alphabets, otherwise can be set to 0).
+     *                         If set to NULL and a codon frequencies set is requested, an Exception will be thrown.
+     * @param freqDescription  A string in the keyval syntaxe describing the frequency set to use.:if expand("%") == ""|browse confirm w|else|confirm w|endif
      * 
-     * @param data      A pointer toward the SiteContainer for which the substitution model is designed.
-     *                  The alphabet associated to the data must be of the same type as the one specified for the model.
-     *                  May be equal to NULL, but in this cas use_observed_freq option will be unavailable.
-     * @param rateFreqs A vector of rate catégories frequencies in case of a Markov Modulated Markov Model.
-     *                  Ignored if a vector with size 0 is passed.
-     * @param verbose   Print some info to the 'message' output stream.
+     * @param data             A pointer toward the SiteContainer for which the substitution model is designed.
+     *                         The alphabet associated to the data must be of the same type as the one specified for the model.
+     *                         May be equal to NULL, but in this cas use_observed_freq option will be unavailable.
+     * @param rateFreqs        A vector of rate catégories frequencies in case of a Markov Modulated Markov Model.
+     *                         Ignored if a vector with size 0 is passed.
+     * @param verbose          Print some info to the 'message' output stream.
+     * @param warn             Set the warning level (0: always display warnings, >0 display warnings on demand).
      * @return A new FrequenciesSet object according to options specified.
      * @throw Exception if an error occured.
      */
     static FrequenciesSet* getFrequenciesSet(
         const Alphabet* alphabet,
+        const GeneticCode* gCode,
         const std::string& freqDescription,
         const SiteContainer* data, 
         const std::vector<double>& rateFreqs,
-        bool verbose = true)
+        bool verbose = true,
+        int warn = 1)
       throw (Exception);
 
     /**
@@ -244,14 +261,16 @@ namespace bpp
      * methods.
      */
      static SubstitutionModelSet* getSubstitutionModelSet(
-                                        const Alphabet* alphabet,
-                                        const SiteContainer* data, 
-                                        std::map<std::string, std::string>& params,
-                                        const std::string& suffix = "",
-                                        bool suffixIsOptional = true,
-                                        bool verbose = true);    
-
-     /**
+         const Alphabet* alphabet,
+         const GeneticCode* gcode,
+         const SiteContainer* data, 
+         std::map<std::string, std::string>& params,
+         const std::string& suffix = "",
+         bool suffixIsOptional = true,
+         bool verbose = true,
+         int warn = 1);    
+
+    /**
      * @brief Sets a SubstitutionModelSet object according to options.
      *
      * This model set is meant to be used with non-homogeneous substitution models of sequence evolution.
@@ -291,25 +310,30 @@ namespace bpp
      * @endcode
      * but will require more memory and use more CPU, since some calculations will be performed twice.
      *
-     * @param modelSet The modified SubstitutionModelSet object according to options specified.
-     * @param alphabet The alpabet to use in all models.
-     * @param data     A pointer toward the SiteContainer for which the substitution model is designed.
-     *                  The alphabet associated to the data must be of the same type as the one specified for the model.
-     *                 May be equal to NULL, but in this cas use_observed_freq option will be unavailable.
-     * @param params   The attribute map where options may be found.
-     * @param suffix   A suffix to be applied to each attribute name.
+     * @param modelSet         The modified SubstitutionModelSet object according to options specified.
+     * @param alphabet         The alpabet to use in all models.
+     * @param gcode            The genetic code to use (only for codon models, otherwise can be set to 0).
+     *                         If set to NULL and a codon model is requested, an Exception will be thrown.
+     * @param data             A pointer toward the SiteContainer for which the substitution model is designed.
+     *                         The alphabet associated to the data must be of the same type as the one specified for the model.
+     *                         May be equal to NULL, but in this cas use_observed_freq option will be unavailable.
+     * @param params           The attribute map where options may be found.
+     * @param suffix           A suffix to be applied to each attribute name.
      * @param suffixIsOptional Tell if the suffix is absolutely required.
-     * @param verbose Print some info to the 'message' output stream.
+     * @param verbose          Print some info to the 'message' output stream.
+     * @param warn             Set the warning level (0: always display warnings, >0 display warnings on demand).
      * @throw Exception if an error occured.
      */
     static void setSubstitutionModelSet(
-                                        SubstitutionModelSet& modelSet,
-                                        const Alphabet* alphabet,
-                                        const SiteContainer* data, 
-                                        std::map<std::string, std::string>& params,
-                                        const std::string& suffix = "",
-                                        bool suffixIsOptional = true,
-                                        bool verbose = true);
+        SubstitutionModelSet& modelSet,
+        const Alphabet* alphabet,
+        const GeneticCode* gcode,
+        const SiteContainer* data, 
+        std::map<std::string, std::string>& params,
+        const std::string& suffix = "",
+        bool suffixIsOptional = true,
+        bool verbose = true,
+        int warn = 1);
     
     /**
      * @brief Complete a MixedSubstitutionModelSet object according to
@@ -362,26 +386,27 @@ namespace bpp
      * See MixedSubstitutionModelSet description for further
      * information.
      *
-     * @param mixedModelSet The modified MixedSubstitutionModelSet object according to options specified.
-     * @param alphabet The alpabet to use in all models.
-     * @param data     A pointer toward the SiteContainer for which the substitution model is designed.
-     *                  The alphabet associated to the data must be of the same type as the one specified for the model.
-     *                 May be equal to NULL, but in this cas use_observed_freq option will be unavailable.
-     * @param params   The attribute map where options may be found.
-     * @param suffix   A suffix to be applied to each attribute name.
+     * @param mixedModelSet    The modified MixedSubstitutionModelSet object according to options specified.
+     * @param alphabet         The alpabet to use in all models.
+     * @param data             A pointer toward the SiteContainer for which the substitution model is designed.
+     *                         The alphabet associated to the data must be of the same type as the one specified for the model.
+     *                         May be equal to NULL, but in this cas use_observed_freq option will be unavailable.
+     * @param params           The attribute map where options may be found.
+     * @param suffix           A suffix to be applied to each attribute name.
      * @param suffixIsOptional Tell if the suffix is absolutely required.
-     * @param verbose Print some info to the 'message' output stream.
+     * @param verbose          Print some info to the 'message' output stream.
+     * @param warn             Set the warning level (0: always display warnings, >0 display warnings on demand).
      * @throw Exception if an error occured.
      */
-    
     static void completeMixedSubstitutionModelSet(
-                                             MixedSubstitutionModelSet& mixedModelSet,
-                                             const Alphabet* alphabet,
-                                             const SiteContainer* data, 
-                                             std::map<std::string, std::string>& params,
-                                             const std::string& suffix = "",
-                                             bool suffixIsOptional = true,
-                                             bool verbose = true);
+        MixedSubstitutionModelSet& mixedModelSet,
+        const Alphabet* alphabet,
+        const SiteContainer* data, 
+        std::map<std::string, std::string>& params,
+        const std::string& suffix = "",
+        bool suffixIsOptional = true,
+        bool verbose = true,
+        int warn = 1);
 
     /**
      * @brief Build a multi-dimension distribution as a
@@ -398,11 +423,10 @@ namespace bpp
      * @return A new MultipleDiscreteDistribution object according to options specified.
      * @throw Exception if an error occured.
      */
-    
     static MultipleDiscreteDistribution* getMultipleDistributionDefaultInstance(
-                                                                        const std::string& distDescription,
-                                                                        std::map<std::string, std::string>& unparsedParameterValues,
-                                                                        bool verbose = true);
+        const std::string& distDescription,
+        std::map<std::string, std::string>& unparsedParameterValues,
+        bool verbose = true);
 
     /**
      * @brief Build a DiscreteDistribution object according to options.
@@ -428,36 +452,6 @@ namespace bpp
     /**
      * @brief Optimize parameters according to options.
      *
-     * Options used are:
-     * - optimization = Tell if optimization must be performed.
-     * - optimization.message_handler = [std, file_path]
-     *   A path to a specific path (existing will be overwritten) or std for use
-     *   of the standard output.
-     * - optimization.profiler = [std, file_path], idem for the profiling (history
-     *   of all functions evaluations).
-     * - optimization.max_number_f_eval = The maximum number of function evaluation.
-     * - optimization.tolerance = The tolerance parameter (when to stop the optimization).
-     * - optimization.scale_first = Tell if we must scale the tree first.
-     * - optimization.ignore_parameter = A coma-separated list of parameter
-     *   names to ignore in the optimizing process.
-     * - optimization.method = [DB|fullD] Algorithm to use: Derivatives+Brent or full derivatives, with numerical derivatives when required.
-     * - optimization.method.derivatives = [gradient|newton] Use Conjugate Grandient or Newton-Rhaphson algorithm.
-     * - optimization.final = [none|simplex|powell] Perform a downhill simplex or a Powell multidimensions optimization
-     * - optimization.topology = Tell if we must optimize tree topology. Toplogy estimation uses the DB algorithm with Newton-Raphson during estimation.
-     *   The previous options will be used only for final estimation of numerical parameters.
-     * Options depending on other options:
-     * - If optimization.scale_first is set to true:
-     *   - optimization.scale_first.tolerance = The tolerance of the scaling alogrithm.
-     *   - optimization.scale_first.max_number_f_eval = the maximum number of function evaluations
-     *     for the scaling algorithm.
-     * - optimization.method_DB.nstep = number of progressive steps to use in DB algorithm.
-     * - optimization.topology.algorithm = [nni] algorithm to use (for now, only Nearest Neighbor Interchanges (NNI) are implemented). 
-     * - optimization.topology.algorithm_nni.method = [fast,better,phyml]
-     * - optimization.topology.nstep = Estimate numerical parameters every 'n' NNI rounds.
-     * - optimization.topology.numfirst = Tell if numerical parameters must be estimated prior to topology search.
-     * - optimization.topology.tolerance.before = Numerical parameters estimation prior to topology search.
-     * - optimization.topology.tolerance.during = Numerical parameters estimation during topology search.
-     *
      * @param tl               The TreeLikelihood function to optimize.
      * @param parameters       The initial list of parameters to optimize.
      *                         Use tl->getIndependentParameters() in order to estimate all parameters.
@@ -465,6 +459,7 @@ namespace bpp
      * @param suffix           A suffix to be applied to each attribute name.
      * @param suffixIsOptional Tell if the suffix is absolutely required.
      * @param verbose          Print some info to the 'message' output stream.
+     * @param warn             Set the warning level (0: always display warnings, >0 display warnings on demand).
      * @throw Exception        Any exception that may happen during the optimization process.
      * @return A pointer toward the final likelihood object.
      * This pointer may be the same as passed in argument (tl), but in some cases the algorithm
@@ -480,28 +475,13 @@ namespace bpp
         std::map<std::string, std::string>& params,
         const std::string& suffix = "",
         bool suffixIsOptional = true,
-        bool verbose = true)
+        bool verbose = true,
+        int warn = 1)
       throw (Exception);
     
     /**
      * @brief Optimize parameters according to options, with a molecular clock.
      *
-     * Options used are:
-     * - optimization = Tell if optimization must be performed.
-     * - optimization.message_handler = [std, file_path]
-     *   A path to a specific path (existing will be overwritten) or std for use
-     *   of the standard output.
-     * - optimization.profiler = [std, file_path], idem for the profiling (history
-     *   of all functions evaluations).
-     * - optimization.max_number_f_eval = The maximum number of function evaluation.
-     * - optimization.tolerance = The tolerance parameter (when to stop the optimization).
-     * - optimization.ignore_parameter = A coma-separated list of parameter
-     *   names to ignore in the optimizing process.
-     * - optimization.method = [DB|fullD] Algorithm to use: Derivatives+Brent or full derivatives, with numerical derivatives when required.
-     * - optimization.method.derivatives = [gradient|newton] Use Conjugate Grandient or Newton-Rhaphson algorithm.
-     * - optimization.final = [none|simplex|powell] Perform a downhill simplex or a Powell multidimensions optimization
-     * - optimization.method_DB.nstep = number of progressive steps to use in DB algorithm.
-     *
      * @param tl               The ClockTreeLikelihood function to optimize.
      * @param parameters       The initial list of parameters to optimize.
      *                         Use tl->getIndependentParameters() in order to estimate all parameters.
@@ -509,6 +489,7 @@ namespace bpp
      * @param suffix           A suffix to be applied to each attribute name.
      * @param suffixIsOptional Tell if the suffix is absolutely required.
      * @param verbose          Print some info to the 'message' output stream.
+     * @param warn             Set the warning level (0: always display warnings, >0 display warnings on demand).
      * @throw Exception        Any exception that may happen during the optimization process.
      */
     static void optimizeParameters(
@@ -517,7 +498,8 @@ namespace bpp
         std::map<std::string, std::string>& params,
         const std::string& suffix = "",
         bool suffixIsOptional = true,
-        bool verbose = true)
+        bool verbose = true,
+        int warn = 1)
       throw (Exception);
     
     /**
@@ -537,12 +519,17 @@ namespace bpp
      * @param model The model to use.
      * @param params The attribute map where options may be found.
      * @param suffix Optional suffix for command name.
+     * @param verbose          Print some info to the 'message' output stream.
+     * @param warn Set the warning level (0: always display warnings, >0 display warnings on demand).
+     * @return A SubstitutionCount object.
      */
     static SubstitutionCount* getSubstitutionCount(
         const Alphabet* alphabet,
         const SubstitutionModel* model,
         map<string, string>& params,
-        string suffix = "");
+        string suffix = "",
+        bool verbose = true,
+        int warn = 1);
    
     /**
      * @brief Write a tree according to options.
@@ -557,6 +544,7 @@ namespace bpp
      * @param verbose Print some info to the 'message' output stream.
      * @param checkOnly If this parameter is set to true, then all options are
      * checked and error messages sent, but no file is written.
+     * @param warn             Set the warning level (0: always display warnings, >0 display warnings on demand).
      * @throw Exception if an error occured.
      */
     static void writeTree(
@@ -566,21 +554,23 @@ namespace bpp
         const std::string& suffix = "",
         bool suffixIsOptional = true,
         bool verbose = true,
-        bool checkOnly = false) throw (Exception);
+        bool checkOnly = false,
+        int warn = 1) throw (Exception);
     
     /**
      * @brief Write a tree according to options.
      *
      * See the Bio++ Program Suite manual for a descriptio of all available options.
      *
-     * @param trees   The trees to write.
-     * @param params  The attribute map where options may be found.
-     * @param prefix  A prefix to be applied to each attribute name.
-     * @param suffix  A suffix to be applied to each attribute name.
+     * @param trees            The trees to write.
+     * @param params           The attribute map where options may be found.
+     * @param prefix           A prefix to be applied to each attribute name.
+     * @param suffix           A suffix to be applied to each attribute name.
      * @param suffixIsOptional Tell if the suffix is absolutely required.
-     * @param verbose Print some info to the 'message' output stream.
-     * @param checkOnly If this parameter is set to true, then all options are
-     * checked and error messages sent, but no file is written.
+     * @param verbose          Print some info to the 'message' output stream.
+     * @param checkOnly        If this parameter is set to true, then all options are
+     *                         checked and error messages sent, but no file is written.
+     * @param warn             Set the warning level (0: always display warnings, >0 display warnings on demand).
      * @throw Exception if an error occured.
      */
     static void writeTrees(
@@ -590,7 +580,8 @@ namespace bpp
         const std::string& suffix = "",
         bool suffixIsOptional = true,
         bool verbose = true,
-        bool checkOnly = false) throw (Exception);
+        bool checkOnly = false,
+        int warn = 1) throw (Exception);
 
 
     
@@ -599,8 +590,9 @@ namespace bpp
      *
      * @param model The model to serialize.
      * @param out   The stream where to print.
+     * @param warn  Set the warning level (0: always display warnings, >0 display warnings on demand).
      */
-    static void printParameters(const SubstitutionModel* model, OutputStream& out);
+    static void printParameters(const SubstitutionModel* model, OutputStream& out,int warn = 1);
 
 
 
@@ -609,8 +601,9 @@ namespace bpp
      *
      * @param modelSet The model set to serialize.
      * @param out      The stream where to print.
+     * @param warn  Set the warning level (0: always display warnings, >0 display warnings on demand).
      */
-    static void printParameters(const SubstitutionModelSet* modelSet, OutputStream& out);
+    static void printParameters(const SubstitutionModelSet* modelSet, OutputStream& out, int warn = 1);
 
 
 
diff --git a/src/Bpp/Phyl/BipartitionList.cpp b/src/Bpp/Phyl/BipartitionList.cpp
index c4f06eb..291130f 100644
--- a/src/Bpp/Phyl/BipartitionList.cpp
+++ b/src/Bpp/Phyl/BipartitionList.cpp
@@ -118,7 +118,7 @@ BipartitionList::BipartitionList(const Tree& tr, bool sorted, std::vector<int>*
   if (sorted)
     std::sort(elements_.begin(), elements_.end());
 
-  size_t lword  = BipartitionTools::LWORD;
+  size_t lword  = static_cast<size_t>(BipartitionTools::LWORD);
   size_t nbword = (elements_.size() + lword - 1) / lword;
   size_t nbint  = nbword * lword / (CHAR_BIT * sizeof(int));
 
@@ -156,7 +156,7 @@ BipartitionList::BipartitionList(
   elements_(elements),
   sorted_()
 {
-  size_t lword  = BipartitionTools::LWORD;
+  size_t lword  = static_cast<size_t>(BipartitionTools::LWORD);
   size_t nbword = (elements.size() + lword - 1) / lword;
   size_t nbint  = nbword * lword / (CHAR_BIT * sizeof(int));
 
@@ -184,7 +184,7 @@ BipartitionList::BipartitionList(const BipartitionList& bipL) :
   elements_(bipL.elements_),
   sorted_(bipL.sorted_)
 {
-  size_t lword  = BipartitionTools::LWORD;
+  size_t lword  = static_cast<size_t>(BipartitionTools::LWORD);
   size_t nbword = (bipL.getNumberOfElements() + lword - 1) / lword;
   size_t nbint  = nbword * lword / (CHAR_BIT * sizeof(int));
 
@@ -204,7 +204,7 @@ BipartitionList::BipartitionList(const BipartitionList& bipL) :
 
 BipartitionList& BipartitionList::operator=(const BipartitionList& bipL)
 {
-  size_t lword  = BipartitionTools::LWORD;
+  size_t lword  = static_cast<size_t>(BipartitionTools::LWORD);
   size_t nbword = (bipL.getNumberOfElements() + lword - 1) / lword;
   size_t nbint  = nbword * lword / (CHAR_BIT * sizeof(int));
 
@@ -296,7 +296,7 @@ void BipartitionList::addBipartition(map<string, bool>& bipart, bool checkElemen
   if (checkElements && !BipartitionList::haveSameElementsThan(bipart))
     throw Exception("Distinct bipartition element sets");
 
-  size_t lword  = BipartitionTools::LWORD;
+  size_t lword  = static_cast<size_t>(BipartitionTools::LWORD);
   size_t nbword = (elements_.size() + lword - 1) / lword;
   size_t nbint  = nbword * lword / (CHAR_BIT * sizeof(int));
   bitBipartitionList_.push_back(new int[nbint]);
@@ -323,7 +323,7 @@ void BipartitionList::deleteBipartition(size_t i) throw (Exception)
     throw Exception("Bipartition index exceeds BipartitionList size");
 
   delete[] bitBipartitionList_[i];
-  bitBipartitionList_.erase(bitBipartitionList_.begin() + i);
+  bitBipartitionList_.erase(bitBipartitionList_.begin() + static_cast<ptrdiff_t>(i));
 }
 
 /******************************************************************************/
@@ -494,7 +494,7 @@ void BipartitionList::sortElements()
 
   nbbip = bitBipartitionList_.size();
   bitBipartitionList_.resize(2 * nbbip);
-  size_t lword  = BipartitionTools::LWORD;
+  size_t lword  = static_cast<size_t>(BipartitionTools::LWORD);
   size_t nbword = (elements_.size() + lword - 1) / lword;
   size_t nbint  = nbword * lword / (CHAR_BIT * sizeof(int));
 
@@ -519,7 +519,7 @@ void BipartitionList::sortElements()
     delete[] bitBipartitionList_[j];
   }
 
-  bitBipartitionList_.erase(bitBipartitionList_.begin(), bitBipartitionList_.begin() + nbbip);
+  bitBipartitionList_.erase(bitBipartitionList_.begin(), bitBipartitionList_.begin() + static_cast<ptrdiff_t>(nbbip));
   sorted_ = true;
 }
 
@@ -606,7 +606,7 @@ void BipartitionList::flip(size_t k) throw (Exception)
 {
   if (k >= bitBipartitionList_.size())
     throw Exception("Bipartition index exceeds BipartitionList size");
-  size_t lword = BipartitionTools::LWORD;
+  size_t lword = static_cast<size_t>(BipartitionTools::LWORD);
   size_t nbword = (elements_.size() + lword - 1) / lword;
   size_t nbint = nbword * lword / (CHAR_BIT * sizeof(int));
   int* flipbip = new int[nbint];
@@ -676,7 +676,7 @@ TreeTemplate<Node>* BipartitionList::toTree() const throw (Exception)
     alive.push_back(true);
   }
   vecNd.resize(sortedBipL->getNumberOfBipartitions() + 1);
-  lword  = BipartitionTools::LWORD;
+  lword  = static_cast<size_t>(BipartitionTools::LWORD);
   nbword = (elements_.size() + lword - 1) / lword;
   nbint  = nbword * lword / (CHAR_BIT * sizeof(int));
   bip    = new int[1]; bip[0] = 0;
diff --git a/src/Bpp/Phyl/BipartitionTools.cpp b/src/Bpp/Phyl/BipartitionTools.cpp
index a387082..2b86927 100644
--- a/src/Bpp/Phyl/BipartitionTools.cpp
+++ b/src/Bpp/Phyl/BipartitionTools.cpp
@@ -60,7 +60,7 @@ using namespace std;
 
 /******************************************************************************/
 
-size_t BipartitionTools::LWORD = CHAR_BIT * sizeof(int);
+int BipartitionTools::LWORD = static_cast<int>(CHAR_BIT * sizeof(int));
 
 /******************************************************************************/
 
@@ -216,14 +216,14 @@ BipartitionList* BipartitionTools::mergeBipartitionLists(
 
   if (checkElements)
   {
-    for (size_t i = 1; i < vecBipartL.size(); i++)
+    for (size_t i = 1; i < vecBipartL.size(); ++i)
     {
       if (!VectorTools::haveSameElements(vecBipartL[0]->getElementNames(), vecBipartL[0]->getElementNames()))
         throw Exception("BipartitionTools::mergeBipartitionLists. Distinct bipartition element sets");
     }
   }
 
-  size_t lword  = BipartitionTools::LWORD;
+  size_t lword  = static_cast<size_t>(BipartitionTools::LWORD);
   size_t nbword = (vecBipartL[0]->getElementNames().size() + lword - 1) / lword;
   size_t nbint  = nbword * lword / (CHAR_BIT * sizeof(int));
 
@@ -327,3 +327,90 @@ VectorSiteContainer* BipartitionTools::MRPEncode(
 
 /******************************************************************************/
 
+VectorSiteContainer* BipartitionTools::MRPEncodeMultilabel(
+                                                 const vector<BipartitionList*>& vecBipartL) throw (Exception)
+{
+    vector<string> all_elements;
+    map<string, bool> bip;
+    vector<string> bip_elements;
+    const DNA* alpha = &AlphabetTools::DNA_ALPHABET;
+    vector<string> sequences;
+    
+    if (vecBipartL.size() == 0)
+        throw Exception("Empty vector passed");
+    
+    vector< vector<string> > vecElementLists;
+    for (size_t i = 0; i < vecBipartL.size(); i++)
+    {
+        vecElementLists.push_back(vecBipartL[i]->getElementNames());
+    }
+    
+    all_elements = VectorTools::vectorUnion(vecElementLists);
+    
+    sequences.resize(all_elements.size());
+    
+    for (size_t i = 0; i < vecBipartL.size(); i++)
+    {
+        for (size_t j = 0; j < vecBipartL[i]->getNumberOfBipartitions(); j++)
+        {
+            bip = vecBipartL[i]->getBipartition(j);
+            bip_elements = MapTools::getKeys(bip);
+            //Check for multilabel trees: if a taxa found on both sides, do not consider the entire bipartition
+            vector< string > zeroes;
+            vector< string > ones;
+            for (size_t k = 0; k < all_elements.size(); k++)
+            {
+                if (VectorTools::contains(bip_elements, all_elements[k]))
+                {
+                    if (bip[all_elements[k]])
+                        ones.push_back(all_elements[k]);
+                    else
+                        zeroes.push_back(all_elements[k]);
+                }
+            }
+            vector<string> inter = VectorTools::vectorIntersection(ones, zeroes);
+            if (inter.size() != 0) { //some taxa found on both sides of the bipartition
+                for (size_t k = 0; k < all_elements.size(); k++)
+                {
+                    sequences[k].push_back('N');
+                }
+            }
+            else
+            {
+                for (size_t k = 0; k < all_elements.size(); k++)
+                {
+                    if (VectorTools::contains(bip_elements, all_elements[k]))
+                    {
+                        if (bip[all_elements[k]])
+                            sequences[k].push_back('C');
+                        else
+                            sequences[k].push_back('A');
+                    }
+                    else
+                        sequences[k].push_back('N');
+                }
+            }
+        }
+    }
+    
+    vector<const Sequence*> vec_sequences;
+    for (size_t i = 0; i < all_elements.size(); i++)
+    {
+        const Sequence* seq = new BasicSequence(all_elements[i], sequences[i], alpha);
+        vec_sequences.push_back(seq);
+    }
+    
+    VectorSequenceContainer vec_seq_cont(vec_sequences, alpha);
+    for (size_t i = 0; i < all_elements.size(); i++)
+    {
+        delete vec_sequences[i];
+    }
+    
+    VectorSiteContainer* vec_site_cont = new VectorSiteContainer(vec_seq_cont);
+    
+    return vec_site_cont;
+}
+
+/******************************************************************************/
+
+
diff --git a/src/Bpp/Phyl/BipartitionTools.h b/src/Bpp/Phyl/BipartitionTools.h
index f9e0dba..63cb725 100644
--- a/src/Bpp/Phyl/BipartitionTools.h
+++ b/src/Bpp/Phyl/BipartitionTools.h
@@ -66,7 +66,7 @@ public:
    * Unit length (in bits) of arrays of bits. Must be a multiple of CHAR_BIT*sizeof(int).
    * Default value is 64.
    */
-  static size_t LWORD;
+  static int LWORD;
 
 public:
   BipartitionTools() {}
@@ -164,6 +164,16 @@ public:
    * according to the MRP supertree method.
    */
   static VectorSiteContainer* MRPEncode(const std::vector<BipartitionList*>& vecBipartL) throw (Exception);
+    
+    /**
+     * @brief Create a sequence data set corresponding to the Matrix Representation of the input BipartitionList objects and accomodates multilabel trees
+     *
+     * The input BipartitionList objects can have distinct sets of elements - missing data will be represented as 'N'.
+     * The output alignment (DNA sequences including only A, C and N)) is ready for maximum parsimony analysis
+     * according to the MRP supertree method.
+     */
+    static VectorSiteContainer* MRPEncodeMultilabel(                                                                     const std::vector<BipartitionList*>& vecBipartL) throw (Exception);
+
 };
 } // end of namespace bpp.
 
diff --git a/src/Bpp/Phyl/Distance/AbstractAgglomerativeDistanceMethod.cpp b/src/Bpp/Phyl/Distance/AbstractAgglomerativeDistanceMethod.cpp
index 8c04ca9..e9fdb37 100755
--- a/src/Bpp/Phyl/Distance/AbstractAgglomerativeDistanceMethod.cpp
+++ b/src/Bpp/Phyl/Distance/AbstractAgglomerativeDistanceMethod.cpp
@@ -50,8 +50,10 @@ using namespace bpp;
 
 using namespace std;
 
-void AbstractAgglomerativeDistanceMethod::setDistanceMatrix(const DistanceMatrix& matrix)
+void AbstractAgglomerativeDistanceMethod::setDistanceMatrix(const DistanceMatrix& matrix) throw (Exception)
 {
+  if (matrix.size() <= 3)
+    throw Exception("AbstractAgglomerativeDistanceMethod::setDistanceMatrix(): matrix must be at least of dimension 3.");
   matrix_ = matrix;
   currentNodes_.clear();
   if (tree_) delete tree_;
diff --git a/src/Bpp/Phyl/Distance/AbstractAgglomerativeDistanceMethod.h b/src/Bpp/Phyl/Distance/AbstractAgglomerativeDistanceMethod.h
index a404c7e..4041be6 100755
--- a/src/Bpp/Phyl/Distance/AbstractAgglomerativeDistanceMethod.h
+++ b/src/Bpp/Phyl/Distance/AbstractAgglomerativeDistanceMethod.h
@@ -111,7 +111,7 @@ class AbstractAgglomerativeDistanceMethod:
     }
 
 	public:
-		virtual void setDistanceMatrix(const DistanceMatrix& matrix);
+		virtual void setDistanceMatrix(const DistanceMatrix& matrix) throw (Exception);
 
     /**
      * @brief Get the computed tree, if there is one.
diff --git a/src/Bpp/Phyl/Distance/BioNJ.h b/src/Bpp/Phyl/Distance/BioNJ.h
index 0c44f89..9be4a7d 100644
--- a/src/Bpp/Phyl/Distance/BioNJ.h
+++ b/src/Bpp/Phyl/Distance/BioNJ.h
@@ -98,7 +98,7 @@ public:
 public:
   std::string getName() const { return "BioNJ"; }
 
-  void setDistanceMatrix(const DistanceMatrix& matrix)
+  void setDistanceMatrix(const DistanceMatrix& matrix) throw (Exception)
   {
     NeighborJoining::setDistanceMatrix(matrix);
     variance_ = matrix;
diff --git a/src/Bpp/Phyl/Distance/DistanceEstimation.cpp b/src/Bpp/Phyl/Distance/DistanceEstimation.cpp
index e578e11..7fa7d70 100755
--- a/src/Bpp/Phyl/Distance/DistanceEstimation.cpp
+++ b/src/Bpp/Phyl/Distance/DistanceEstimation.cpp
@@ -6,7 +6,7 @@
 //
 
 /*
-   Copyright or © or Copr. CNRS, (November 16, 2004)
+   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.
@@ -140,7 +140,7 @@ TwoTreeLikelihood::TwoTreeLikelihood(const TwoTreeLikelihood& lik) :
   leafLikelihoods1_  (lik.leafLikelihoods1_),
   leafLikelihoods2_  (lik.leafLikelihoods2_),
   minimumBrLen_      (lik.minimumBrLen_),
-  brLenConstraint_   (dynamic_cast<Constraint*>(brLenConstraint_->clone())),
+  brLenConstraint_   (dynamic_cast<Constraint*>(lik.brLenConstraint_->clone())),
   brLen_             (lik.brLen_)
 {}
 
@@ -264,14 +264,14 @@ double TwoTreeLikelihood::getLogLikelihoodForASiteForARateClass(size_t site, siz
 
 double TwoTreeLikelihood::getLikelihoodForASiteForARateClassForAState(size_t site, size_t rateClass, int state) const
 {
-  return rootLikelihoods_[rootPatternLinks_[site]][rateClass][state];
+  return rootLikelihoods_[rootPatternLinks_[site]][rateClass][static_cast<size_t>(state)];
 }
 
 /******************************************************************************/
 
 double TwoTreeLikelihood::getLogLikelihoodForASiteForARateClassForAState(size_t site, size_t rateClass, int state) const
 {
-  return log(rootLikelihoods_[rootPatternLinks_[site]][rateClass][state]);
+  return log(rootLikelihoods_[rootPatternLinks_[site]][rateClass][static_cast<size_t>(state)]);
 }
 
 /******************************************************************************/
@@ -655,8 +655,8 @@ void DistanceEstimation::computeMatrix() throw (NullPointerException)
   vector<string> names = sites_->getSequencesNames();
   if (dist_ != 0) delete dist_;
   dist_ = new DistanceMatrix(names);
-  optimizer_->setVerbose(static_cast<size_t>(max(static_cast<int>(verbose_) - 2, 0)));
-  for (size_t i = 0; i < n; i++)
+  optimizer_->setVerbose(static_cast<unsigned int>(max(static_cast<int>(verbose_) - 2, 0)));
+  for (size_t i = 0; i < n; ++i)
   {
     (*dist_)(i, i) = 0;
     if (verbose_ == 1)
diff --git a/src/Bpp/Phyl/Distance/DistanceEstimation.h b/src/Bpp/Phyl/Distance/DistanceEstimation.h
index 911da5d..3227098 100755
--- a/src/Bpp/Phyl/Distance/DistanceEstimation.h
+++ b/src/Bpp/Phyl/Distance/DistanceEstimation.h
@@ -137,6 +137,14 @@ class TwoTreeLikelihood:
      *
      * @{
      */
+    size_t getNumberOfStates() const { return model_->getNumberOfStates(); } 
+    
+    const std::vector<int>& getAlphabetStates() const { return model_->getAlphabetStates(); } 
+    
+    int getAlphabetStateAsInt(size_t i) const { return model_->getAlphabetStateAsInt(i); }
+  
+    std::string getAlphabetStateAsChar(size_t i) const { return model_->getAlphabetStateAsChar(i); }
+    
     TreeLikelihoodData* getLikelihoodData() throw (NotImplementedException)
     {
       throw NotImplementedException("TwoTreeLikelihood::getLikelihoodData.");
@@ -389,7 +397,7 @@ class DistanceEstimation:
       sites_(distanceEstimation.sites_),
       dist_(0),
       optimizer_(dynamic_cast<Optimizer *>(distanceEstimation.optimizer_->clone())),
-      defaultOptimizer_(dynamic_cast<MetaOptimizer *>(defaultOptimizer_->clone())),
+      defaultOptimizer_(dynamic_cast<MetaOptimizer *>(distanceEstimation.defaultOptimizer_->clone())),
       verbose_(distanceEstimation.verbose_),
       parameters_(distanceEstimation.parameters_)
     {
diff --git a/src/Bpp/Phyl/Distance/DistanceMethod.h b/src/Bpp/Phyl/Distance/DistanceMethod.h
index 099fc90..62cb22d 100755
--- a/src/Bpp/Phyl/Distance/DistanceMethod.h
+++ b/src/Bpp/Phyl/Distance/DistanceMethod.h
@@ -43,6 +43,7 @@ knowledge of the CeCILL license and that you accept its terms.
 
 //From bpp-core:
 #include <Bpp/Clonable.h>
+#include <Bpp/Exceptions.h>
 
 //From the STL:
 #include <string>
@@ -69,8 +70,9 @@ class DistanceMethod:
      * @brief Set the distance matrix to use.
      *
      * @param matrix The matrix to use.
+     * @throw Exception In case an incorrect matrix is provided (eg smaller than 3).
      */
-		virtual void setDistanceMatrix(const DistanceMatrix& matrix) = 0;
+		virtual void setDistanceMatrix(const DistanceMatrix& matrix) throw (Exception) = 0;
 		
     /**
      * @brief Perform the clustering.
diff --git a/src/Bpp/Phyl/Distance/NeighborJoining.h b/src/Bpp/Phyl/Distance/NeighborJoining.h
index 905ef09..5e885db 100755
--- a/src/Bpp/Phyl/Distance/NeighborJoining.h
+++ b/src/Bpp/Phyl/Distance/NeighborJoining.h
@@ -97,7 +97,7 @@ class NeighborJoining :
 	public:
     std::string getName() const { return "NJ"; }
 
-		virtual void setDistanceMatrix(const DistanceMatrix& matrix)
+		virtual void setDistanceMatrix(const DistanceMatrix& matrix) throw (Exception)
 		{ 
 			AbstractAgglomerativeDistanceMethod::setDistanceMatrix(matrix);
 			sumDist_.resize(matrix.size());
diff --git a/src/Bpp/Phyl/Distance/PGMA.h b/src/Bpp/Phyl/Distance/PGMA.h
index e3e71de..e750f55 100644
--- a/src/Bpp/Phyl/Distance/PGMA.h
+++ b/src/Bpp/Phyl/Distance/PGMA.h
@@ -94,7 +94,7 @@ public:
 public:
   std::string getName() const { return std::string(weighted_ ? "W" : "U") + "PGMA"; }
 
-  void setDistanceMatrix(const DistanceMatrix& matrix)
+  void setDistanceMatrix(const DistanceMatrix& matrix) throw (Exception)
   {
     AbstractAgglomerativeDistanceMethod::setDistanceMatrix(matrix);
   }
diff --git a/src/Bpp/Phyl/Graphics/TreeDrawingDisplayControler.h b/src/Bpp/Phyl/Graphics/TreeDrawingDisplayControler.h
index 1124dad..b4861d3 100644
--- a/src/Bpp/Phyl/Graphics/TreeDrawingDisplayControler.h
+++ b/src/Bpp/Phyl/Graphics/TreeDrawingDisplayControler.h
@@ -164,10 +164,10 @@ class BasicTreeDrawingDisplayControler :
     {
       if (!settings)
         throw NullPointerException("BasicTreeDrawingDisplayControler::constructor. Trying to use NULL settings.");
-      addListener(PROPERTY_NODE_IDS        , reinterpret_cast<TreeDrawingListener*>(new NodesIdTreeDrawingListener        (settings_, true)));
-      addListener(PROPERTY_LEAF_NAMES      , reinterpret_cast<TreeDrawingListener*>(new LeafNamesTreeDrawingListener      (settings_, true)));
-      addListener(PROPERTY_BRANCH_LENGTHS  , reinterpret_cast<TreeDrawingListener*>(new BranchLengthsTreeDrawingListener  (settings_, true)));
-      addListener(PROPERTY_BOOTSTRAP_VALUES, reinterpret_cast<TreeDrawingListener*>(new BootstrapValuesTreeDrawingListener(settings_, true)));
+      addListener(PROPERTY_NODE_IDS        , new NodesIdTreeDrawingListener        (settings_, true));
+      addListener(PROPERTY_LEAF_NAMES      , new LeafNamesTreeDrawingListener      (settings_, true));
+      addListener(PROPERTY_BRANCH_LENGTHS  , new BranchLengthsTreeDrawingListener  (settings_, true));
+      addListener(PROPERTY_BOOTSTRAP_VALUES, new BootstrapValuesTreeDrawingListener(settings_, true));
     }
 
   private:
diff --git a/src/Bpp/Phyl/Io/BppOFrequenciesSetFormat.cpp b/src/Bpp/Phyl/Io/BppOFrequenciesSetFormat.cpp
index 9761233..66a99fb 100644
--- a/src/Bpp/Phyl/Io/BppOFrequenciesSetFormat.cpp
+++ b/src/Bpp/Phyl/Io/BppOFrequenciesSetFormat.cpp
@@ -99,18 +99,30 @@ FrequenciesSet* BppOFrequenciesSetFormat::read(const Alphabet* alphabet, const s
     }
     else if (AlphabetTools::isCodonAlphabet(alphabet))
     {
-      if (alphabetCode_ & CODON)
-        pFS.reset(new FixedCodonFrequenciesSet(dynamic_cast<const CodonAlphabet*>(alphabet)));
-      else
+      if (alphabetCode_ & CODON) {
+        if (!geneticCode_)
+          throw Exception("BppOFrequenciesSetFormat::read(). No genetic code specified! Consider using 'setGeneticCode'.");
+        pFS.reset(new FixedCodonFrequenciesSet(geneticCode_));
+      } else {
         throw Exception("Codon alphabet not supported.");
+      }
     }
     else
     {
-      pFS.reset(new FixedFrequenciesSet(alphabet, alphabet->getSize()));
+      pFS.reset(new FixedFrequenciesSet(new CanonicalStateMap(alphabet, false)));
     }
   }
   else if (freqName == "Full")
   {
+    unsigned short method = 1;
+    if (args.find("method") != args.end()){
+      if (args["method"] == "local")
+        method=2;
+      else
+        if (args["method"] == "binary")
+          method=3;
+    }
+      
     if (AlphabetTools::isNucleicAlphabet(alphabet))
     {
       if (alphabetCode_ & NUCLEOTIDE)
@@ -121,20 +133,24 @@ FrequenciesSet* BppOFrequenciesSetFormat::read(const Alphabet* alphabet, const s
     else if (AlphabetTools::isProteicAlphabet(alphabet))
     {
       if (alphabetCode_ & PROTEIN)
-        pFS.reset(new FullProteinFrequenciesSet(dynamic_cast<const ProteicAlphabet*>(alphabet)));
+        pFS.reset(new FullProteinFrequenciesSet(dynamic_cast<const ProteicAlphabet*>(alphabet), false, method));
       else
         throw Exception("Protein alphabet not supported.");
     }
     else if (AlphabetTools::isCodonAlphabet(alphabet))
     {
-      if (alphabetCode_ & CODON)
-        pFS.reset(new FullCodonFrequenciesSet(dynamic_cast<const CodonAlphabet*>(alphabet)));
-      else
+      if (alphabetCode_ & CODON) {
+        if (!geneticCode_)
+          throw Exception("BppOFrequenciesSetFormat::read(). No genetic code specified! Consider using 'setGeneticCode'.");
+        pFS.reset(new FullCodonFrequenciesSet(geneticCode_));
+      } else {
         throw Exception("Codon alphabet not supported.");
+      }
     }
     else
     {
-      pFS.reset(new FullFrequenciesSet(alphabet));
+      //NB: jdutheil 25/09/14 => gap models will not be supported before we add the appropriate option!
+      pFS.reset(new FullFrequenciesSet(new CanonicalStateMap(alphabet, false), false, method));
     }
   }
   else if (freqName == "GC")
@@ -150,7 +166,7 @@ FrequenciesSet* BppOFrequenciesSetFormat::read(const Alphabet* alphabet, const s
   // INDEPENDENTWORD
   else if (freqName == "Word")
   {
-    if (!(alphabetCode_ & WORD))
+    if (!(alphabetCode_& WORD))
       throw Exception("Word alphabet not supported.");
     if (!AlphabetTools::isWordAlphabet(alphabet))
       throw Exception("BppOFrequenciesSetFormat::read(...).\n\t Bad alphabet type "
@@ -169,7 +185,7 @@ FrequenciesSet* BppOFrequenciesSetFormat::read(const Alphabet* alphabet, const s
         st += TextTools::toString(i + 1);
       }
 
-      BppOFrequenciesSetFormat nestedReader(alphabetCode_, false);
+      BppOFrequenciesSetFormat nestedReader(alphabetCode_, false, warningLevel_);
       auto_ptr<FrequenciesSet> pFS2(nestedReader.read(pWA->getNAlphabet(0), sAFS, data, false));
       map<string, string> unparsedParameterValuesNested(nestedReader.getUnparsedArguments());
       for (map<string, string>::iterator it = unparsedParameterValuesNested.begin(); it != unparsedParameterValuesNested.end(); it++)
@@ -194,9 +210,9 @@ FrequenciesSet* BppOFrequenciesSetFormat::read(const Alphabet* alphabet, const s
       if (v_sAFS.size() != pWA->getLength())
         throw Exception("BppOFrequenciesSetFormat::read. Number of frequencies (" + TextTools::toString(v_sAFS.size()) + ") does not match length of the words (" + TextTools::toString(pWA->getLength()) + ")");
 
-      for (unsigned i = 0; i < v_sAFS.size(); i++)
+      for (size_t i = 0; i < v_sAFS.size(); ++i)
       {
-        BppOFrequenciesSetFormat nestedReader(alphabetCode_, false);
+        BppOFrequenciesSetFormat nestedReader(alphabetCode_, false, warningLevel_);
         pFS.reset(nestedReader.read(pWA->getNAlphabet(i), v_sAFS[i], data, false));
         map<string, string> unparsedParameterValuesNested(nestedReader.getUnparsedArguments());
         for (map<string, string>::iterator it = unparsedParameterValuesNested.begin(); it != unparsedParameterValuesNested.end(); it++)
@@ -217,6 +233,8 @@ FrequenciesSet* BppOFrequenciesSetFormat::read(const Alphabet* alphabet, const s
     if (!AlphabetTools::isCodonAlphabet(alphabet))
       throw Exception("BppOFrequenciesSetFormat::read.\n\t Bad alphabet type "
                       + alphabet->getAlphabetType() + " for frequenciesset " + freqName + ".");
+    if (!geneticCode_)
+      throw Exception("BppOFrequenciesSetFormat::read(). No genetic code specified! Consider using 'setGeneticCode'.");
 
     const CodonAlphabet* pWA = dynamic_cast<const CodonAlphabet*>(alphabet);
 
@@ -224,7 +242,7 @@ FrequenciesSet* BppOFrequenciesSetFormat::read(const Alphabet* alphabet, const s
     {
       string sAFS = args["frequency"];
 
-      BppOFrequenciesSetFormat nestedReader(alphabetCode_, false);
+      BppOFrequenciesSetFormat nestedReader(alphabetCode_, false, warningLevel_);
       auto_ptr<FrequenciesSet> pFS2(nestedReader.read(pWA->getNAlphabet(0), sAFS, data, false));
       map<string, string> unparsedParameterValuesNested(nestedReader.getUnparsedArguments());
 
@@ -232,7 +250,8 @@ FrequenciesSet* BppOFrequenciesSetFormat::read(const Alphabet* alphabet, const s
       {
         unparsedArguments_["123_" + it->first] = it->second;
       }
-      pFS.reset(new CodonFromUniqueFrequenciesSet(pWA, pFS2.release(), "Codon"));
+      
+      pFS.reset(new CodonFromUniqueFrequenciesSet(geneticCode_, pFS2.release(), "Codon"));
     }
     else
     {
@@ -250,9 +269,9 @@ FrequenciesSet* BppOFrequenciesSetFormat::read(const Alphabet* alphabet, const s
       if (v_sAFS.size() != 3)
         throw Exception("BppOFrequenciesSetFormat::read. Number of frequencies (" + TextTools::toString(v_sAFS.size()) + ") is not three");
 
-      for (unsigned i = 0; i < v_sAFS.size(); i++)
+      for (size_t i = 0; i < v_sAFS.size(); ++i)
       {
-        BppOFrequenciesSetFormat nestedReader(alphabetCode_, false);
+        BppOFrequenciesSetFormat nestedReader(alphabetCode_, false, warningLevel_);
         pFS.reset(nestedReader.read(pWA->getNAlphabet(i), v_sAFS[i], data, false));
         map<string, string> unparsedParameterValuesNested(nestedReader.getUnparsedArguments());
         for (map<string, string>::iterator it = unparsedParameterValuesNested.begin(); it != unparsedParameterValuesNested.end(); it++)
@@ -262,7 +281,9 @@ FrequenciesSet* BppOFrequenciesSetFormat::read(const Alphabet* alphabet, const s
         v_AFS.push_back(pFS.release());
       }
 
-      pFS.reset(new CodonFromIndependentFrequenciesSet(pWA, v_AFS, "Codon"));
+      if (!geneticCode_)
+        throw Exception("BppOFrequenciesSetFormat::read(). No genetic code specified! Consider using 'setGeneticCode'.");
+      pFS.reset(new CodonFromIndependentFrequenciesSet(geneticCode_, v_AFS, "Codon"));
     }
   }
 
@@ -275,34 +296,35 @@ FrequenciesSet* BppOFrequenciesSetFormat::read(const Alphabet* alphabet, const s
       throw Exception("BppOFrequenciesSetFormat::read.\n\t Bad alphabet type "
                       + alphabet->getAlphabetType() + " for frequenciesset " + freqName + ".");
 
-    const CodonAlphabet* pWA = dynamic_cast<const CodonAlphabet*>(alphabet);
-
-    if (args.find("genetic_code") == args.end())
-      args["genetic_code"] = pWA->getAlphabetType();
-
-    GeneticCode* pgc = SequenceApplicationTools::getGeneticCode(dynamic_cast<const NucleicAlphabet*>(pWA->getNAlphabet(0)), args["genetic_code"]);
-    if (pgc->getSourceAlphabet()->getAlphabetType() != pWA->getAlphabetType())
-      throw Exception("Mismatch between genetic code and codon alphabet");
-
-    const ProteicAlphabet* pPA = dynamic_cast<const ProteicAlphabet*>(pgc->getTargetAlphabet());
+    if (!geneticCode_)
+      throw Exception("BppOFrequenciesSetFormat::read(). No genetic code specified! Consider using 'setGeneticCode'.");
+    
+    const ProteicAlphabet* pPA = dynamic_cast<const ProteicAlphabet*>(geneticCode_->getTargetAlphabet());
 
-    auto_ptr<ProteinFrequenciesSet> pPFS;
+    unsigned short method=1;
+    if (args.find("method") != args.end()){
+      if (args["method"]=="local")
+        method=2;
+      else
+        if (args["method"]=="binary")
+          method=3;
+    }
 
     if (args.find("protein_frequencies") != args.end())
     {
       string sPFS = args["protein_frequencies"];
-      BppOFrequenciesSetFormat nestedReader(alphabetCode_, false);
-      pPFS.reset(dynamic_cast<ProteinFrequenciesSet*>(nestedReader.read(pPA, sPFS, data, false)));
+      BppOFrequenciesSetFormat nestedReader(alphabetCode_, false, warningLevel_);
+      auto_ptr<ProteinFrequenciesSet> pPFS(dynamic_cast<ProteinFrequenciesSet*>(nestedReader.read(pPA, sPFS, data, false)));
       map<string, string> unparsedParameterValuesNested(nestedReader.getUnparsedArguments());
 
       for (map<string, string>::iterator it = unparsedParameterValuesNested.begin(); it != unparsedParameterValuesNested.end(); it++)
       {
         unparsedArguments_["FullPerAA." + it->first] = it->second;
       }
-      pFS.reset(new FullPerAACodonFrequenciesSet(pgc, pPFS.release()));
+      pFS.reset(new FullPerAACodonFrequenciesSet(geneticCode_, pPFS.release(), method));
     }
     else
-      pFS.reset(new FullPerAACodonFrequenciesSet(pgc));
+      pFS.reset(new FullPerAACodonFrequenciesSet(geneticCode_, method));
   }
 
   // codeml frequencies syntax
@@ -311,10 +333,17 @@ FrequenciesSet* BppOFrequenciesSetFormat::read(const Alphabet* alphabet, const s
   {
     if (!(alphabetCode_ & CODON))
       throw Exception("Codon alphabet not supported.");
+    if (!geneticCode_)
+      throw Exception("BppOFrequenciesSetFormat::read(). No genetic code specified! Consider using 'setGeneticCode'.");
+    
     const CodonAlphabet* pWA = dynamic_cast<const CodonAlphabet*>(alphabet);
 
+    if (args.find("genetic_code") != args.end()) {
+      ApplicationTools::displayWarning("'genetic_code' argument is no longer supported inside model description, and has been supersided by a global 'genetic_code' option.");
+      throw Exception("BppOFrequenciesSetFormat::read. Deprecated 'genetic_code' argument.");
+    }
     short opt = -1;
-    string mgmtStopCodon="quadratic";
+    string mgmtStopCodon = "quadratic";
     
     if (freqName == "F0")
     {
@@ -332,7 +361,7 @@ FrequenciesSet* BppOFrequenciesSetFormat::read(const Alphabet* alphabet, const s
         {
           string sAFS = args["frequency"];
 
-          BppOFrequenciesSetFormat nestedReader(alphabetCode_, false);
+          BppOFrequenciesSetFormat nestedReader(alphabetCode_, false, warningLevel_);
           auto_ptr<FrequenciesSet> pFS2(nestedReader.read(pWA->getNAlphabet(0), sAFS, data, false));
           if (pFS2->getName()!="Full")
             throw Exception("BppOFrequenciesSetFormat::read. The frequency option in F1X4 can only be Full");
@@ -350,6 +379,12 @@ FrequenciesSet* BppOFrequenciesSetFormat::read(const Alphabet* alphabet, const s
         unparsedArguments_["123_Full.theta1"] = args["123_theta1"];
       if (args.find("123_theta2") != args.end())
         unparsedArguments_["123_Full.theta2"] = args["123_theta2"];
+      if (args.find("theta") != args.end())
+        unparsedArguments_["123_Full.theta"] = args["123_theta"];
+      if (args.find("theta1") != args.end())
+        unparsedArguments_["123_Full.theta1"] = args["123_theta1"];
+      if (args.find("theta2") != args.end())
+        unparsedArguments_["123_Full.theta2"] = args["123_theta2"];
     }
     else if (freqName == "F3X4")
     {
@@ -374,7 +409,7 @@ FrequenciesSet* BppOFrequenciesSetFormat::read(const Alphabet* alphabet, const s
         
         for (unsigned i = 0; i < v_sAFS.size(); i++)
           {
-            BppOFrequenciesSetFormat nestedReader(alphabetCode_, false);
+            BppOFrequenciesSetFormat nestedReader(alphabetCode_, false, warningLevel_);
             if (v_sAFS[i]!=""){
               pFS.reset(nestedReader.read(pWA->getNAlphabet(i), v_sAFS[i], data, false));
               if (pFS->getName()!="Full")
@@ -402,8 +437,17 @@ FrequenciesSet* BppOFrequenciesSetFormat::read(const Alphabet* alphabet, const s
     {
       opt = CodonFrequenciesSet::F61;
     }
-    if (opt != -1)
-      pFS.reset(CodonFrequenciesSet::getFrequenciesSetForCodons(opt, *dynamic_cast<const CodonAlphabet*>(alphabet), mgmtStopCodon));
+    if (opt != -1){
+      unsigned short method=1;
+      if (args.find("method") != args.end()){
+        if (args["method"]=="local")
+          method=2;
+        else
+          if (args["method"]=="binary")
+            method=3;
+      }      
+      pFS.reset(CodonFrequenciesSet::getFrequenciesSetForCodons(opt, geneticCode_, mgmtStopCodon, method));
+    }
     else
       throw Exception("Unknown frequency option: " + freqName);
   }
@@ -420,7 +464,7 @@ FrequenciesSet* BppOFrequenciesSetFormat::read(const Alphabet* alphabet, const s
   vector<string> pnames = pFS->getParameters().getParameterNames();
 
   string pref = pFS->getNamespace();
-  for (unsigned int i = 0; i < pnames.size(); i++)
+  for (size_t i = 0; i < pnames.size(); i++)
   {
     string name = pFS->getParameterNameWithoutNamespace(pnames[i]);
     if (args.find(name) != args.end())
@@ -459,7 +503,7 @@ void BppOFrequenciesSetFormat::write(const FrequenciesSet* pfreqset,
     return;
   }
   ParameterList pl = pfreqset->getParameters();
-  unsigned int p = out.getPrecision();
+  int p = out.getPrecision();
   out.setPrecision(12);
   bool flag(false);
   string name = pfreqset->getName();
@@ -470,7 +514,7 @@ void BppOFrequenciesSetFormat::write(const FrequenciesSet* pfreqset,
   {
     vector<double> vf = pfreqset->getFrequencies();
     out << "values=(";
-    for (unsigned int i = 0; i < vf.size(); i++)
+    for (size_t i = 0; i < vf.size(); i++)
     {
       if (i != 0)
         out << ", ";
@@ -480,34 +524,46 @@ void BppOFrequenciesSetFormat::write(const FrequenciesSet* pfreqset,
   }
   else
   {
-    if (name != "F1X4" && name != "F3X4" && name != "F61")
+    if (dynamic_cast<const FullProteinFrequenciesSet*>(pfreqset))
+    {
+      size_t meth=dynamic_cast<const FullProteinFrequenciesSet*>(pfreqset)->getMethod();
+      if (meth>1){
+        if (flag)
+          out << ",";
+        out << "method=" << ((meth==2)?"local":"binary");
+        flag=true;
+      }
+    }
+    else
     {
-      const WordFromIndependentFrequenciesSet* pWFI = dynamic_cast<const WordFromIndependentFrequenciesSet*>(pfreqset);
-      if (pWFI != NULL)
+      if (name != "F1X4" && name != "F3X4" && name != "F61")
       {
-        for (unsigned int i = 0; i < pWFI->getLength(); i++)
+        const WordFromIndependentFrequenciesSet* pWFI = dynamic_cast<const WordFromIndependentFrequenciesSet*>(pfreqset);
+        if (pWFI != NULL)
         {
-          if (i != 0)
-            out << ", ";
-          out << "frequency" << i + 1 << "=";
-          write(&pWFI->getFrequenciesSetForLetter(i), out, writtenNames);
+          for (size_t i = 0; i < pWFI->getLength(); i++)
+          {
+            if (i != 0)
+              out << ", ";
+            out << "frequency" << i + 1 << "=";
+            write(&pWFI->getFrequenciesSetForLetter(i), out, writtenNames);
+          }
+          flag = true;
         }
-        flag = true;
-      }
-      const WordFromUniqueFrequenciesSet* pWFU = dynamic_cast<const WordFromUniqueFrequenciesSet*>(pfreqset);
-      if (pWFU != NULL)
-      {
-        for (unsigned int i = 0; i < pWFU->getLength(); i++)
+        const WordFromUniqueFrequenciesSet* pWFU = dynamic_cast<const WordFromUniqueFrequenciesSet*>(pfreqset);
+        if (pWFU != NULL)
         {
-          if (i != 0)
-            out << ", ";
-          out << "frequency=";
-          write(&pWFU->getFrequenciesSetForLetter(i), out, writtenNames);
+          for (size_t i = 0; i < pWFU->getLength(); i++)
+          {
+            if (i != 0)
+              out << ", ";
+            out << "frequency=";
+            write(&pWFU->getFrequenciesSetForLetter(i), out, writtenNames);
+          }
+          flag = true;
         }
-        flag = true;
-      }
-      const FullPerAACodonFrequenciesSet* pFPA=dynamic_cast<const FullPerAACodonFrequenciesSet*>(pfreqset);
-      if (pFPA != NULL)
+        const FullPerAACodonFrequenciesSet* pFPA=dynamic_cast<const FullPerAACodonFrequenciesSet*>(pfreqset);
+        if (pFPA != NULL)
         {
           const ProteinFrequenciesSet* ppfs=pFPA->getProteinFrequenciesSet();
           out << "protein_frequencies=";
@@ -515,22 +571,43 @@ void BppOFrequenciesSetFormat::write(const FrequenciesSet* pfreqset,
           write(ppfs, out, writtenNames);
       
           flag = true;
+              
+          unsigned short meth=pFPA->getMethod();
+          if (meth>1){
+            if (flag)
+              out << ",";
+            out << "method=" << ((meth==2)?"local":"binary");
+            flag=true;
+          }
         }
+      }
     }
 
-    for (unsigned int i = 0; i < pl.size(); i++)
+    
+    for (size_t i = 0; i < pl.size(); i++)
+    {
+      if (find(writtenNames.begin(), writtenNames.end(), pl[i].getName()) == writtenNames.end())
       {
-        if (find(writtenNames.begin(), writtenNames.end(), pl[i].getName()) == writtenNames.end())
-          {
-            if (flag)
-              out << ",";
-            else
-              flag = true;
-            string pname = pfreqset->getParameterNameWithoutNamespace(pl[i].getName());
-            (out << pname << "=").enableScientificNotation(false) << pl[i].getValue();
-            writtenNames.push_back(pl[i].getName());
-          }
+        if (flag)
+          out << ",";
+        else
+          flag = true;
+        string pname = pfreqset->getParameterNameWithoutNamespace(pl[i].getName());
+        (out << pname << "=").enableScientificNotation(false) << pl[i].getValue();
+        writtenNames.push_back(pl[i].getName());
+      }
+    }
+    const FullCodonFrequenciesSet* pF=dynamic_cast<const FullCodonFrequenciesSet*>(pfreqset);
+    if (pF != NULL)
+    {
+      unsigned short meth=pF->getMethod();
+      if (meth>1){
+        if (flag)
+          out << ",";
+        out << "method=" << ((meth==2)?"local":"binary");
+        flag=true;
       }
+    }
   }
   
   out << ")";
@@ -549,12 +626,12 @@ void BppOFrequenciesSetFormat::initialize_(FrequenciesSet& freqSet, const SiteCo
         throw Exception("Missing data for observed frequencies");
       unsigned int psc = 0;
       if (unparsedArguments_.find("observedPseudoCount") != unparsedArguments_.end())
-        psc = TextTools::toInt(unparsedArguments_["observedPseudoCount"]);
+        psc = TextTools::to<unsigned int>(unparsedArguments_["observedPseudoCount"]);
 
       map<int, double> freqs;
       SequenceContainerTools::getFrequencies(*data, freqs, psc);
 
-      freqSet.setFrequenciesFromMap(freqs);
+      freqSet.setFrequenciesFromAlphabetStatesFrequencies(freqs);
     }
     else if (init.substr(0, 6) == "values")
     {
@@ -579,7 +656,7 @@ void BppOFrequenciesSetFormat::initialize_(FrequenciesSet& freqSet, const SiteCo
     // Explicit initialization of each parameter
     ParameterList pl = freqSet.getParameters();
 
-    for (unsigned int i = 0; i < pl.size(); i++)
+    for (size_t i = 0; i < pl.size(); ++i)
     {
       AutoParameter ap(pl[i]);
       if (verbose_)
@@ -587,10 +664,10 @@ void BppOFrequenciesSetFormat::initialize_(FrequenciesSet& freqSet, const SiteCo
       pl.setParameter(i, ap);
     }
 
-    for (unsigned int i = 0; i < pl.size(); i++)
+    for (size_t i = 0; i < pl.size(); ++i)
     {
       const string pName = pl[i].getName();
-      double value = ApplicationTools::getDoubleParameter(pName, unparsedArguments_, pl[i].getValue());
+      double value = ApplicationTools::getDoubleParameter(pName, unparsedArguments_, pl[i].getValue(), "", true, warningLevel_);
 
       pl[i].setValue(value);
       if (verbose_)
diff --git a/src/Bpp/Phyl/Io/BppOFrequenciesSetFormat.h b/src/Bpp/Phyl/Io/BppOFrequenciesSetFormat.h
index e50b435..a86ccfa 100644
--- a/src/Bpp/Phyl/Io/BppOFrequenciesSetFormat.h
+++ b/src/Bpp/Phyl/Io/BppOFrequenciesSetFormat.h
@@ -42,14 +42,16 @@
 
 #include "IoFrequenciesSetFactory.h"
 
+//From bpp-seq:
+#include <Bpp/Seq/GeneticCode/GeneticCode.h>
+
 namespace bpp
 {
 /**
- * @brief Substitution model I/O in BppO format.
+ * @brief Frequencies set I/O in BppO format.
  *
- * Creates a new substitution model object according to model description syntax
+ * Allow to create a new frequencies set object according to model description syntax
  * (see the Bio++ Progam Suite manual for a detailed description of this syntax).
- *
  */
 class BppOFrequenciesSetFormat :
   public virtual IFrequenciesSet,
@@ -68,10 +70,36 @@ private:
   unsigned char alphabetCode_;
   bool verbose_;
   std::map<std::string, std::string> unparsedArguments_;
+  const GeneticCode* geneticCode_;
+  int warningLevel_;
 
 public:
-  BppOFrequenciesSetFormat(unsigned char alphabetCode, bool verbose):
-    alphabetCode_(alphabetCode), verbose_(verbose), unparsedArguments_() {}
+  BppOFrequenciesSetFormat(unsigned char alphabetCode, bool verbose, int warn):
+    alphabetCode_(alphabetCode),
+    verbose_(verbose),
+    unparsedArguments_(),
+    geneticCode_(0),
+    warningLevel_(warn)
+  {}
+
+  BppOFrequenciesSetFormat(const BppOFrequenciesSetFormat& format):
+    alphabetCode_(format.alphabetCode_),
+    verbose_(format.verbose_),
+    unparsedArguments_(format.unparsedArguments_),
+    geneticCode_(format.geneticCode_),
+    warningLevel_(format.warningLevel_)
+  {}
+
+  BppOFrequenciesSetFormat& operator=(const BppOFrequenciesSetFormat& format)
+  {
+    alphabetCode_      = format.alphabetCode_;
+    verbose_           = format.verbose_;
+    unparsedArguments_ = format.unparsedArguments_;
+    geneticCode_       = format.geneticCode_;
+    warningLevel_      = format.warningLevel_;
+    return *this;
+  }
+
   virtual ~BppOFrequenciesSetFormat() {}
 
 public:
@@ -79,16 +107,27 @@ public:
 
   const std::string getFormatDescription() const { return "Bpp Options format."; }
 
-  FrequenciesSet* read(const Alphabet* alphabet,
-                       const std::string& freqDescription,
-                       const SiteContainer* data,
-                       bool parseArguments = true);
+  /**
+   * @brief Set the genetic code to use in case a codon frequencies set should be built.
+   *
+   * @param gCode The genetic code to use.
+   */
+  void setGeneticCode(const GeneticCode* gCode) {
+    geneticCode_ = gCode;
+  }
+
+  FrequenciesSet* read(
+      const Alphabet* alphabet,
+      const std::string& freqDescription,
+      const SiteContainer* data,
+      bool parseArguments = true);
 
   const std::map<std::string, std::string>& getUnparsedArguments() const { return unparsedArguments_; }
 
-  void write(const FrequenciesSet* pfreqset,
-             OutputStream& out,
-             std::vector<std::string>& writtenNames) const;
+  void write(
+      const FrequenciesSet* pfreqset,
+      OutputStream& out,
+      std::vector<std::string>& writtenNames) const;
 
 private:
   void initialize_(FrequenciesSet& freqSet, const SiteContainer* data);
diff --git a/src/Bpp/Phyl/Io/BppOSubstitutionModelFormat.cpp b/src/Bpp/Phyl/Io/BppOSubstitutionModelFormat.cpp
index d524866..37a7e37 100644
--- a/src/Bpp/Phyl/Io/BppOSubstitutionModelFormat.cpp
+++ b/src/Bpp/Phyl/Io/BppOSubstitutionModelFormat.cpp
@@ -92,6 +92,7 @@
 #include "../Model/Protein/LGL08_CAT.h"
 #include "../Model/Protein/WAG01.h"
 #include "../Model/Protein/LLG08_EHO.h"
+#include "../Model/Protein/LG10_EX_EHO.h"
 #include "../Model/BinarySubstitutionModel.h"
 
 #include "../App/PhylogeneticsApplicationTools.h"
@@ -127,10 +128,11 @@ unsigned char BppOSubstitutionModelFormat::BINARY = 32;
 unsigned char BppOSubstitutionModelFormat::ALL = 1 | 2 | 4 | 8 | 16 | 32;
 
 
-SubstitutionModel* BppOSubstitutionModelFormat::read(const Alphabet* alphabet,
-                                                     const std::string& modelDescription,
-                                                     const SiteContainer* data,
-                                                     bool parseArguments)
+SubstitutionModel* BppOSubstitutionModelFormat::read(
+    const Alphabet* alphabet,
+    const std::string& modelDescription,
+    const SiteContainer* data,
+    bool parseArguments)
 {
   unparsedArguments_.clear();
   auto_ptr<SubstitutionModel> model;
@@ -163,20 +165,25 @@ SubstitutionModel* BppOSubstitutionModelFormat::read(const Alphabet* alphabet,
   {
     if (!(alphabetCode_ & CODON))
       throw Exception("BppOSubstitutionModelFormat::read. Codon alphabet not supported.");
+    if (!geneticCode_)
+      throw Exception("BppOSubstitutionModelFormat::read(). No genetic code specified! Consider using 'setGeneticCode'.");
+    
     if (!AlphabetTools::isCodonAlphabet(alphabet))
       throw Exception("Alphabet should be Codon Alphabet.");
 
     const CodonAlphabet* pCA = dynamic_cast<const CodonAlphabet*>(alphabet);
 
-    if (args.find("genetic_code") == args.end())
-      args["genetic_code"] = pCA->getAlphabetType();
+    if (args.find("genetic_code") != args.end()) {
+      ApplicationTools::displayWarning("'genetic_code' argument is no longer supported inside model description, and has been supersided by a global 'genetic_code' option.");
+      throw Exception("BppOSubstitutionModelFormat::read. Deprecated 'genetic_code' argument.");
+    }
 
-    auto_ptr<GeneticCode> pgc(SequenceApplicationTools::getGeneticCode(dynamic_cast<const NucleicAlphabet*>(pCA->getNAlphabet(0)), args["genetic_code"]));
-    if (pgc->getSourceAlphabet()->getAlphabetType() != pCA->getAlphabetType())
+    if (geneticCode_->getSourceAlphabet()->getAlphabetType() != pCA->getAlphabetType())
       throw Exception("Mismatch between genetic code and codon alphabet");
 
-    string freqOpt = ApplicationTools::getStringParameter("frequencies", args, "F0", "", true, verbose_);
-    BppOFrequenciesSetFormat freqReader(BppOFrequenciesSetFormat::ALL, verbose_);
+    string freqOpt = ApplicationTools::getStringParameter("frequencies", args, "F0", "", true, warningLevel_);
+    BppOFrequenciesSetFormat freqReader(BppOFrequenciesSetFormat::ALL, verbose_, warningLevel_);
+    freqReader.setGeneticCode(geneticCode_); //This uses the same instance as the one that will be used by the model.
     auto_ptr<FrequenciesSet> codonFreqs(freqReader.read(pCA, freqOpt, data, false));
     map<string, string> unparsedParameterValuesNested(freqReader.getUnparsedArguments());
 
@@ -186,20 +193,20 @@ SubstitutionModel* BppOSubstitutionModelFormat::read(const Alphabet* alphabet,
     }
 
     if (modelName == "MG94")
-      model.reset(new MG94(pgc.release(), codonFreqs.release()));
+      model.reset(new MG94(geneticCode_, codonFreqs.release()));
     else if (modelName == "GY94")
-      model.reset(new GY94(pgc.release(), codonFreqs.release()));
+      model.reset(new GY94(geneticCode_, codonFreqs.release()));
     else if ((modelName == "YN98") || (modelName == "YNGKP_M0"))
-      model.reset(new YN98(pgc.release(), codonFreqs.release()));
+      model.reset(new YN98(geneticCode_, codonFreqs.release()));
     else if (modelName == "YNGKP_M1")
-      model.reset(new YNGKP_M1(pgc.release(), codonFreqs.release()));
+      model.reset(new YNGKP_M1(geneticCode_, codonFreqs.release()));
     else if (modelName == "YNGKP_M2")
-      model.reset(new YNGKP_M2(pgc.release(), codonFreqs.release()));
+      model.reset(new YNGKP_M2(geneticCode_, codonFreqs.release()));
     else if (modelName == "YNGKP_M3")
       if (args.find("n") == args.end())
-        model.reset(new YNGKP_M3(pgc.release(), codonFreqs.release()));
+        model.reset(new YNGKP_M3(geneticCode_, codonFreqs.release()));
       else
-        model.reset(new YNGKP_M3(pgc.release(), codonFreqs.release(), TextTools::to<unsigned int>(args["n"])));
+        model.reset(new YNGKP_M3(geneticCode_, codonFreqs.release(), TextTools::to<unsigned int>(args["n"])));
     else if ((modelName == "YNGKP_M7") || modelName == "YNGKP_M8")
     {
       if (args.find("n") == args.end())
@@ -209,9 +216,9 @@ SubstitutionModel* BppOSubstitutionModelFormat::read(const Alphabet* alphabet,
         ApplicationTools::displayResult("Number of classes in model", nbClasses);
 
       if (modelName == "YNGKP_M7")
-        model.reset(new YNGKP_M7(pgc.release(), codonFreqs.release(), nbClasses));
+        model.reset(new YNGKP_M7(geneticCode_, codonFreqs.release(), nbClasses));
       else if (modelName == "YNGKP_M8")
-        model.reset(new YNGKP_M8(pgc.release(), codonFreqs.release(), nbClasses));
+        model.reset(new YNGKP_M8(geneticCode_, codonFreqs.release(), nbClasses));
     }
     else
       throw Exception("Unknown Codon model: " + modelName);
@@ -232,7 +239,7 @@ SubstitutionModel* BppOSubstitutionModelFormat::read(const Alphabet* alphabet,
       throw Exception("BppOSubstitutionModelFormat::read. Missing argument 'model' for model 'gBGC'.");
     if (verbose_)
       ApplicationTools::displayResult("Biased gene conversion", modelName);
-    BppOSubstitutionModelFormat nestedReader(NUCLEOTIDE, true, true, false, verbose_);
+    BppOSubstitutionModelFormat nestedReader(NUCLEOTIDE, true, true, false, verbose_, warningLevel_);
     auto_ptr<NucleotideSubstitutionModel> nestedModel(dynamic_cast<NucleotideSubstitutionModel*>(nestedReader.read(alphabet, nestedModelDescription, data, false)));
     map<string, string> unparsedParameterValuesNested(nestedReader.getUnparsedArguments());
 
@@ -263,7 +270,7 @@ SubstitutionModel* BppOSubstitutionModelFormat::read(const Alphabet* alphabet,
       throw Exception("BppOSubstitutionModelFormat::read. Missing argument 'model' for model 'YpR_sym'.");
     if (verbose_)
       ApplicationTools::displayResult("Symetric YpR model", modelName);
-    BppOSubstitutionModelFormat nestedReader(NUCLEOTIDE, false, false, false, verbose_);
+    BppOSubstitutionModelFormat nestedReader(NUCLEOTIDE, false, false, false, verbose_, warningLevel_);
     auto_ptr<NucleotideSubstitutionModel> nestedModel(dynamic_cast<NucleotideSubstitutionModel*>(nestedReader.read(&prny->getLetterAlphabet(), nestedModelDescription, data, false)));
     map<string, string> unparsedParameterValuesNested(nestedReader.getUnparsedArguments());
     for (map<string, string>::iterator it = unparsedParameterValuesNested.begin(); it != unparsedParameterValuesNested.end(); it++)
@@ -286,7 +293,7 @@ SubstitutionModel* BppOSubstitutionModelFormat::read(const Alphabet* alphabet,
       throw Exception("BppOSubstitutionModelFormat::read. Missing argument 'model' for model 'YpR_gen'.");
     if (verbose_)
       ApplicationTools::displayResult("General YpR model", modelName);
-    BppOSubstitutionModelFormat nestedReader(NUCLEOTIDE, false, false, false, verbose_);
+    BppOSubstitutionModelFormat nestedReader(NUCLEOTIDE, false, false, false, verbose_, warningLevel_);
     auto_ptr<NucleotideSubstitutionModel> nestedModel(dynamic_cast<NucleotideSubstitutionModel*>(nestedReader.read(&prny->getLetterAlphabet(), nestedModelDescription, data, false)));
     map<string, string> unparsedParameterValuesNested(nestedReader.getUnparsedArguments());
 
@@ -314,7 +321,7 @@ SubstitutionModel* BppOSubstitutionModelFormat::read(const Alphabet* alphabet,
       throw Exception("BppOSubstitutionModelFormat::read. Missing argument 'model' for model 'RE08'.");
     if (verbose_)
       ApplicationTools::displayResult("Gap model", modelName);
-    BppOSubstitutionModelFormat nestedReader(ALL, allowCovarions_, false, false, verbose_);
+    BppOSubstitutionModelFormat nestedReader(ALL, allowCovarions_, false, false, verbose_, warningLevel_);
     auto_ptr<ReversibleSubstitutionModel> nestedModel(dynamic_cast<ReversibleSubstitutionModel*>(nestedReader.read(alphabet, nestedModelDescription, data, false)));
     map<string, string> unparsedParameterValuesNested(nestedReader.getUnparsedArguments());
 
@@ -343,7 +350,7 @@ SubstitutionModel* BppOSubstitutionModelFormat::read(const Alphabet* alphabet,
       throw Exception("BppOSubstitutionModelFormat::read. Missing argument 'model' for model 'TS98'.");
     if (verbose_)
       ApplicationTools::displayResult("Covarion model", modelName);
-    BppOSubstitutionModelFormat nestedReader(ALL, false, allowMixed_, allowGaps_, false);
+    BppOSubstitutionModelFormat nestedReader(ALL, false, allowMixed_, allowGaps_, false, warningLevel_);
     auto_ptr<ReversibleSubstitutionModel> nestedModel(dynamic_cast<ReversibleSubstitutionModel*>(nestedReader.read(alphabet, nestedModelDescription, data, false)));
     map<string, string> unparsedParameterValuesNested(nestedReader.getUnparsedArguments());
 
@@ -375,7 +382,7 @@ SubstitutionModel* BppOSubstitutionModelFormat::read(const Alphabet* alphabet,
       throw Exception("BppOSubstitutionModelFormat::read. Missing argument 'rdist' for model 'G01'.");
     if (verbose_)
       ApplicationTools::displayResult("Covarion model", modelName);
-    BppOSubstitutionModelFormat nestedReader(ALL, false, allowMixed_, allowGaps_, verbose_);
+    BppOSubstitutionModelFormat nestedReader(ALL, false, allowMixed_, allowGaps_, verbose_, warningLevel_);
     auto_ptr<ReversibleSubstitutionModel> nestedModel(dynamic_cast<ReversibleSubstitutionModel*>(nestedReader.read(alphabet, nestedModelDescription, data, false)));
     map<string, string> unparsedParameterValuesNestedModel(nestedReader.getUnparsedArguments());
     BppORateDistributionFormat rateReader(false);
@@ -515,9 +522,9 @@ SubstitutionModel* BppOSubstitutionModelFormat::read(const Alphabet* alphabet,
         throw Exception("BppOSubstitutionModelFormat::read. Protein alphabet not supported.");
       const ProteicAlphabet* alpha = dynamic_cast<const ProteicAlphabet*>(alphabet);
 
-      if (modelName.find("+F")!=string::npos){
-        string freqOpt = ApplicationTools::getStringParameter("frequencies", args, "Full", "", true, verbose_);
-        BppOFrequenciesSetFormat freqReader(BppOFrequenciesSetFormat::ALL, false);
+      if (modelName.find("+F") != string::npos) {
+        string freqOpt = ApplicationTools::getStringParameter("frequencies", args, "Full", "", true, warningLevel_);
+        BppOFrequenciesSetFormat freqReader(BppOFrequenciesSetFormat::ALL, false, warningLevel_);
         auto_ptr<FrequenciesSet> protFreq(freqReader.read(alpha, freqOpt, data, true));
         map<string, string> unparsedParameterValuesNested(freqReader.getUnparsedArguments());
 
@@ -564,9 +571,11 @@ SubstitutionModel* BppOSubstitutionModelFormat::read(const Alphabet* alphabet,
         model.reset(new LLG08_UL2(alpha));
       else if (modelName == "LLG08_UL3")
         model.reset(new LLG08_UL3(alpha));
+      else if (modelName == "LG10_EX_EHO")
+        model.reset(new LG10_EX_EHO(alpha));	
       else if (modelName == "LGL08_CAT")
       {
-        unsigned int nbCat = TextTools::toInt(args["nbCat"]);
+        unsigned int nbCat = TextTools::to<unsigned int>(args["nbCat"]);
         model.reset(new LGL08_CAT(alpha, nbCat));
       }
       else if (modelName == "Empirical")
@@ -576,19 +585,22 @@ SubstitutionModel* BppOSubstitutionModelFormat::read(const Alphabet* alphabet,
           throw Exception("'name' argument missing for user-defined substitution model.");
         model.reset(new UserProteinSubstitutionModel(alpha, args["file"], prefix));
       }
-      else if (modelName == "COaLA")
+      else if (modelName == "Coala")
       {
+        string exchangeability = args["exch"];
+        if (TextTools::isEmpty(exchangeability))
+          throw Exception("BppOSubstitutionModelFormat::read. missing argument 'exch' for model 'Coala'.");
+        string prefix = args["name"];
+        if (exchangeability == "Empirical" && TextTools::isEmpty(prefix))
+          throw Exception("'name' argument missing to specify the exchangeabilities of the user-defined empirical model.");  
+        BppOSubstitutionModelFormat nestedReader(PROTEIN, false, allowMixed_, allowGaps_, verbose_, warningLevel_);
+        auto_ptr<ProteinSubstitutionModel> nestedModel(dynamic_cast<ProteinSubstitutionModel*>(nestedReader.read(alphabet, exchangeability, data, false)));
         string nbrOfParametersPerBranch = args["nbrAxes"];
         if (TextTools::isEmpty(nbrOfParametersPerBranch))
           throw Exception("'nbrAxes' argument missing to define the number of axis of the Correspondence Analysis.");
-        string exchangeability = args["exch"];
-        if (TextTools::isEmpty(exchangeability))
-          throw Exception("'exch' argument missing to define exchangeability.");
-        string file = args["file"];
-        if (exchangeability == "Empirical" && TextTools::isEmpty(file))
-          throw Exception("'file' argument missing to specify the exchangeabilities of the user-defined empirical model.");
-        model.reset(new Coala(alpha, TextTools::toInt(nbrOfParametersPerBranch), exchangeability, file));
-        dynamic_cast<Coala*>(model.get())->setFreqFromData(*data);
+        //Now we create the Coala model:
+        model.reset(new Coala(alpha, *nestedModel, TextTools::to<unsigned int>(nbrOfParametersPerBranch)));
+        model->setFreqFromData(*data);
       }
 
       else if (AlphabetTools::isBinaryAlphabet(alphabet))
@@ -630,7 +642,7 @@ SubstitutionModel* BppOSubstitutionModelFormat::read(const Alphabet* alphabet,
       continue;
     pval = args[pname];
 
-    if ((pval.length() >= 5 && pval.substr(0, 5) == "model") ||
+    if (((pval.rfind("_") != string::npos) && (TextTools::isDecimalInteger(pval.substr(pval.rfind("_")+1,string::npos)))) ||
         (pval.find("(") != string::npos))
       continue;
     bool found = false;
@@ -651,8 +663,8 @@ SubstitutionModel* BppOSubstitutionModelFormat::read(const Alphabet* alphabet,
         found = true;
       }
     }
-    if (!TextTools::isDecimalNumber(pval) && !found)
-      throw Exception("Incorrect parameter syntax: parameter " + pval + " was not found and can't be used as a value for parameter " + pname + ".");
+    // if (!TextTools::isDecimalNumber(pval) && !found)
+    //   throw Exception("Incorrect parameter syntax: parameter " + pval + " was not found and can't be used as a value for parameter " + pname + ".");
   }
 
   // 2 following tests be removed in a later version
@@ -721,7 +733,7 @@ SubstitutionModel* BppOSubstitutionModelFormat::readWord_(const Alphabet* alphab
 
   if (v_nestedModelDescription.size() != nbmodels)
   {
-    BppOSubstitutionModelFormat nestedReader(alphabetCode_, false, true, false, false);
+    BppOSubstitutionModelFormat nestedReader(alphabetCode_, false, true, false, false, warningLevel_);
     model.reset(nestedReader.read(pWA->getNAlphabet(0), v_nestedModelDescription[0], data, false));
     map<string, string> unparsedParameterValuesNested(nestedReader.getUnparsedArguments());
     string pref = "";
@@ -741,7 +753,7 @@ SubstitutionModel* BppOSubstitutionModelFormat::readWord_(const Alphabet* alphab
   {
     for (unsigned i = 0; i < v_nestedModelDescription.size(); i++)
     {
-      BppOSubstitutionModelFormat nestedReader(alphabetCode_, false, true, false, false);
+      BppOSubstitutionModelFormat nestedReader(alphabetCode_, false, true, false, false, warningLevel_);
       model.reset(nestedReader.read(pWA->getNAlphabet(i), v_nestedModelDescription[i], data, false));
       map<string, string> unparsedParameterValuesNested(nestedReader.getUnparsedArguments());
       for (map<string, string>::iterator it = unparsedParameterValuesNested.begin(); it != unparsedParameterValuesNested.end(); it++)
@@ -772,10 +784,9 @@ SubstitutionModel* BppOSubstitutionModelFormat::readWord_(const Alphabet* alphab
   {
     const CodonAlphabet* pCA = dynamic_cast<const CodonAlphabet*>(pWA);
     if (pCA == 0)
-      throw Exception("Non codon Alphabet fo model" + modelName + " model.");
+      throw Exception("Non codon Alphabet for model" + modelName + ".");
 
     auto_ptr< AlphabetIndex2 > pai2;
-    auto_ptr<GeneticCode> pgc;
     auto_ptr<FrequenciesSet> pFS;
 
     if ((dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[0]) == 0) ||
@@ -783,26 +794,26 @@ SubstitutionModel* BppOSubstitutionModelFormat::readWord_(const Alphabet* alphab
          (dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[1]) == 0 || dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[2]) == 0)))
       throw Exception("Non simple NucleotideSubstitutionModel imbedded in " + modelName + " model.");
 
+    if (args.find("genetic_code") != args.end()) {
+      ApplicationTools::displayWarning("'genetic_code' argument is no longer supported inside model description, and has been supersided by a global 'genetic_code' option.");
+      throw Exception("BppOSubstitutionModelFormat::read. Deprecated 'genetic_code' argument.");
+    }
 
-    if (modelName.find("Dist") != string::npos)
-    {
-      if (args.find("genetic_code") == args.end())
-        args["genetic_code"] = pCA->getAlphabetType();
-
-      pgc.reset(SequenceApplicationTools::getGeneticCode(dynamic_cast<const NucleicAlphabet*>(pCA->getNAlphabet(0)), args["genetic_code"]));
-      if (pgc->getSourceAlphabet()->getAlphabetType() != pCA->getAlphabetType())
-        throw Exception("Mismatch between genetic code and codon alphabet");
+    if (!geneticCode_)
+      throw Exception("BppOSubstitutionModelFormat::readWord_(). No genetic code specified! Consider using 'setGeneticCode'.");
 
+    
+    if (modelName.find("Dist") != string::npos)
       pai2.reset((args.find("aadistance") == args.end()) ? 0 : SequenceApplicationTools::getAlphabetIndex2(&AlphabetTools::PROTEIN_ALPHABET, args["aadistance"]));
-    }
-
+    
 
     if (modelName.find("Freq") != string::npos)
     {
       if (args.find("frequencies") == args.end())
         throw Exception("Missing equilibrium frequencies.");
 
-      BppOFrequenciesSetFormat bIOFreq(alphabetCode_, verbose_);
+      BppOFrequenciesSetFormat bIOFreq(alphabetCode_, verbose_, warningLevel_);
+      bIOFreq.setGeneticCode(geneticCode_); //This uses the same instance as the one that will be used by the model
       pFS.reset(bIOFreq.read(pCA, args["frequencies"], data, false));
       map<string, string> unparsedParameterValuesNested(bIOFreq.getUnparsedArguments());
 
@@ -829,10 +840,10 @@ SubstitutionModel* BppOSubstitutionModelFormat::readWord_(const Alphabet* alphab
     else if (modelName == "CodonRate")
       model.reset((v_nestedModelDescription.size() != 3)
                   ? new CodonRateSubstitutionModel(
-                    pCA,
+                    geneticCode_,
                     dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[0]))
                   : new CodonRateSubstitutionModel(
-                    pCA,
+                    geneticCode_,
                     dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[0]),
                     dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[1]),
                     dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[2])));
@@ -841,10 +852,10 @@ SubstitutionModel* BppOSubstitutionModelFormat::readWord_(const Alphabet* alphab
     else if (modelName == "CodonDist")
     {
       if (v_nestedModelDescription.size() != 3)
-        model.reset(new CodonDistanceSubstitutionModel(pgc.release(), dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[0]), pai2.release()));
+        model.reset(new CodonDistanceSubstitutionModel(geneticCode_, dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[0]), pai2.release()));
       else
         model.reset(new CodonDistanceSubstitutionModel(
-                      pgc.release(),
+                      geneticCode_,
                       dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[0]),
                       dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[1]),
                       dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[2]), pai2.release()));
@@ -853,25 +864,31 @@ SubstitutionModel* BppOSubstitutionModelFormat::readWord_(const Alphabet* alphab
     else if (modelName == "CodonRateFreq")
     {
       if (v_nestedModelDescription.size() != 3)
-        model.reset(new CodonRateFrequenciesSubstitutionModel(pCA, dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[0]), pFS.release()));
+        model.reset(
+            new CodonRateFrequenciesSubstitutionModel(
+              geneticCode_,
+              dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[0]),
+              pFS.release()));
       else
-        model.reset(new CodonRateFrequenciesSubstitutionModel(pCA,
-                                                              dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[0]),
-                                                              dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[1]),
-                                                              dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[2]),
-                                                              pFS.release()));
+        model.reset(
+            new CodonRateFrequenciesSubstitutionModel(
+              geneticCode_,
+              dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[0]),
+              dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[1]),
+              dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[2]),
+              pFS.release()));
     }
 
     else if (modelName == "CodonDistFreq")
     {
       if (v_nestedModelDescription.size() != 3)
-        model.reset(new CodonDistanceFrequenciesSubstitutionModel(pgc.release(),
+        model.reset(new CodonDistanceFrequenciesSubstitutionModel(geneticCode_,
                                                                   dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[0]),
                                                                   pFS.release(),
                                                                   pai2.release()));
       else
         model.reset(new CodonDistanceFrequenciesSubstitutionModel(
-                      pgc.release(),
+                      geneticCode_,
                       dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[0]),
                       dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[1]),
                       dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[2]),
@@ -882,13 +899,13 @@ SubstitutionModel* BppOSubstitutionModelFormat::readWord_(const Alphabet* alphab
     else if (modelName == "CodonDistPhasFreq")
     {
       if (v_nestedModelDescription.size() != 3)
-        model.reset(new CodonDistancePhaseFrequenciesSubstitutionModel(pgc.release(),
+        model.reset(new CodonDistancePhaseFrequenciesSubstitutionModel(geneticCode_,
                                                                        dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[0]),
                                                                        pFS.release(),
                                                                        pai2.release()));
       else
         model.reset(new CodonDistancePhaseFrequenciesSubstitutionModel(
-                      pgc.release(),
+                      geneticCode_,
                       dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[0]),
                       dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[1]),
                       dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[2]),
@@ -900,7 +917,8 @@ SubstitutionModel* BppOSubstitutionModelFormat::readWord_(const Alphabet* alphab
       if (args.find("fitness") == args.end())
         throw Exception("Missing fitness in model " + modelName + ".");
 
-      BppOFrequenciesSetFormat bIOFreq(alphabetCode_, verbose_);
+      BppOFrequenciesSetFormat bIOFreq(alphabetCode_, verbose_, warningLevel_);
+      bIOFreq.setGeneticCode(geneticCode_); 
       auto_ptr<FrequenciesSet> pFit(bIOFreq.read(pCA, args["fitness"], data, false));
       map<string, string> unparsedParameterValuesNested(bIOFreq.getUnparsedArguments());
 
@@ -911,7 +929,7 @@ SubstitutionModel* BppOSubstitutionModelFormat::readWord_(const Alphabet* alphab
 
       if (v_nestedModelDescription.size() != 3)
       {
-        model.reset(new CodonDistanceFitnessPhaseFrequenciesSubstitutionModel(pgc.release(),
+        model.reset(new CodonDistanceFitnessPhaseFrequenciesSubstitutionModel(geneticCode_,
                                                                               dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[0]),
                                                                               pFit.release(),
                                                                               pFS.release(),
@@ -919,7 +937,7 @@ SubstitutionModel* BppOSubstitutionModelFormat::readWord_(const Alphabet* alphab
       }
       else
         model.reset(new CodonDistanceFitnessPhaseFrequenciesSubstitutionModel(
-                      pgc.release(),
+                      geneticCode_,
                       dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[0]),
                       dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[1]),
                       dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[2]),
@@ -946,7 +964,7 @@ MixedSubstitutionModel* BppOSubstitutionModelFormat::readMixed_(const Alphabet*
     if (args.find("model") == args.end())
       throw Exception("The argument 'model' is missing from MixedSubstitutionModel description");
     string nestedModelDescription = args["model"];
-    BppOSubstitutionModelFormat nestedReader(alphabetCode_, allowCovarions_, true, allowGaps_, false);
+    BppOSubstitutionModelFormat nestedReader(alphabetCode_, allowCovarions_, true, allowGaps_, false, warningLevel_);
     pSM.reset(nestedReader.read(alphabet, nestedModelDescription, data, false));
     map<string, string> unparsedParameterValuesNested(nestedReader.getUnparsedArguments());
 
@@ -1028,7 +1046,7 @@ MixedSubstitutionModel* BppOSubstitutionModelFormat::readMixed_(const Alphabet*
 
     for (unsigned i = 0; i < v_nestedModelDescription.size(); i++)
     {
-      BppOSubstitutionModelFormat nestedReader(alphabetCode_, false, true, false, false);
+      BppOSubstitutionModelFormat nestedReader(alphabetCode_, false, true, false, false, warningLevel_);
       pSM.reset(nestedReader.read(alphabet, v_nestedModelDescription[i], data, false));
       map<string, string> unparsedParameterValuesNested(nestedReader.getUnparsedArguments());
       for (map<string, string>::iterator it = unparsedParameterValuesNested.begin(); it != unparsedParameterValuesNested.end(); it++)
@@ -1116,6 +1134,16 @@ void BppOSubstitutionModelFormat::write(const SubstitutionModel& model,
     comma = true;
   }
 
+  // Is it a gBGC model?
+  const gBGC* gbgcModel = dynamic_cast<const gBGC*>(&model);
+  if (gbgcModel)
+  {
+    out << "model=";
+    const SubstitutionModel* nestedModel = gbgcModel->getNestedModel();
+    write(*nestedModel, out, globalAliases, writtenNames);
+    comma = true;
+  }
+
   // Is it a word model?
 
   const AbstractWordSubstitutionModel* wM = dynamic_cast<const AbstractWordSubstitutionModel*>(&model);
@@ -1166,7 +1194,7 @@ void BppOSubstitutionModelFormat::write(const SubstitutionModel& model,
       out << ",";
     out << "frequencies=";
 
-    BppOFrequenciesSetFormat bIOFreq(alphabetCode_, false);
+    BppOFrequenciesSetFormat bIOFreq(alphabetCode_, false, warningLevel_);
     bIOFreq.write(pfs, out, writtenNames);
     comma = true;
   }
@@ -1180,7 +1208,7 @@ void BppOSubstitutionModelFormat::write(const SubstitutionModel& model,
       out << ",";
     out << "fitness=";
 
-    BppOFrequenciesSetFormat bIOFreq(alphabetCode_, false);
+    BppOFrequenciesSetFormat bIOFreq(alphabetCode_, false, warningLevel_);
     bIOFreq.write(pCF->getFitness(), out, writtenNames);
     comma = true;
   }
@@ -1188,6 +1216,7 @@ void BppOSubstitutionModelFormat::write(const SubstitutionModel& model,
   // and the other parameters
 
   BppOParametrizableFormat bIO;
+  
   bIO.write(&model, out, globalAliases, model.getIndependentParameters().getParameterNames(), writtenNames, true, comma);
   out << ")";
 }
@@ -1270,7 +1299,7 @@ void BppOSubstitutionModelFormat::initialize_(
   SubstitutionModel& model,
   const SiteContainer* data) throw (Exception)
 {
-  string initFreqs = ApplicationTools::getStringParameter(model.getNamespace() + "initFreqs", unparsedArguments_, "", "", true, false);
+  string initFreqs = ApplicationTools::getStringParameter(model.getNamespace() + "initFreqs", unparsedArguments_, "", "", true, warningLevel_);
   if (verbose_)
     ApplicationTools::displayResult("External frequencies initialization for model", (initFreqs == "") ? "None" : initFreqs);
 
@@ -1280,7 +1309,7 @@ void BppOSubstitutionModelFormat::initialize_(
     {
       if (!data)
         throw Exception("BppOSubstitutionModelFormat::initialize_(). Missing data for observed frequencies");
-      unsigned int psi = ApplicationTools::getParameter<unsigned int>(model.getNamespace() + "initFreqs.observedPseudoCount", unparsedArguments_, 0);
+      unsigned int psi = ApplicationTools::getParameter<unsigned int>(model.getNamespace() + "initFreqs.observedPseudoCount", unparsedArguments_, 0, "", true, warningLevel_);
       model.setFreqFromData(*data, psi);
     }
     else if (initFreqs.substr(0, 6) == "values")
@@ -1290,7 +1319,7 @@ void BppOSubstitutionModelFormat::initialize_(
 
       string rf = initFreqs.substr(6);
       StringTokenizer strtok(rf.substr(1, rf.length() - 2), ",");
-      unsigned int i = 0;
+      int i = 0;
       while (strtok.hasMoreToken())
         frequencies[i++] = TextTools::toDouble(strtok.nextToken());
       model.setFreq(frequencies);
@@ -1314,16 +1343,25 @@ void BppOSubstitutionModelFormat::initialize_(
     bool test1 = (initFreqs == "");
     bool test2 = (model.getParameterNameWithoutNamespace(pName).size() < posp + 6) || (model.getParameterNameWithoutNamespace(pName).substr(posp + 1, 5) != "theta");
     bool test3 = (unparsedArguments_.find(pName) != unparsedArguments_.end());
-    if (test1 || test2 || test3)
-    {
-      if (!test1 && !test2 && test3)
-        ApplicationTools::displayWarning("Warning, initFreqs argument is set and a value is set for parameter " + pName);
-      double value = ApplicationTools::getDoubleParameter(pName, unparsedArguments_, pl[i].getValue());
-      pl[i].setValue(value);
+    try {
+      if (test1 || test2 || test3)
+      {
+        if (!test1 && !test2 && test3)
+          ApplicationTools::displayWarning("Warning, initFreqs argument is set and a value is set for parameter " + pName);
+
+        double value = ApplicationTools::getDoubleParameter(pName, unparsedArguments_, pl[i].getValue(), "", true, warningLevel_);
+        pl[i].setValue(value);
+        
+        if (unparsedArguments_.find(pName) != unparsedArguments_.end())
+          unparsedArguments_.erase(unparsedArguments_.find(pName));
+      }
+      if (verbose_)
+        ApplicationTools::displayResult("Parameter found", pName + "=" + TextTools::toString(pl[i].getValue()));
     }
-    if (verbose_)
-      ApplicationTools::displayResult("Parameter found", pName + "=" + TextTools::toString(pl[i].getValue()));
+  
+    catch (Exception& e) {}
   }
+  
 
   model.matchParametersValues(pl);
 }
diff --git a/src/Bpp/Phyl/Io/BppOSubstitutionModelFormat.h b/src/Bpp/Phyl/Io/BppOSubstitutionModelFormat.h
index e3d89b7..5910f47 100644
--- a/src/Bpp/Phyl/Io/BppOSubstitutionModelFormat.h
+++ b/src/Bpp/Phyl/Io/BppOSubstitutionModelFormat.h
@@ -43,6 +43,9 @@
 #include "IoSubstitutionModelFactory.h"
 #include "../Model/MixedSubstitutionModel.h"
 
+// From bpp-seq
+#include <Bpp/Seq/GeneticCode/GeneticCode.h>
+
 namespace bpp
 {
 /**
@@ -74,6 +77,8 @@ private:
   bool allowGaps_;
   bool verbose_;
   std::map<std::string, std::string> unparsedArguments_;
+  const GeneticCode* geneticCode_;
+  int warningLevel_;
 
 public:
   /**
@@ -84,16 +89,43 @@ public:
    * @param allowMixed       Tell is a mixture model can be returned.
    * @param allowGaps        Tell is a gap model can be returned.
    * @param verbose          Tell if the construction is verbose.
+   * @param warn             Set the warning level (0: always display warnings, >0 display warnings on demand).
    */
-  BppOSubstitutionModelFormat(unsigned char alphabetCode, bool allowCovarions, bool allowMixed, bool allowGaps, bool verbose):
+  BppOSubstitutionModelFormat(unsigned char alphabetCode, bool allowCovarions, bool allowMixed, bool allowGaps, bool verbose, int warn):
     alphabetCode_(alphabetCode),
     allowCovarions_(allowCovarions),
     allowMixed_(allowMixed),
     allowGaps_(allowGaps),
     verbose_(verbose),
-    unparsedArguments_()
+    unparsedArguments_(),
+    geneticCode_(0),
+    warningLevel_(warn)
+  {}
+
+  BppOSubstitutionModelFormat(const BppOSubstitutionModelFormat& format):
+    alphabetCode_(format.alphabetCode_),
+    allowCovarions_(format.allowCovarions_),
+    allowMixed_(format.allowMixed_),
+    allowGaps_(format.allowGaps_),
+    verbose_(format.verbose_),
+    unparsedArguments_(format.unparsedArguments_),
+    geneticCode_(format.geneticCode_),
+    warningLevel_(format.warningLevel_)
   {}
 
+  BppOSubstitutionModelFormat& operator=(const BppOSubstitutionModelFormat& format)
+  {
+    alphabetCode_      = format.alphabetCode_;
+    allowCovarions_    = format.allowCovarions_;
+    allowMixed_        = format.allowMixed_;
+    allowGaps_         = format.allowGaps_;
+    verbose_           = format.verbose_;
+    unparsedArguments_ = format.unparsedArguments_;
+    geneticCode_       = format.geneticCode_;
+    warningLevel_      = format.warningLevel_;
+    return *this;
+  }
+
   virtual ~BppOSubstitutionModelFormat() {}
 
 public:
@@ -101,6 +133,15 @@ public:
 
   const std::string getFormatDescription() const { return "Bpp Options format."; }
 
+  /**
+   * @brief Set the genetic code to use in case a codon frequencies set should be built.
+   *
+   * @param gCode The genetic code to use.
+   */
+  void setGeneticCode(const GeneticCode* gCode) {
+    geneticCode_ = gCode;
+  }
+
   SubstitutionModel* read(const Alphabet* alphabet, const std::string& modelDescription, const SiteContainer* data = 0, bool parseArguments = true);
 
   const std::map<std::string, std::string>& getUnparsedArguments() const { return unparsedArguments_; }
@@ -121,6 +162,8 @@ public:
              std::map<std::string, std::string>& globalAliases,
              std::vector<std::string>& writtenNames) const;
 
+  void setVerbose(bool verbose) { verbose_=verbose;}
+  
 private:
   MixedSubstitutionModel* readMixed_(const Alphabet* alphabet, const std::string& modelDescription, const SiteContainer* data);
 
diff --git a/src/Bpp/Phyl/Io/IoDistanceMatrixFactory.cpp b/src/Bpp/Phyl/Io/IoDistanceMatrixFactory.cpp
index 12f826f..5456991 100644
--- a/src/Bpp/Phyl/Io/IoDistanceMatrixFactory.cpp
+++ b/src/Bpp/Phyl/Io/IoDistanceMatrixFactory.cpp
@@ -44,15 +44,15 @@ using namespace bpp;
 
 const std::string IODistanceMatrixFactory::PHYLIP_FORMAT = "Phylip"; 
 
-IDistanceMatrix* IODistanceMatrixFactory::createReader(const std::string& format) throw (Exception)
+IDistanceMatrix* IODistanceMatrixFactory::createReader(const std::string& format, bool extended) throw (Exception)
 {
-  if(format == PHYLIP_FORMAT) return new PhylipDistanceMatrixFormat();
+  if(format == PHYLIP_FORMAT) return new PhylipDistanceMatrixFormat(extended);
   else throw Exception("Format " + format + " is not supported for input.");
 }
   
-ODistanceMatrix* IODistanceMatrixFactory::createWriter(const std::string& format) throw (Exception)
+ODistanceMatrix* IODistanceMatrixFactory::createWriter(const std::string& format, bool extended) throw (Exception)
 {
-  if(format == PHYLIP_FORMAT) return new PhylipDistanceMatrixFormat();
+  if(format == PHYLIP_FORMAT) return new PhylipDistanceMatrixFormat(extended);
   else throw Exception("Format " + format + " is not supported for output.");
 }
 
diff --git a/src/Bpp/Phyl/Io/IoDistanceMatrixFactory.h b/src/Bpp/Phyl/Io/IoDistanceMatrixFactory.h
index 978e044..b6f86e6 100644
--- a/src/Bpp/Phyl/Io/IoDistanceMatrixFactory.h
+++ b/src/Bpp/Phyl/Io/IoDistanceMatrixFactory.h
@@ -79,20 +79,24 @@ public:
   /**
    * @brief Get a new dynamically created IDistanceMatrix object.
    *
-   * @param format The input file format.
+   * @param format The input file format, and whether names should be
+   *      only less than 10 characters, or not (false=10 characters max).
+   * @param extended format (default false).
    * @return A pointer toward a new IDistanceMatrix object.
    * @throw Exception If the format name do not match any available format.
    */
-  virtual IDistanceMatrix* createReader(const std::string& format) throw (Exception);
+  virtual IDistanceMatrix* createReader(const std::string& format, bool extended=false) throw (Exception);
   
   /**
    * @brief Get a new dynamically created ODistanceMatrix object.
    *
-   * @param format The output file format.
+   * @param format The output file format, and whether names should be
+   *        only less than 10 characters, or not (false=10 characters max).
+   * @param extended format (default false).
    * @return A pointer toward a new ODistanceMatrix object.
    * @throw Exception If the format name do not match any available format.
    */
-  virtual ODistanceMatrix * createWriter(const std::string& format) throw (Exception);
+  virtual ODistanceMatrix * createWriter(const std::string& format, bool extended=false) throw (Exception);
 };
 
 } //end of namespace bpp.
diff --git a/src/Bpp/Phyl/Io/IoFrequenciesSetFactory.cpp b/src/Bpp/Phyl/Io/IoFrequenciesSetFactory.cpp
index cd95717..7091c3c 100644
--- a/src/Bpp/Phyl/Io/IoFrequenciesSetFactory.cpp
+++ b/src/Bpp/Phyl/Io/IoFrequenciesSetFactory.cpp
@@ -45,13 +45,13 @@ const std::string IOFrequenciesSetFactory::BPPO_FORMAT = "Bpp0";
 
 IFrequenciesSet* IOFrequenciesSetFactory::createReader(const std::string& format) throw (Exception)
 {
-  if(format == BPPO_FORMAT) return new BppOFrequenciesSetFormat(BppOFrequenciesSetFormat::ALL, true);
+  if(format == BPPO_FORMAT) return new BppOFrequenciesSetFormat(BppOFrequenciesSetFormat::ALL, true, 1);
   else throw Exception("Format " + format + " is not supported for input.");
 }
   
 OFrequenciesSet* IOFrequenciesSetFactory::createWriter(const std::string& format) throw (Exception)
 {
-  if(format == BPPO_FORMAT) return new BppOFrequenciesSetFormat(BppOFrequenciesSetFormat::ALL, true);
+  if(format == BPPO_FORMAT) return new BppOFrequenciesSetFormat(BppOFrequenciesSetFormat::ALL, true, 1);
   else throw Exception("Format " + format + " is not supported for output.");
 }
 
diff --git a/src/Bpp/Phyl/Io/IoPairedSiteLikelihoods.cpp b/src/Bpp/Phyl/Io/IoPairedSiteLikelihoods.cpp
index f37c75f..5b41c82 100644
--- a/src/Bpp/Phyl/Io/IoPairedSiteLikelihoods.cpp
+++ b/src/Bpp/Phyl/Io/IoPairedSiteLikelihoods.cpp
@@ -140,7 +140,7 @@ PairedSiteLikelihoods IOTreepuzzlePairedSiteLikelihoods::read(const std::string&
  */
 void IOTreepuzzlePairedSiteLikelihoods::write(const bpp::PairedSiteLikelihoods& psl, ostream& os, const string& delim)
 {
-  if (!psl.getLikelihoods().size() > 0)
+  if (psl.getLikelihoods().size() == 0)
     throw Exception("Writing an empty PairedSiteLikelihoods object to file.");
 
   // Header line
diff --git a/src/Bpp/Phyl/Io/IoSubstitutionModelFactory.cpp b/src/Bpp/Phyl/Io/IoSubstitutionModelFactory.cpp
index babe7aa..13668f0 100644
--- a/src/Bpp/Phyl/Io/IoSubstitutionModelFactory.cpp
+++ b/src/Bpp/Phyl/Io/IoSubstitutionModelFactory.cpp
@@ -5,7 +5,7 @@
 //
 
 /*
-Copyright or © or Copr. CNRS, (November 17, 2004)
+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.
@@ -45,13 +45,13 @@ const std::string IOSubstitutionModelFactory::BPPO_FORMAT = "Bpp0";
 
 ISubstitutionModel* IOSubstitutionModelFactory::createReader(const std::string& format) throw (Exception)
 {
-  if (format == BPPO_FORMAT) return new BppOSubstitutionModelFormat(BppOSubstitutionModelFormat::ALL, true, true, true, true);
+  if (format == BPPO_FORMAT) return new BppOSubstitutionModelFormat(BppOSubstitutionModelFormat::ALL, true, true, true, true, 0);
   else throw Exception("Format " + format + " is not supported for input.");
 }
   
 OSubstitutionModel* IOSubstitutionModelFactory::createWriter(const std::string& format) throw (Exception)
 {
-  if(format == BPPO_FORMAT) return new BppOSubstitutionModelFormat(BppOSubstitutionModelFormat::ALL, true, true, true, true);
+  if(format == BPPO_FORMAT) return new BppOSubstitutionModelFormat(BppOSubstitutionModelFormat::ALL, true, true, true, true, 0);
   else throw Exception("Format " + format + " is not supported for output.");
 }
 
diff --git a/src/Bpp/Phyl/Likelihood/AbstractDiscreteRatesAcrossSitesTreeLikelihood.h b/src/Bpp/Phyl/Likelihood/AbstractDiscreteRatesAcrossSitesTreeLikelihood.h
index 41d471a..5593a50 100755
--- a/src/Bpp/Phyl/Likelihood/AbstractDiscreteRatesAcrossSitesTreeLikelihood.h
+++ b/src/Bpp/Phyl/Likelihood/AbstractDiscreteRatesAcrossSitesTreeLikelihood.h
@@ -54,18 +54,18 @@ namespace bpp
  * This object may be shared by several instances of the class.
  */
 class AbstractDiscreteRatesAcrossSitesTreeLikelihood:
-	public AbstractTreeLikelihood,
-	public virtual DiscreteRatesAcrossSitesTreeLikelihood
+  public AbstractTreeLikelihood,
+  public virtual DiscreteRatesAcrossSitesTreeLikelihood
 {
-	protected:
-		DiscreteDistribution* rateDistribution_;
-		
-	public:
-		AbstractDiscreteRatesAcrossSitesTreeLikelihood(
-			DiscreteDistribution* rDist,
-			bool verbose = true
-		)	throw (Exception);
-		
+  protected:
+    DiscreteDistribution* rateDistribution_;
+    
+  public:
+    AbstractDiscreteRatesAcrossSitesTreeLikelihood(
+      DiscreteDistribution* rDist,
+      bool verbose = true
+    )  throw (Exception);
+    
     AbstractDiscreteRatesAcrossSitesTreeLikelihood(
         const AbstractDiscreteRatesAcrossSitesTreeLikelihood& tl) :
       AbstractTreeLikelihood(tl),
@@ -80,44 +80,44 @@ class AbstractDiscreteRatesAcrossSitesTreeLikelihood:
       return *this;
     }
 
-		virtual ~AbstractDiscreteRatesAcrossSitesTreeLikelihood() {}
-		
-	public:
-		
-		/**
-		 * @name The TreeLikelihood interface.
-		 *
-		 * Other methods are implemented in the AbstractTreeLikelihood class.
-		 *
-		 * @{
-		 */
-		double getLikelihoodForASiteForAState (size_t site, int state) const;
-		double getLogLikelihoodForASiteForAState(size_t site, int state) const;
-		ParameterList getDerivableParameters() const;
-		ParameterList getNonDerivableParameters() const;
+    virtual ~AbstractDiscreteRatesAcrossSitesTreeLikelihood() {}
+    
+  public:
+    
+    /**
+     * @name The TreeLikelihood interface.
+     *
+     * Other methods are implemented in the AbstractTreeLikelihood class.
+     *
+     * @{
+     */
+    double getLikelihoodForASiteForAState (size_t site, int state) const;
+    double getLogLikelihoodForASiteForAState(size_t site, int state) const;
+    ParameterList getDerivableParameters() const;
+    ParameterList getNonDerivableParameters() const;
     VVdouble getTransitionProbabilities(int nodeId, size_t siteIndex) const;
-	 		/** @} */
-
-		/**
-		 * @name The DiscreteRatesAcrossSites interface implementation:
-		 *
-		 * @{
-		 */
-		const DiscreteDistribution* getRateDistribution() const { return rateDistribution_; }
-		      DiscreteDistribution* getRateDistribution()       { return rateDistribution_; }
-		size_t getNumberOfClasses() const { return rateDistribution_->getNumberOfCategories(); } 
-		ParameterList getRateDistributionParameters() const;
-		VVdouble getLikelihoodForEachSiteForEachRateClass() const;
-		VVdouble getLogLikelihoodForEachSiteForEachRateClass() const;
-		VVVdouble getLikelihoodForEachSiteForEachRateClassForEachState() const;
-		VVVdouble getLogLikelihoodForEachSiteForEachRateClassForEachState() const;
-		VVdouble getPosteriorProbabilitiesOfEachRate() const;
-		Vdouble getRateWithMaxPostProbOfEachSite() const;
+    /** @} */
+
+    /**
+     * @name The DiscreteRatesAcrossSites interface implementation:
+     *
+     * @{
+     */
+    const DiscreteDistribution* getRateDistribution() const { return rateDistribution_; }
+          DiscreteDistribution* getRateDistribution()       { return rateDistribution_; }
+    size_t getNumberOfClasses() const { return rateDistribution_->getNumberOfCategories(); } 
+    ParameterList getRateDistributionParameters() const;
+    VVdouble getLikelihoodForEachSiteForEachRateClass() const;
+    VVdouble getLogLikelihoodForEachSiteForEachRateClass() const;
+    VVVdouble getLikelihoodForEachSiteForEachRateClassForEachState() const;
+    VVVdouble getLogLikelihoodForEachSiteForEachRateClassForEachState() const;
+    VVdouble getPosteriorProbabilitiesOfEachRate() const;
+    Vdouble getRateWithMaxPostProbOfEachSite() const;
     std::vector<size_t> getRateClassWithMaxPostProbOfEachSite() const;
-		Vdouble getPosteriorRateOfEachSite() const;
-		/** @} */
+    Vdouble getPosteriorRateOfEachSite() const;
+    /** @} */
 
-		/**
+    /**
      * @name Generic tools to deal with likelihood arrays
      *
      * @{
@@ -135,7 +135,7 @@ class AbstractDiscreteRatesAcrossSitesTreeLikelihood:
      * 
      * @param likelihoodArray the likelihood array.
      */
-		static void displayLikelihoodArray(const VVVdouble & likelihoodArray);
+    static void displayLikelihoodArray(const VVVdouble & likelihoodArray);
 
     /** @} */
     
diff --git a/src/Bpp/Phyl/Likelihood/AbstractHomogeneousTreeLikelihood.cpp b/src/Bpp/Phyl/Likelihood/AbstractHomogeneousTreeLikelihood.cpp
index 849720f..99dcde2 100644
--- a/src/Bpp/Phyl/Likelihood/AbstractHomogeneousTreeLikelihood.cpp
+++ b/src/Bpp/Phyl/Likelihood/AbstractHomogeneousTreeLikelihood.cpp
@@ -43,7 +43,7 @@
 #include <Bpp/Text/TextTools.h>
 #include <Bpp/App/ApplicationTools.h>
 
-// From SeqLib:
+// From bpp-seq:
 #include <Bpp/Seq/SiteTools.h>
 #include <Bpp/Seq/Container/SequenceContainerTools.h>
 
@@ -360,6 +360,7 @@ void AbstractHomogeneousTreeLikelihood::computeTransitionProbabilitiesForNode(co
   {
     VVdouble* pxy__node_c = &(*pxy__node)[c];
     RowMatrix<double> Q = model_->getPij_t(l * rateDistribution_->getCategory(c));
+
     for (unsigned int x = 0; x < nbStates_; x++)
     {
       Vdouble* pxy__node_c_x = &(*pxy__node_c)[x];
@@ -369,7 +370,7 @@ void AbstractHomogeneousTreeLikelihood::computeTransitionProbabilitiesForNode(co
       }
     }
   }
-
+  
   if (computeFirstOrderDerivatives_)
   {
     // Computes all dpxy/dt once for all:
diff --git a/src/Bpp/Phyl/Likelihood/AbstractHomogeneousTreeLikelihood.h b/src/Bpp/Phyl/Likelihood/AbstractHomogeneousTreeLikelihood.h
index 87d156f..2914fad 100755
--- a/src/Bpp/Phyl/Likelihood/AbstractHomogeneousTreeLikelihood.h
+++ b/src/Bpp/Phyl/Likelihood/AbstractHomogeneousTreeLikelihood.h
@@ -84,32 +84,32 @@ class AbstractHomogeneousTreeLikelihood:
     };
 
 
-	protected:
-		SubstitutionModel* model_;
-		ParameterList brLenParameters_;
-		
-		mutable std::map<int, VVVdouble> pxy_;
+  protected:
+    SubstitutionModel* model_;
+    ParameterList brLenParameters_;
+    
+    mutable std::map<int, VVVdouble> pxy_;
 
-		mutable std::map<int, VVVdouble> dpxy_;
+    mutable std::map<int, VVVdouble> dpxy_;
 
-		mutable std::map<int, VVVdouble> d2pxy_;
+    mutable std::map<int, VVVdouble> d2pxy_;
 
     std::vector<double> rootFreqs_;
-				
-		/**
-		 * @brief Pointer toward all nodes in the tree.
+        
+    /**
+     * @brief Pointer toward all nodes in the tree.
      *
      * The position in the array is the number used in the parameter name.
      * This may be different from the node id, unless you used the resetNodeId method on the input tree.
- 		 */
+      */
     std::vector<Node*> nodes_;
 
-		//some values we'll need:
-		size_t nbSites_,         //the number of sites in the container
-                 nbDistinctSites_, //the number of distinct sites
-		             nbClasses_,       //the number of rate classes
-		             nbStates_,        //the number of states in the alphabet
-		             nbNodes_;         //the number of nodes in the tree
+    //some values we'll need:
+    size_t nbSites_,         //the number of sites in the container
+           nbDistinctSites_, //the number of distinct sites
+           nbClasses_,       //the number of rate classes
+           nbStates_,        //the number of states in the alphabet
+           nbNodes_;         //the number of nodes in the tree
 
     bool verbose_;
 
@@ -117,13 +117,13 @@ class AbstractHomogeneousTreeLikelihood:
     double maximumBrLen_;
     std::auto_ptr<Constraint> brLenConstraint_;
 
-	public:
-		AbstractHomogeneousTreeLikelihood(
-			const Tree& tree,
-			SubstitutionModel* model,
-			DiscreteDistribution* rDist,
+  public:
+    AbstractHomogeneousTreeLikelihood(
+      const Tree& tree,
+      SubstitutionModel* model,
+      DiscreteDistribution* rDist,
       bool checkRooted = true,
-			bool verbose = true)
+      bool verbose = true)
       throw (Exception);
 
     /**
@@ -140,34 +140,42 @@ class AbstractHomogeneousTreeLikelihood:
      */
     AbstractHomogeneousTreeLikelihood& operator=(const AbstractHomogeneousTreeLikelihood& lik);
  
-		virtual ~AbstractHomogeneousTreeLikelihood() {}
-		
-	private:
+    virtual ~AbstractHomogeneousTreeLikelihood() {}
+    
+  private:
 
     /**
      * @brief Method called by constructor.
      */
     void init_(const Tree& tree,
-			SubstitutionModel* model,
-			DiscreteDistribution* rDist,
+      SubstitutionModel* model,
+      DiscreteDistribution* rDist,
       bool checkRooted,
-			bool verbose) throw (Exception);
-
-	public:
-		
-		/**
-		 * @name The TreeLikelihood interface.
-		 *
-		 * Other methods are implemented in the AbstractTreeLikelihood class.
-		 *
-		 * @{
-		 */
+      bool verbose) throw (Exception);
+
+  public:
+    
+    /**
+     * @name The TreeLikelihood interface.
+     *
+     * Other methods are implemented in the AbstractTreeLikelihood class.
+     *
+     * @{
+     */
+    size_t getNumberOfStates() const { return model_->getNumberOfStates(); } 
+    
+    const std::vector<int>& getAlphabetStates() const { return model_->getAlphabetStates(); } 
+    
+    int getAlphabetStateAsInt(size_t i) const { return model_->getAlphabetStateAsInt(i); }
+  
+    std::string getAlphabetStateAsChar(size_t i) const { return model_->getAlphabetStateAsChar(i); }
+     
     void initialize() throw(Exception);
-		
+    
     ParameterList getBranchLengthsParameters() const;
-		
+    
     ParameterList getSubstitutionModelParameters() const;
-		
+    
     ParameterList getRateDistributionParameters() const
     {
       return AbstractDiscreteRatesAcrossSitesTreeLikelihood::getRateDistributionParameters();
@@ -189,36 +197,38 @@ class AbstractHomogeneousTreeLikelihood:
    
     /** @} */
 
-		/**
-		 * @name The HomogeneousTreeLikelihood interface.
-		 *
-		 * Other methods are implemented in the AbstractTreeLikelihood class.
-		 *
-		 * @{
-		 */
-		const SubstitutionModel* getSubstitutionModel() const { return model_; }
-		
-		SubstitutionModel* getSubstitutionModel() { return model_; }
-		
+    /**
+     * @name The HomogeneousTreeLikelihood interface.
+     *
+     * Other methods are implemented in the AbstractTreeLikelihood class.
+     *
+     * @{
+     */
+    const SubstitutionModel* getSubstitutionModel() const { return model_; }
+    const SubstitutionModel* getSubstitutionModel(int nodeId, size_t siteIndex) const throw (NodeNotFoundException) { return model_; }
+    
+    SubstitutionModel* getSubstitutionModel() { return model_; }
+    SubstitutionModel* getSubstitutionModel(int nodeId, size_t siteIndex) throw (NodeNotFoundException) { return model_; }
+    
     void setSubstitutionModel(SubstitutionModel* model) throw (Exception);
     /** @} */
-		
-	public: //Specific methods:
-
-		/**
-		 * @brief This builds the <i>parameters</i> list from all parametrizable objects,
-		 * <i>i.e.</i> substitution model, rate distribution and tree.
-		 */
-		virtual void initParameters();
-
-		/**
-		 * @brief All parameters are stored in a parameter list.
-		 * This function apply these parameters to the substitution model,
-		 * to the rate distribution and to the branch lengths.
-		 */
-		virtual void applyParameters() throw (Exception);	
-
-		virtual void initBranchLengthsParameters();
+    
+  public: //Specific methods:
+
+    /**
+     * @brief This builds the <i>parameters</i> list from all parametrizable objects,
+     * <i>i.e.</i> substitution model, rate distribution and tree.
+     */
+    virtual void initParameters();
+
+    /**
+     * @brief All parameters are stored in a parameter list.
+     * This function apply these parameters to the substitution model,
+     * to the rate distribution and to the branch lengths.
+     */
+    virtual void applyParameters() throw (Exception);  
+
+    virtual void initBranchLengthsParameters();
 
     virtual void setMinimumBranchLength(double minimum) throw (Exception)
     {
diff --git a/src/Bpp/Phyl/Likelihood/AbstractNonHomogeneousTreeLikelihood.cpp b/src/Bpp/Phyl/Likelihood/AbstractNonHomogeneousTreeLikelihood.cpp
index a3e72a0..0291f7f 100644
--- a/src/Bpp/Phyl/Likelihood/AbstractNonHomogeneousTreeLikelihood.cpp
+++ b/src/Bpp/Phyl/Likelihood/AbstractNonHomogeneousTreeLikelihood.cpp
@@ -6,34 +6,34 @@
 //
 
 /*
-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
-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.
+  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
+  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 "AbstractNonHomogeneousTreeLikelihood.h"
@@ -56,11 +56,11 @@ using namespace std;
 /******************************************************************************/
 
 AbstractNonHomogeneousTreeLikelihood::AbstractNonHomogeneousTreeLikelihood(
-  const Tree& tree,
-  SubstitutionModelSet* modelSet,
-  DiscreteDistribution* rDist,
-  bool verbose,
-  bool reparametrizeRoot)
+                                                                           const Tree& tree,
+                                                                           SubstitutionModelSet* modelSet,
+                                                                           DiscreteDistribution* rDist,
+                                                                           bool verbose,
+                                                                           bool reparametrizeRoot)
   throw (Exception) :
   AbstractDiscreteRatesAcrossSitesTreeLikelihood(rDist, verbose),
   modelSet_(0),
@@ -90,7 +90,7 @@ AbstractNonHomogeneousTreeLikelihood::AbstractNonHomogeneousTreeLikelihood(
 /******************************************************************************/
 
 AbstractNonHomogeneousTreeLikelihood::AbstractNonHomogeneousTreeLikelihood(
-    const AbstractNonHomogeneousTreeLikelihood& lik) :
+                                                                           const AbstractNonHomogeneousTreeLikelihood& lik) :
   AbstractDiscreteRatesAcrossSitesTreeLikelihood(lik),
   modelSet_(lik.modelSet_),
   brLenParameters_(lik.brLenParameters_),
@@ -100,11 +100,11 @@ AbstractNonHomogeneousTreeLikelihood::AbstractNonHomogeneousTreeLikelihood(
   rootFreqs_(lik.rootFreqs_),
   nodes_(),
   idToNode_(),
-	nbSites_(lik.nbSites_),
+  nbSites_(lik.nbSites_),
   nbDistinctSites_(lik.nbDistinctSites_),
-	nbClasses_(lik.nbClasses_),
-	nbStates_(lik.nbStates_),
-	nbNodes_(lik.nbNodes_),
+  nbClasses_(lik.nbClasses_),
+  nbStates_(lik.nbStates_),
+  nbNodes_(lik.nbNodes_),
   verbose_(lik.verbose_),
   minimumBrLen_(lik.minimumBrLen_),
   maximumBrLen_(lik.maximumBrLen_),
@@ -117,16 +117,16 @@ AbstractNonHomogeneousTreeLikelihood::AbstractNonHomogeneousTreeLikelihood(
   nodes_.pop_back(); //Remove the root node (the last added!).  
   //Rebuild nodes index:
   for (unsigned int i = 0; i < nodes_.size(); i++)
-  {
-    const Node* node = nodes_[i];
-    idToNode_[node->getId()] = node;
-  }
+    {
+      const Node* node = nodes_[i];
+      idToNode_[node->getId()] = node;
+    }
 }
 
 /******************************************************************************/
 
 AbstractNonHomogeneousTreeLikelihood& AbstractNonHomogeneousTreeLikelihood::operator=(
-    const AbstractNonHomogeneousTreeLikelihood& lik)
+                                                                                      const AbstractNonHomogeneousTreeLikelihood& lik)
 {
   AbstractDiscreteRatesAcrossSitesTreeLikelihood::operator=(lik);
   modelSet_          = lik.modelSet_;
@@ -137,11 +137,11 @@ AbstractNonHomogeneousTreeLikelihood& AbstractNonHomogeneousTreeLikelihood::oper
   rootFreqs_         = lik.rootFreqs_;
   nodes_             = tree_->getNodes();
   nodes_.pop_back(); //Remove the root node (the last added!).  
-	nbSites_           = lik.nbSites_;
+  nbSites_           = lik.nbSites_;
   nbDistinctSites_   = lik.nbDistinctSites_;
-	nbClasses_         = lik.nbClasses_;
-	nbStates_          = lik.nbStates_;
-	nbNodes_           = lik.nbNodes_;
+  nbClasses_         = lik.nbClasses_;
+  nbStates_          = lik.nbStates_;
+  nbNodes_           = lik.nbNodes_;
   verbose_           = lik.verbose_;
   minimumBrLen_      = lik.minimumBrLen_;
   maximumBrLen_      = lik.maximumBrLen_;
@@ -152,20 +152,20 @@ AbstractNonHomogeneousTreeLikelihood& AbstractNonHomogeneousTreeLikelihood::oper
   root2_             = lik.root2_;
   //Rebuild nodes index:
   for( unsigned int i = 0; i < nodes_.size(); i++)
-  {
-    const Node * node = nodes_[i];
-    idToNode_[node->getId()] = node;
-  }
+    {
+      const Node * node = nodes_[i];
+      idToNode_[node->getId()] = node;
+    }
   return *this;
 }
 
 /******************************************************************************/
 
 void AbstractNonHomogeneousTreeLikelihood::init_(
-    const Tree& tree,
-			SubstitutionModelSet* modelSet,
-			DiscreteDistribution* rDist,
-			bool verbose) throw (Exception)
+                                                 const Tree& tree,
+                                                 SubstitutionModelSet* modelSet,
+                                                 DiscreteDistribution* rDist,
+                                                 bool verbose) throw (Exception)
 {
   TreeTools::checkIds(tree, true);
   tree_ = new TreeTemplate<Node>(tree);
@@ -176,10 +176,10 @@ void AbstractNonHomogeneousTreeLikelihood::init_(
   nbNodes_ = nodes_.size();
   //Build nodes index:
   for (unsigned int i = 0; i < nodes_.size(); i++)
-  {
-    const Node * node = nodes_[i];
-    idToNode_[node->getId()] = node;
-  }
+    {
+      const Node * node = nodes_[i];
+      idToNode_[node->getId()] = node;
+    }
   nbClasses_ = rateDistribution_->getNumberOfCategories();
 
   verbose_ = verbose;
@@ -196,71 +196,71 @@ void AbstractNonHomogeneousTreeLikelihood::setSubstitutionModelSet(SubstitutionM
 {
   //Check:
   if (data_)
-  {
-    if (modelSet->getAlphabet()->getAlphabetType() != data_->getAlphabet()->getAlphabetType())
-      throw Exception("AbstractBranchNonHomogeneousTreeLikelihood::setSubstitutionModelSet(). Model alphabet do not match existing data.");
-  }
+    {
+      if (modelSet->getAlphabet()->getAlphabetType() != data_->getAlphabet()->getAlphabetType())
+        throw Exception("AbstractBranchNonHomogeneousTreeLikelihood::setSubstitutionModelSet(). Model alphabet do not match existing data.");
+    }
 
   modelSet_ = modelSet;
   
   if (data_)
-  {
-    if (modelSet->getNumberOfStates() != modelSet_->getNumberOfStates())
-      setData(*data_); //Have to reinitialize the whole data structure.
-  }
+    {
+      if (modelSet->getNumberOfStates() != modelSet_->getNumberOfStates())
+        setData(*data_); //Have to reinitialize the whole data structure.
+    }
   
   nbStates_ = modelSet->getNumberOfStates();
 
   //Allocate transition probabilities arrays:
   for (unsigned int l = 0; l < nbNodes_; l++)
-  {
-    //For each son node,i
-    Node* son = nodes_[l];
-
-    VVVdouble* pxy__son = & pxy_[son->getId()];
-    pxy__son->resize(nbClasses_);
-    for (unsigned int c = 0; c < nbClasses_; c++)
     {
-      VVdouble * pxy__son_c = & (* pxy__son)[c];
-      pxy__son_c->resize(nbStates_);
-      for(unsigned int x = 0; x < nbStates_; x++)
-      {
-        (*pxy__son_c)[x].resize(nbStates_);
-      }
-    }
+      //For each son node,i
+      Node* son = nodes_[l];
+
+      VVVdouble* pxy__son = & pxy_[son->getId()];
+      pxy__son->resize(nbClasses_);
+      for (unsigned int c = 0; c < nbClasses_; c++)
+        {
+          VVdouble * pxy__son_c = & (* pxy__son)[c];
+          pxy__son_c->resize(nbStates_);
+          for(unsigned int x = 0; x < nbStates_; x++)
+            {
+              (*pxy__son_c)[x].resize(nbStates_);
+            }
+        }
   
-    VVVdouble* dpxy__son = & dpxy_[son->getId()];
-    dpxy__son->resize(nbClasses_);
-    for (unsigned int c = 0; c < nbClasses_; c++)
-    {
-      VVdouble * dpxy__son_c = & (* dpxy__son)[c];
-      dpxy__son_c->resize(nbStates_);
-      for(unsigned int x = 0; x < nbStates_; x++)
-      {
-        (* dpxy__son_c)[x].resize(nbStates_);
-      }
-    }
+      VVVdouble* dpxy__son = & dpxy_[son->getId()];
+      dpxy__son->resize(nbClasses_);
+      for (unsigned int c = 0; c < nbClasses_; c++)
+        {
+          VVdouble * dpxy__son_c = & (* dpxy__son)[c];
+          dpxy__son_c->resize(nbStates_);
+          for(unsigned int x = 0; x < nbStates_; x++)
+            {
+              (* dpxy__son_c)[x].resize(nbStates_);
+            }
+        }
       
-    VVVdouble* d2pxy__son = & d2pxy_[son->getId()];
-    d2pxy__son->resize(nbClasses_);
-    for (unsigned int c = 0; c < nbClasses_; c++)
-    {
-      VVdouble * d2pxy__son_c = & (* d2pxy__son)[c];
-      d2pxy__son_c->resize(nbStates_);
-      for(unsigned int x = 0; x < nbStates_; x++)
-      {
-        (* d2pxy__son_c)[x].resize(nbStates_);
-      }
+      VVVdouble* d2pxy__son = & d2pxy_[son->getId()];
+      d2pxy__son->resize(nbClasses_);
+      for (unsigned int c = 0; c < nbClasses_; c++)
+        {
+          VVdouble * d2pxy__son_c = & (* d2pxy__son)[c];
+          d2pxy__son_c->resize(nbStates_);
+          for(unsigned int x = 0; x < nbStates_; x++)
+            {
+              (* d2pxy__son_c)[x].resize(nbStates_);
+            }
+        }
     }
-  }
 
   //We have to reset parameters. If the instance is not initialized, this will be done by the initialize method.
   if (initialized_) 
-  {
-    initParameters();
-    computeAllTransitionProbabilities();
-    fireParameterChanged(getParameters());
-  }
+    {
+      initParameters();
+      computeAllTransitionProbabilities();
+      fireParameterChanged(getParameters());
+    }
 }
 
 /******************************************************************************/
@@ -316,27 +316,28 @@ void AbstractNonHomogeneousTreeLikelihood::applyParameters() throw (Exception)
   if (!initialized_) throw Exception("AbstractBranchNonHomogeneousTreeLikelihood::applyParameters(). Object not initialized.");
   //Apply branch lengths:
   for (unsigned int i = 0; i < nbNodes_; i++)
-  {
-    int id = nodes_[i]->getId();
-    if (reparametrizeRoot_ && id == root1_)
-    {
-      const Parameter* rootBrLen = &getParameter("BrLenRoot");
-      const Parameter* rootPos = &getParameter("RootPosition");
-      nodes_[i]->setDistanceToFather(rootBrLen->getValue() * rootPos->getValue());
-    }
-    else if (reparametrizeRoot_ && id == root2_)
     {
-      const Parameter* rootBrLen = &getParameter("BrLenRoot");
-      const Parameter* rootPos = &getParameter("RootPosition");
-      nodes_[i]->setDistanceToFather(rootBrLen->getValue() * (1. - rootPos->getValue()));
-    }
-    else
-    {
-      const Parameter* brLen = &getParameter(string("BrLen") + TextTools::toString(i));
-      if (brLen) nodes_[i]->setDistanceToFather(brLen->getValue());
+      int id = nodes_[i]->getId();
+      if (reparametrizeRoot_ && id == root1_)
+        {
+          const Parameter* rootBrLen = &getParameter("BrLenRoot");
+          const Parameter* rootPos = &getParameter("RootPosition");
+          nodes_[i]->setDistanceToFather(rootBrLen->getValue() * rootPos->getValue());
+        }
+      else if (reparametrizeRoot_ && id == root2_)
+        {
+          const Parameter* rootBrLen = &getParameter("BrLenRoot");
+          const Parameter* rootPos = &getParameter("RootPosition");
+          nodes_[i]->setDistanceToFather(rootBrLen->getValue() * (1. - rootPos->getValue()));
+        }
+      else
+        {
+          const Parameter* brLen = &getParameter(string("BrLen") + TextTools::toString(i));
+          if (brLen) nodes_[i]->setDistanceToFather(brLen->getValue());
+        }
     }
-  }
   //Apply substitution model parameters:
+
   modelSet_->matchParametersValues(getParameters());
   //Apply rate distribution parameters:
   rateDistribution_->matchParametersValues(getParameters());
@@ -349,38 +350,38 @@ void AbstractNonHomogeneousTreeLikelihood::initBranchLengthsParameters()
   brLenParameters_.reset();
   double l1 = 0, l2 = 0;
   for (unsigned int i = 0; i < nbNodes_; i++)
-  {
-    double d = minimumBrLen_;
-    if (!nodes_[i]->hasDistanceToFather())
-    {
-      ApplicationTools::displayWarning("Missing branch length " + TextTools::toString(i) + ". Value is set to " + TextTools::toString(minimumBrLen_));
-      nodes_[i]->setDistanceToFather(minimumBrLen_);
-    }
-    else
-    {
-      d = nodes_[i]->getDistanceToFather();
-      if (d < minimumBrLen_)
-      {
-        ApplicationTools::displayWarning("Branch length " + TextTools::toString(i) + " is too small: " + TextTools::toString(d) + ". Value is set to " + TextTools::toString(minimumBrLen_));
-        nodes_[i]->setDistanceToFather(minimumBrLen_);
-        d = minimumBrLen_;
-      }
-      if (d > maximumBrLen_)
-      {
-        ApplicationTools::displayWarning("Branch length " + TextTools::toString(i) + " is too big: " + TextTools::toString(d) + ". Value is set to " + TextTools::toString(maximumBrLen_));
-        nodes_[i]->setDistanceToFather(maximumBrLen_);
-        d = maximumBrLen_;
-      }
-    }
-    if (reparametrizeRoot_ && nodes_[i]->getId() == root1_)
-      l1 = d;
-    else if (reparametrizeRoot_ && nodes_[i]->getId() == root2_)
-      l2 = d;
-    else
     {
-      brLenParameters_.addParameter(Parameter("BrLen" + TextTools::toString(i), d, brLenConstraint_->clone(), true)); //Attach constraint to avoid clonage problems!
+      double d = minimumBrLen_;
+      if (!nodes_[i]->hasDistanceToFather())
+        {
+          ApplicationTools::displayWarning("Missing branch length " + TextTools::toString(i) + ". Value is set to " + TextTools::toString(minimumBrLen_));
+          nodes_[i]->setDistanceToFather(minimumBrLen_);
+        }
+      else
+        {
+          d = nodes_[i]->getDistanceToFather();
+          if (d < minimumBrLen_)
+            {
+              ApplicationTools::displayWarning("Branch length " + TextTools::toString(i) + " is too small: " + TextTools::toString(d) + ". Value is set to " + TextTools::toString(minimumBrLen_));
+              nodes_[i]->setDistanceToFather(minimumBrLen_);
+              d = minimumBrLen_;
+            }
+          if (d > maximumBrLen_)
+            {
+              ApplicationTools::displayWarning("Branch length " + TextTools::toString(i) + " is too big: " + TextTools::toString(d) + ". Value is set to " + TextTools::toString(maximumBrLen_));
+              nodes_[i]->setDistanceToFather(maximumBrLen_);
+              d = maximumBrLen_;
+            }
+        }
+      if (reparametrizeRoot_ && nodes_[i]->getId() == root1_)
+        l1 = d;
+      else if (reparametrizeRoot_ && nodes_[i]->getId() == root2_)
+        l2 = d;
+      else
+        {
+          brLenParameters_.addParameter(Parameter("BrLen" + TextTools::toString(i), d, brLenConstraint_->clone(), true)); //Attach constraint to avoid clonage problems!
+        }
     }
-  }
   if (reparametrizeRoot_) {
     brLenParameters_.addParameter(Parameter("BrLenRoot", l1 + l2, brLenConstraint_->clone(), true));
     brLenParameters_.addParameter(Parameter("RootPosition", l1 / (l1 + l2), &Parameter::PROP_CONSTRAINT_EX));
@@ -392,11 +393,11 @@ void AbstractNonHomogeneousTreeLikelihood::initBranchLengthsParameters()
 void AbstractNonHomogeneousTreeLikelihood::computeAllTransitionProbabilities()
 {
   for(unsigned int l = 0; l < nbNodes_; l++)
-  {
-    //For each node,
-    Node * node = nodes_[l];
-    computeTransitionProbabilitiesForNode(node);
-  }
+    {
+      //For each node,
+      Node * node = nodes_[l];
+      computeTransitionProbabilitiesForNode(node);
+    }
   rootFreqs_ = modelSet_->getRootFrequencies();
 }
 
@@ -410,59 +411,59 @@ void AbstractNonHomogeneousTreeLikelihood::computeTransitionProbabilitiesForNode
   //Computes all pxy and pyx once for all:
   VVVdouble * pxy__node = & pxy_[node->getId()];
   for(unsigned int c = 0; c < nbClasses_; c++)
-  {
-    VVdouble * pxy__node_c = & (* pxy__node)[c];
-    RowMatrix<double> Q = model->getPij_t(l * rateDistribution_->getCategory(c));
-    for(unsigned int x = 0; x < nbStates_; x++)
     {
-      Vdouble * pxy__node_c_x = & (* pxy__node_c)[x];
-      for(unsigned int y = 0; y < nbStates_; y++)
-      {
-        (* pxy__node_c_x)[y] = Q(x, y);
-      }
+      VVdouble * pxy__node_c = & (* pxy__node)[c];
+      RowMatrix<double> Q = model->getPij_t(l * rateDistribution_->getCategory(c));
+      for(unsigned int x = 0; x < nbStates_; x++)
+        {
+          Vdouble * pxy__node_c_x = & (* pxy__node_c)[x];
+          for(unsigned int y = 0; y < nbStates_; y++)
+            {
+              (* pxy__node_c_x)[y] = Q(x, y);
+            }
+        }
     }
-  }
   
   if(computeFirstOrderDerivatives_)
-  {
-    //Computes all dpxy/dt once for all:
-    VVVdouble * dpxy__node = & dpxy_[node->getId()];
-
-    for(unsigned int c = 0; c < nbClasses_; c++)
     {
-      VVdouble * dpxy__node_c = & (* dpxy__node)[c];
-      double rc = rateDistribution_->getCategory(c);
+      //Computes all dpxy/dt once for all:
+      VVVdouble * dpxy__node = & dpxy_[node->getId()];
 
-      RowMatrix<double> dQ = model->getdPij_dt(l * rc);  
+      for(unsigned int c = 0; c < nbClasses_; c++)
+        {
+          VVdouble * dpxy__node_c = & (* dpxy__node)[c];
+          double rc = rateDistribution_->getCategory(c);
 
-      for(unsigned int x = 0; x < nbStates_; x++)
-      {
-        Vdouble * dpxy__node_c_x = & (* dpxy__node_c)[x];
-        for(unsigned int y = 0; y < nbStates_; y++)
-          (* dpxy__node_c_x)[y] = rc * dQ(x, y); 
-      }
+          RowMatrix<double> dQ = model->getdPij_dt(l * rc);  
+
+          for(unsigned int x = 0; x < nbStates_; x++)
+            {
+              Vdouble * dpxy__node_c_x = & (* dpxy__node_c)[x];
+              for(unsigned int y = 0; y < nbStates_; y++)
+                (* dpxy__node_c_x)[y] = rc * dQ(x, y); 
+            }
+        }
     }
-  }
       
   if(computeSecondOrderDerivatives_)
-  {
-    //Computes all d2pxy/dt2 once for all:
-    VVVdouble * d2pxy__node = & d2pxy_[node->getId()];
-    for(unsigned int c = 0; c < nbClasses_; c++)
     {
-      VVdouble * d2pxy__node_c = & (* d2pxy__node)[c];
-      double rc =  rateDistribution_->getCategory(c);
-      RowMatrix<double> d2Q = model->getd2Pij_dt2(l * rc);
-      for(unsigned int x = 0; x < nbStates_; x++)
-      {
-        Vdouble * d2pxy__node_c_x = & (* d2pxy__node_c)[x];
-        for(unsigned int y = 0; y < nbStates_; y++)
+      //Computes all d2pxy/dt2 once for all:
+      VVVdouble * d2pxy__node = & d2pxy_[node->getId()];
+      for(unsigned int c = 0; c < nbClasses_; c++)
         {
-          (* d2pxy__node_c_x)[y] = rc * rc * d2Q(x, y);
+          VVdouble * d2pxy__node_c = & (* d2pxy__node)[c];
+          double rc =  rateDistribution_->getCategory(c);
+          RowMatrix<double> d2Q = model->getd2Pij_dt2(l * rc);
+          for(unsigned int x = 0; x < nbStates_; x++)
+            {
+              Vdouble * d2pxy__node_c_x = & (* d2pxy__node_c)[x];
+              for(unsigned int y = 0; y < nbStates_; y++)
+                {
+                  (* d2pxy__node_c_x)[y] = rc * rc * d2Q(x, y);
+                }
+            }
         }
-      }
     }
-  }
 }
 
 /*******************************************************************************/
diff --git a/src/Bpp/Phyl/Likelihood/AbstractNonHomogeneousTreeLikelihood.h b/src/Bpp/Phyl/Likelihood/AbstractNonHomogeneousTreeLikelihood.h
index c233f1a..b17fada 100644
--- a/src/Bpp/Phyl/Likelihood/AbstractNonHomogeneousTreeLikelihood.h
+++ b/src/Bpp/Phyl/Likelihood/AbstractNonHomogeneousTreeLikelihood.h
@@ -115,10 +115,10 @@ class AbstractNonHomogeneousTreeLikelihood:
  
     //some values we'll need:
     size_t nbSites_,         //the number of sites in the container
-                 nbDistinctSites_, //the number of distinct sites
-                 nbClasses_,       //the number of rate classes
-                 nbStates_,        //the number of states in the alphabet
-                 nbNodes_;         //the number of nodes in the tree
+           nbDistinctSites_, //the number of distinct sites
+           nbClasses_,       //the number of rate classes
+           nbStates_,        //the number of states in the alphabet
+           nbNodes_;         //the number of nodes in the tree
 
     bool verbose_;
 
@@ -174,6 +174,14 @@ class AbstractNonHomogeneousTreeLikelihood:
      *
      * @{
      */
+    size_t getNumberOfStates() const { return modelSet_->getNumberOfStates(); } 
+    
+    const std::vector<int>& getAlphabetStates() const { return modelSet_->getAlphabetStates(); } 
+    
+    int getAlphabetStateAsInt(size_t i) const { return modelSet_->getAlphabetStateAsInt(i); }
+  
+    std::string getAlphabetStateAsChar(size_t i) const { return modelSet_->getAlphabetStateAsChar(i); }
+     
     void initialize() throw(Exception);
     
     ParameterList getBranchLengthsParameters() const;
diff --git a/src/Bpp/Phyl/Likelihood/AbstractTreeLikelihood.h b/src/Bpp/Phyl/Likelihood/AbstractTreeLikelihood.h
index 902f640..528cc78 100755
--- a/src/Bpp/Phyl/Likelihood/AbstractTreeLikelihood.h
+++ b/src/Bpp/Phyl/Likelihood/AbstractTreeLikelihood.h
@@ -67,8 +67,8 @@ namespace bpp
  * It also adds an abstract method for recursive computations.
  */
 class AbstractTreeLikelihood :
-	public virtual TreeLikelihood,
-	public AbstractParametrizable
+  public virtual TreeLikelihood,
+  public AbstractParametrizable
 {
   public:
     /**
@@ -221,15 +221,15 @@ class AbstractTreeLikelihood :
 
 
 
-	protected:
-		const SiteContainer* data_;
-		mutable TreeTemplate<Node>* tree_;
-		bool computeFirstOrderDerivatives_;
-		bool computeSecondOrderDerivatives_;
+  protected:
+    const SiteContainer* data_;
+    mutable TreeTemplate<Node>* tree_;
+    bool computeFirstOrderDerivatives_;
+    bool computeSecondOrderDerivatives_;
     bool initialized_;
 
-	public:
-		AbstractTreeLikelihood():
+  public:
+    AbstractTreeLikelihood():
       AbstractParametrizable(""),
       data_(0),
       tree_(0),
@@ -269,50 +269,49 @@ class AbstractTreeLikelihood :
      *
      * This destructor is empty.
      */
-		virtual ~AbstractTreeLikelihood()
+    virtual ~AbstractTreeLikelihood()
     {
       if (data_) delete data_;
       if (tree_) delete tree_;
     }
-	
-	public:
-		/**
-		 * @name The TreeLikelihood interface.
-		 *
-		 * @{
-		 */
-		const SiteContainer* getData() const { return data_; }
-		const Alphabet* getAlphabet() const { return data_->getAlphabet(); }	
-		Vdouble getLikelihoodForEachSite()                 const;
-		Vdouble getLogLikelihoodForEachSite()              const;
-		VVdouble getLikelihoodForEachSiteForEachState()    const;
-		VVdouble getLogLikelihoodForEachSiteForEachState() const;
-		size_t getNumberOfSites() const { return data_->getNumberOfSites(); }
-		size_t getNumberOfStates() const { return data_->getAlphabet()->getSize(); }
-		const Tree& getTree() const { return *tree_; }
-		void enableDerivatives(bool yn) { computeFirstOrderDerivatives_ = computeSecondOrderDerivatives_ = yn; }
-		void enableFirstOrderDerivatives(bool yn) { computeFirstOrderDerivatives_ = yn; }
-		void enableSecondOrderDerivatives(bool yn) { computeFirstOrderDerivatives_ = computeSecondOrderDerivatives_ = yn; }
-		bool enableFirstOrderDerivatives() const { return computeFirstOrderDerivatives_; }
-		bool enableSecondOrderDerivatives() const { return computeSecondOrderDerivatives_; }
+  
+  public:
+    /**
+     * @name The TreeLikelihood interface.
+     *
+     * @{
+     */
+    const SiteContainer* getData() const { return data_; }
+    const Alphabet* getAlphabet() const { return data_->getAlphabet(); }  
+    Vdouble getLikelihoodForEachSite()                 const;
+    Vdouble getLogLikelihoodForEachSite()              const;
+    VVdouble getLikelihoodForEachSiteForEachState()    const;
+    VVdouble getLogLikelihoodForEachSiteForEachState() const;
+    size_t getNumberOfSites() const { return data_->getNumberOfSites(); }
+    const Tree& getTree() const { return *tree_; }
+    void enableDerivatives(bool yn) { computeFirstOrderDerivatives_ = computeSecondOrderDerivatives_ = yn; }
+    void enableFirstOrderDerivatives(bool yn) { computeFirstOrderDerivatives_ = yn; }
+    void enableSecondOrderDerivatives(bool yn) { computeFirstOrderDerivatives_ = computeSecondOrderDerivatives_ = yn; }
+    bool enableFirstOrderDerivatives() const { return computeFirstOrderDerivatives_; }
+    bool enableSecondOrderDerivatives() const { return computeSecondOrderDerivatives_; }
     bool isInitialized() const { return initialized_; }
     void initialize() throw (Exception) { initialized_ = true; }
-		/** @} */
-
-//	protected:
-//		
-//		/**
-//		 * @brief Recompute pxy_, dpxy_ and d2pxy_ arrays, and derivatives if needed.
-//		 *
-//		 * This method is called when some parameter has changed.
-//		 *
-//		 * @param params The parameters that changed.
-//		 */
-//		virtual void fireParameterChanged(const ParameterList & params) = 0;
-		
+    /** @} */
+
+//  protected:
+//    
+//    /**
+//     * @brief Recompute pxy_, dpxy_ and d2pxy_ arrays, and derivatives if needed.
+//     *
+//     * This method is called when some parameter has changed.
+//     *
+//     * @param params The parameters that changed.
+//     */
+//    virtual void fireParameterChanged(const ParameterList & params) = 0;
+    
 };
 
 } //end of namespace bpp.
 
-#endif	//_ABSTRACTTREELIKELIHOOD_H_
+#endif  //_ABSTRACTTREELIKELIHOOD_H_
 
diff --git a/src/Bpp/Phyl/Likelihood/DRHomogeneousMixedTreeLikelihood.cpp b/src/Bpp/Phyl/Likelihood/DRHomogeneousMixedTreeLikelihood.cpp
index 6dee6c9..2d80c65 100644
--- a/src/Bpp/Phyl/Likelihood/DRHomogeneousMixedTreeLikelihood.cpp
+++ b/src/Bpp/Phyl/Likelihood/DRHomogeneousMixedTreeLikelihood.cpp
@@ -269,7 +269,7 @@ double DRHomogeneousMixedTreeLikelihood::getLogLikelihood() const
 }
 
 
-double DRHomogeneousMixedTreeLikelihood::getLikelihoodForASite(unsigned int site) const
+double DRHomogeneousMixedTreeLikelihood::getLikelihoodForASite(size_t site) const
 {
   double res = 0;
   for (unsigned int i = 0; i < treeLikelihoodsContainer_.size(); i++)
@@ -280,14 +280,14 @@ double DRHomogeneousMixedTreeLikelihood::getLikelihoodForASite(unsigned int site
   return res;
 }
 
-double DRHomogeneousMixedTreeLikelihood::getLogLikelihoodForASite(unsigned int site) const
+double DRHomogeneousMixedTreeLikelihood::getLogLikelihoodForASite(size_t site) const
 {
   double x = getLikelihoodForASite(site);
   if (x < 0) x = 0;
   return log(x);
 }
 
-double DRHomogeneousMixedTreeLikelihood::getLikelihoodForASiteForARateClass(unsigned int site, unsigned int rateClass) const
+double DRHomogeneousMixedTreeLikelihood::getLikelihoodForASiteForARateClass(size_t site, size_t rateClass) const
 {
   double res = 0;
   for (unsigned int i = 0; i < treeLikelihoodsContainer_.size(); i++)
@@ -298,14 +298,14 @@ double DRHomogeneousMixedTreeLikelihood::getLikelihoodForASiteForARateClass(unsi
   return res;
 }
 
-double DRHomogeneousMixedTreeLikelihood::getLogLikelihoodForASiteForARateClass(unsigned int site, unsigned int rateClass) const
+double DRHomogeneousMixedTreeLikelihood::getLogLikelihoodForASiteForARateClass(size_t site, size_t rateClass) const
 {
   double x = getLikelihoodForASiteForARateClass(site, rateClass);
   if (x < 0) x = 0;
   return log(x);
 }
 
-double DRHomogeneousMixedTreeLikelihood::getLikelihoodForASiteForARateClassForAState(unsigned int site, unsigned int rateClass, int state) const
+double DRHomogeneousMixedTreeLikelihood::getLikelihoodForASiteForARateClassForAState(size_t site, size_t rateClass, int state) const
 {
   double res = 0;
 
@@ -317,7 +317,7 @@ double DRHomogeneousMixedTreeLikelihood::getLikelihoodForASiteForARateClassForAS
   return res;
 }
 
-double DRHomogeneousMixedTreeLikelihood::getLogLikelihoodForASiteForARateClassForAState(unsigned int site, unsigned int rateClass, int state) const
+double DRHomogeneousMixedTreeLikelihood::getLogLikelihoodForASiteForARateClassForAState(size_t site, size_t rateClass, int state) const
 {
   double x = getLikelihoodForASiteForARateClassForAState(site, rateClass, state);
   if (x < 0) x = 0;
@@ -343,41 +343,41 @@ void DRHomogeneousMixedTreeLikelihood::computeSubtreeLikelihoodPrefix(const Node
 
 void DRHomogeneousMixedTreeLikelihood::computeRootLikelihood()
 {
-  for (unsigned int i = 0; i < treeLikelihoodsContainer_.size(); i++)
+  for (size_t i = 0; i < treeLikelihoodsContainer_.size(); i++)
   {
     treeLikelihoodsContainer_[i]->computeRootLikelihood();
   }
 }
 
-void DRHomogeneousMixedTreeLikelihood::computeLikelihoodAtNode_(const Node* node, VVVdouble& likelihoodArray) const
+void DRHomogeneousMixedTreeLikelihood::computeLikelihoodAtNode_(const Node* node, VVVdouble& likelihoodArray, const Node* sonNode) const
 {
   likelihoodArray.resize(nbDistinctSites_);
-  for (unsigned int i = 0; i < nbDistinctSites_; i++){
+  for (size_t i = 0; i < nbDistinctSites_; i++){
     VVdouble* likelihoodArray_i = &likelihoodArray[i];
     likelihoodArray_i->resize(nbClasses_);
-    for (unsigned int c = 0; c < nbClasses_; c++) {
+    for (size_t c = 0; c < nbClasses_; c++) {
       Vdouble* likelihoodArray_i_c = &(*likelihoodArray_i)[c];
       likelihoodArray_i_c->resize(nbStates_);
-      for (unsigned int x = 0; x < nbStates_; x++)
+      for (size_t x = 0; x < nbStates_; x++)
         (*likelihoodArray_i_c)[x] = 0;
     }
   }
 
   VVVdouble lArray;
-  for (unsigned int nm = 0; nm < treeLikelihoodsContainer_.size(); nm++)
+  for (size_t nm = 0; nm < treeLikelihoodsContainer_.size(); nm++)
   {
-    treeLikelihoodsContainer_[nm]->computeLikelihoodAtNode_(node, lArray);
+    treeLikelihoodsContainer_[nm]->computeLikelihoodAtNode_(node, lArray, sonNode);
     
-    for (unsigned int i = 0; i < nbDistinctSites_; i++)
+    for (size_t i = 0; i < nbDistinctSites_; i++)
       {
         VVdouble* likelihoodArray_i = &likelihoodArray[i];
         VVdouble* lArray_i = &lArray[i];
         
-        for (unsigned int c = 0; c < nbClasses_; c++)
+        for (size_t c = 0; c < nbClasses_; c++)
           {
             Vdouble* likelihoodArray_i_c = &(*likelihoodArray_i)[c];
             Vdouble* lArray_i_c = &(*lArray_i)[c];
-            for (unsigned int x = 0; x < nbStates_; x++)
+            for (size_t x = 0; x < nbStates_; x++)
               (*likelihoodArray_i_c)[x] += (*lArray_i_c)[x] * probas_[nm];
          }
       }
@@ -391,7 +391,7 @@ void DRHomogeneousMixedTreeLikelihood::computeLikelihoodAtNode_(const Node* node
 
 void DRHomogeneousMixedTreeLikelihood::computeTreeDLikelihoods()
 {
-  for (unsigned int i = 0; i < treeLikelihoodsContainer_.size(); i++)
+  for (size_t i = 0; i < treeLikelihoodsContainer_.size(); i++)
   {
     treeLikelihoodsContainer_[i]->computeTreeDLikelihoods();
   }
@@ -419,7 +419,7 @@ throw (Exception)
   unsigned int brI = TextTools::to<unsigned int>(variable.substr(5));
   const Node* branch = nodes_[brI];
   vector< Vdouble*> _vdLikelihoods_branch;
-  for (unsigned int i = 0; i < treeLikelihoodsContainer_.size(); i++)
+  for (size_t i = 0; i < treeLikelihoodsContainer_.size(); i++)
   {
     _vdLikelihoods_branch.push_back(&treeLikelihoodsContainer_[i]->likelihoodData_->getDLikelihoodArray(branch->getId()));
   }
diff --git a/src/Bpp/Phyl/Likelihood/DRHomogeneousMixedTreeLikelihood.h b/src/Bpp/Phyl/Likelihood/DRHomogeneousMixedTreeLikelihood.h
index 7958486..64ba1c7 100644
--- a/src/Bpp/Phyl/Likelihood/DRHomogeneousMixedTreeLikelihood.h
+++ b/src/Bpp/Phyl/Likelihood/DRHomogeneousMixedTreeLikelihood.h
@@ -143,8 +143,8 @@ public:
   double getLogLikelihood() const;
   
   void setData(const SiteContainer& sites) throw (Exception);
-  double getLikelihoodForASite (unsigned int site) const;
-  double getLogLikelihoodForASite(unsigned int site) const;
+  double getLikelihoodForASite (size_t site) const;
+  double getLogLikelihoodForASite(size_t site) const;
   /** @} */
 
 
@@ -153,10 +153,10 @@ public:
    *
    * @{
    */
-  double getLikelihoodForASiteForARateClass(unsigned int site, unsigned int rateClass) const;
-  double getLogLikelihoodForASiteForARateClass(unsigned int site, unsigned int rateClass) const;
-  double getLikelihoodForASiteForARateClassForAState(unsigned int site, unsigned int rateClass, int state) const;
-  double getLogLikelihoodForASiteForARateClassForAState(unsigned int site, unsigned int rateClass, int state) const;
+  double getLikelihoodForASiteForARateClass(size_t site, size_t rateClass) const;
+  double getLogLikelihoodForASiteForARateClass(size_t site, size_t rateClass) const;
+  double getLikelihoodForASiteForARateClassForAState(size_t site, size_t rateClass, int state) const;
+  double getLogLikelihoodForASiteForARateClassForAState(size_t site, size_t rateClass, int state) const;
   /** @} */
 
   /**
@@ -187,7 +187,7 @@ public:
   virtual void computeTreeDLikelihoods();
 
 protected:
-  virtual void computeLikelihoodAtNode_(const Node* node, VVVdouble& likelihoodArray) const;
+  virtual void computeLikelihoodAtNode_(const Node* node, VVVdouble& likelihoodArray, const Node* sonNode = 0) const;
 
   /**
    * @brief Compute the likelihood for a subtree defined by the Tree::Node <i>node</i>.
diff --git a/src/Bpp/Phyl/Likelihood/DRHomogeneousTreeLikelihood.cpp b/src/Bpp/Phyl/Likelihood/DRHomogeneousTreeLikelihood.cpp
index abfae54..97bd4a9 100644
--- a/src/Bpp/Phyl/Likelihood/DRHomogeneousTreeLikelihood.cpp
+++ b/src/Bpp/Phyl/Likelihood/DRHomogeneousTreeLikelihood.cpp
@@ -5,7 +5,7 @@
 //
 
 /*
-   Copyright or © or Copr. CNRS, (November 16, 2004)
+   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.
@@ -218,14 +218,14 @@ double DRHomogeneousTreeLikelihood::getLogLikelihoodForASiteForARateClass(size_t
 
 double DRHomogeneousTreeLikelihood::getLikelihoodForASiteForARateClassForAState(size_t site, size_t rateClass, int state) const
 {
-  return likelihoodData_->getRootLikelihoodArray()[likelihoodData_->getRootArrayPosition(site)][rateClass][state];
+  return likelihoodData_->getRootLikelihoodArray()[likelihoodData_->getRootArrayPosition(site)][rateClass][static_cast<size_t>(state)];
 }
 
 /******************************************************************************/
 
 double DRHomogeneousTreeLikelihood::getLogLikelihoodForASiteForARateClassForAState(size_t site, size_t rateClass, int state) const
 {
-  return log(likelihoodData_->getRootLikelihoodArray()[likelihoodData_->getRootArrayPosition(site)][rateClass][state]);
+  return log(likelihoodData_->getRootLikelihoodArray()[likelihoodData_->getRootArrayPosition(site)][rateClass][static_cast<size_t>(state)]);
 }
 
 /******************************************************************************/
@@ -291,47 +291,40 @@ throw (Exception)
 void DRHomogeneousTreeLikelihood::computeTreeDLikelihoodAtNode(const Node* node)
 {
   const Node* father = node->getFather();
-  VVVdouble* _likelihoods_father_node = &likelihoodData_->getLikelihoodArray(father->getId(), node->getId());
-  Vdouble* _dLikelihoods_node = &likelihoodData_->getDLikelihoodArray(node->getId());
-  VVVdouble*  pxy__node = &pxy_[node->getId()];
-  VVVdouble* dpxy__node = &dpxy_[node->getId()];
+  VVVdouble* likelihoods_father_node = &likelihoodData_->getLikelihoodArray(father->getId(), node->getId());
+  Vdouble* dLikelihoods_node = &likelihoodData_->getDLikelihoodArray(node->getId());
+  VVVdouble* dpxy_node = &dpxy_[node->getId()];
   VVVdouble larray;
-  computeLikelihoodAtNode_(father, larray);
+  computeLikelihoodAtNode_(father, larray, node);
   Vdouble* rootLikelihoodsSR = &likelihoodData_->getRootRateSiteLikelihoodArray();
 
-  double dLi, dLic, dLicx, numerator, denominator;
+  double dLi, dLic, dLicx;
 
   for (size_t i = 0; i < nbDistinctSites_; i++)
   {
-    VVdouble* _likelihoods_father_node_i = &(*_likelihoods_father_node)[i];
+    VVdouble* likelihoods_father_node_i = &(*likelihoods_father_node)[i];
     VVdouble* larray_i = &larray[i];
     dLi = 0;
     for (size_t c = 0; c < nbClasses_; c++)
     {
-      Vdouble* _likelihoods_father_node_i_c = &(*_likelihoods_father_node_i)[c];
+      Vdouble* likelihoods_father_node_i_c = &(*likelihoods_father_node_i)[c];
       Vdouble* larray_i_c = &(*larray_i)[c];
-      VVdouble*  pxy__node_c = &(*pxy__node)[c];
-      VVdouble* dpxy__node_c = &(*dpxy__node)[c];
+      VVdouble* dpxy_node_c = &(*dpxy_node)[c];
       dLic = 0;
       for (size_t x = 0; x < nbStates_; x++)
       {
-        numerator = 0;
-        denominator = 0;
-        Vdouble*  pxy__node_c_x = &(*pxy__node_c)[x];
-        Vdouble* dpxy__node_c_x = &(*dpxy__node_c)[x];
+        Vdouble* dpxy_node_c_x = &(*dpxy_node_c)[x];
         dLicx = 0;
         for (size_t y = 0; y < nbStates_; y++)
         {
-          numerator   += (*dpxy__node_c_x)[y] * (*_likelihoods_father_node_i_c)[y];
-          denominator += (*pxy__node_c_x)[y] * (*_likelihoods_father_node_i_c)[y];
+          dLicx += (*dpxy_node_c_x)[y] * (*likelihoods_father_node_i_c)[y];
         }
-        dLicx = denominator == 0. ? 0. : (*larray_i_c)[x] * numerator / denominator;
-        // cout << i << "\t" << c << "\t" << x << "\t" << (*larray_i_c)[x] << "\t" << numerator << "\t" << denominator << endl;
+        dLicx *= (*larray_i_c)[x];
         dLic += dLicx;
       }
       dLi += rateDistribution_->getProbability(c) * dLic;
     }
-    (*_dLikelihoods_node)[i] = dLi / (*rootLikelihoodsSR)[i];
+    (*dLikelihoods_node)[i] = dLi / (*rootLikelihoodsSR)[i];
     // cout << dLi << "\t" << (*rootLikelihoodsSR)[i] << endl;
   }
 }
@@ -369,12 +362,12 @@ throw (Exception)
   // Get the node with the branch whose length must be derivated:
   size_t brI = TextTools::to<size_t>(variable.substr(5));
   const Node* branch = nodes_[brI];
-  Vdouble* _dLikelihoods_branch = &likelihoodData_->getDLikelihoodArray(branch->getId());
+  Vdouble* dLikelihoods_branch = &likelihoodData_->getDLikelihoodArray(branch->getId());
   double d = 0;
   const vector<unsigned int>* w = &likelihoodData_->getWeights();
   for (size_t i = 0; i < nbDistinctSites_; i++)
   {
-    d += (*w)[i] * (*_dLikelihoods_branch)[i];
+    d += (*w)[i] * (*dLikelihoods_branch)[i];
   }
   return -d;
 }
@@ -385,46 +378,40 @@ throw (Exception)
 void DRHomogeneousTreeLikelihood::computeTreeD2LikelihoodAtNode(const Node* node)
 {
   const Node* father = node->getFather();
-  VVVdouble* _likelihoods_father_node = &likelihoodData_->getLikelihoodArray(father->getId(), node->getId());
-  Vdouble* _d2Likelihoods_node = &likelihoodData_->getD2LikelihoodArray(node->getId());
-  VVVdouble*   pxy__node = &pxy_[node->getId()];
-  VVVdouble* d2pxy__node = &d2pxy_[node->getId()];
+  VVVdouble* likelihoods_father_node = &likelihoodData_->getLikelihoodArray(father->getId(), node->getId());
+  Vdouble* d2Likelihoods_node = &likelihoodData_->getD2LikelihoodArray(node->getId());
+  VVVdouble* d2pxy_node = &d2pxy_[node->getId()];
   VVVdouble larray;
-  computeLikelihoodAtNode_(father, larray);
+  computeLikelihoodAtNode_(father, larray, node);
   Vdouble* rootLikelihoodsSR = &likelihoodData_->getRootRateSiteLikelihoodArray();
 
-  double d2Li, d2Lic, d2Licx, numerator, denominator;
+  double d2Li, d2Lic, d2Licx;
 
   for (size_t i = 0; i < nbDistinctSites_; i++)
   {
-    VVdouble* _likelihoods_father_node_i = &(*_likelihoods_father_node)[i];
+    VVdouble* likelihoods_father_node_i = &(*likelihoods_father_node)[i];
     VVdouble* larray_i = &larray[i];
     d2Li = 0;
     for (size_t c = 0; c < nbClasses_; c++)
     {
-      Vdouble* _likelihoods_father_node_i_c = &(*_likelihoods_father_node_i)[c];
+      Vdouble* likelihoods_father_node_i_c = &(*likelihoods_father_node_i)[c];
       Vdouble* larray_i_c = &(*larray_i)[c];
-      VVdouble*   pxy__node_c = &(*pxy__node)[c];
-      VVdouble* d2pxy__node_c = &(*d2pxy__node)[c];
+      VVdouble* d2pxy_node_c = &(*d2pxy_node)[c];
       d2Lic = 0;
       for (size_t x = 0; x < nbStates_; x++)
       {
-        numerator = 0;
-        denominator = 0;
-        Vdouble*   pxy__node_c_x = &(*pxy__node_c)[x];
-        Vdouble* d2pxy__node_c_x = &(*d2pxy__node_c)[x];
+        Vdouble* d2pxy_node_c_x = &(*d2pxy_node_c)[x];
         d2Licx = 0;
         for (size_t y = 0; y < nbStates_; y++)
         {
-          numerator   += (*d2pxy__node_c_x)[y] * (*_likelihoods_father_node_i_c)[y];
-          denominator += (*pxy__node_c_x)[y] * (*_likelihoods_father_node_i_c)[y];
+          d2Licx += (*d2pxy_node_c_x)[y] * (*likelihoods_father_node_i_c)[y];
         }
-        d2Licx = denominator == 0. ? 0. : (*larray_i_c)[x] * numerator / denominator;
+        d2Licx *= (*larray_i_c)[x];
         d2Lic += d2Licx;
       }
       d2Li += rateDistribution_->getProbability(c) * d2Lic;
     }
-    (*_d2Likelihoods_node)[i] = d2Li / (*rootLikelihoodsSR)[i];
+    (*d2Likelihoods_node)[i] = d2Li / (*rootLikelihoodsSR)[i];
   }
 }
 
@@ -739,7 +726,7 @@ void DRHomogeneousTreeLikelihood::computeRootLikelihood()
 
 /******************************************************************************/
 
-void DRHomogeneousTreeLikelihood::computeLikelihoodAtNode_(const Node* node, VVVdouble& likelihoodArray) const
+void DRHomogeneousTreeLikelihood::computeLikelihoodAtNode_(const Node* node, VVVdouble& likelihoodArray, const Node* sonNode) const
 {
   // const Node * node = tree_->getNode(nodeId);
   int nodeId = node->getId();
@@ -788,13 +775,24 @@ void DRHomogeneousTreeLikelihood::computeLikelihoodAtNode_(const Node* node, VVV
 
   size_t nbNodes = node->getNumberOfSons();
 
-  vector<const VVVdouble*> iLik(nbNodes);
-  vector<const VVVdouble*> tProb(nbNodes);
+  vector<const VVVdouble*> iLik;
+  vector<const VVVdouble*> tProb;
+  bool test = false;
   for (size_t n = 0; n < nbNodes; n++)
   {
     const Node* son = node->getSon(n);
-    tProb[n] = &pxy_[son->getId()];
-    iLik[n] = &(*likelihoods_node)[son->getId()];
+    if (son != sonNode) {
+      tProb.push_back(&pxy_[son->getId()]);
+      iLik.push_back(&(*likelihoods_node)[son->getId()]);
+    } else {
+      test = true;
+    }
+  }
+  if (sonNode) {
+    if (test)
+      nbNodes--;
+    else
+      throw Exception("DRHomogeneousTreeLikelihood::computeLikelihoodAtNode_(...). 'sonNode' not found as a son of 'node'.");
   }
 
   if (node->hasFather())
diff --git a/src/Bpp/Phyl/Likelihood/DRHomogeneousTreeLikelihood.h b/src/Bpp/Phyl/Likelihood/DRHomogeneousTreeLikelihood.h
index f62cf7b..cd5e147 100755
--- a/src/Bpp/Phyl/Likelihood/DRHomogeneousTreeLikelihood.h
+++ b/src/Bpp/Phyl/Likelihood/DRHomogeneousTreeLikelihood.h
@@ -212,7 +212,7 @@ class DRHomogeneousTreeLikelihood:
     }
       
   protected:
-    virtual void computeLikelihoodAtNode_(const Node* node, VVVdouble& likelihoodArray) const;
+    virtual void computeLikelihoodAtNode_(const Node* node, VVVdouble& likelihoodArray, const Node* sonNode = 0) const;
   
     /**
      * Initialize the arrays corresponding to each son node for the node passed as argument.
diff --git a/src/Bpp/Phyl/Likelihood/DRNonHomogeneousTreeLikelihood.cpp b/src/Bpp/Phyl/Likelihood/DRNonHomogeneousTreeLikelihood.cpp
index 25b3ec1..dafd301 100644
--- a/src/Bpp/Phyl/Likelihood/DRNonHomogeneousTreeLikelihood.cpp
+++ b/src/Bpp/Phyl/Likelihood/DRNonHomogeneousTreeLikelihood.cpp
@@ -5,7 +5,7 @@
 //
 
 /*
-   Copyright or © or Copr. CNRS, (November 16, 2004)
+   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.
@@ -222,14 +222,14 @@ double DRNonHomogeneousTreeLikelihood::getLogLikelihoodForASiteForARateClass(siz
 
 double DRNonHomogeneousTreeLikelihood::getLikelihoodForASiteForARateClassForAState(size_t site, size_t rateClass, int state) const
 {
-  return likelihoodData_->getRootLikelihoodArray()[likelihoodData_->getRootArrayPosition(site)][rateClass][state];
+  return likelihoodData_->getRootLikelihoodArray()[likelihoodData_->getRootArrayPosition(site)][rateClass][static_cast<size_t>(state)];
 }
 
 /******************************************************************************/
 
 double DRNonHomogeneousTreeLikelihood::getLogLikelihoodForASiteForARateClassForAState(size_t site, size_t rateClass, int state) const
 {
-  return log(likelihoodData_->getRootLikelihoodArray()[likelihoodData_->getRootArrayPosition(site)][rateClass][state]);
+  return log(likelihoodData_->getRootLikelihoodArray()[likelihoodData_->getRootArrayPosition(site)][rateClass][static_cast<size_t>(state)]);
 }
 
 /******************************************************************************/
diff --git a/src/Bpp/Phyl/Likelihood/MarginalAncestralStateReconstruction.cpp b/src/Bpp/Phyl/Likelihood/MarginalAncestralStateReconstruction.cpp
index fe4a673..0093a18 100644
--- a/src/Bpp/Phyl/Likelihood/MarginalAncestralStateReconstruction.cpp
+++ b/src/Bpp/Phyl/Likelihood/MarginalAncestralStateReconstruction.cpp
@@ -53,12 +53,12 @@ vector<size_t> MarginalAncestralStateReconstruction::getAncestralStatesForNode(i
   if (likelihood_->getTree().isLeaf(nodeId))
   {
     VVdouble larray = likelihood_->getLikelihoodData()->getLeafLikelihoods(nodeId);
-    for (size_t i = 0; i < nbDistinctSites_; i++)
+    for (size_t i = 0; i < nbDistinctSites_; ++i)
     {
       Vdouble* probs_i = &probs[i];
       probs_i->resize(nbStates_);
       size_t j = VectorTools::whichMax(larray[i]);
-      ancestors[i] = (int)j;
+      ancestors[i] = j;
       (*probs_i)[j] = 1.;
     }
   }
@@ -89,7 +89,7 @@ vector<size_t> MarginalAncestralStateReconstruction::getAncestralStatesForNode(i
           cumProb += (*probs_i)[j];
           if (r <= cumProb)
           {
-            ancestors[i] = (int)j;
+            ancestors[i] = j;
             break;
           }
         }
@@ -125,7 +125,7 @@ Sequence* MarginalAncestralStateReconstruction::getAncestralSequenceForNode(int
     probs->resize(nbSites_);
     for (size_t i = 0; i < nbSites_; i++)
     {
-      allStates[i] = model->getAlphabetChar(states[(*rootPatternLinks)[i]]);
+      allStates[i] = model->getAlphabetStateAsInt(states[(*rootPatternLinks)[i]]);
       (*probs)[i] = patternedProbs[(*rootPatternLinks)[i]];
     }
   }
@@ -134,7 +134,7 @@ Sequence* MarginalAncestralStateReconstruction::getAncestralSequenceForNode(int
     states = getAncestralStatesForNode(nodeId, patternedProbs, sample);
     for (size_t i = 0; i < nbSites_; i++)
     {
-      allStates[i] = model->getAlphabetChar(states[(*rootPatternLinks)[i]]);
+      allStates[i] = model->getAlphabetStateAsInt(states[(*rootPatternLinks)[i]]);
     }
   }
   return new BasicSequence(name, allStates, alphabet_);
diff --git a/src/Bpp/Phyl/Likelihood/MarginalAncestralStateReconstruction.h b/src/Bpp/Phyl/Likelihood/MarginalAncestralStateReconstruction.h
index 0316956..7c3a7ad 100755
--- a/src/Bpp/Phyl/Likelihood/MarginalAncestralStateReconstruction.h
+++ b/src/Bpp/Phyl/Likelihood/MarginalAncestralStateReconstruction.h
@@ -5,7 +5,7 @@
 //
 
 /*
-Copyright or © or Copr. CNRS, (November 16, 2004)
+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.
diff --git a/src/Bpp/Phyl/Likelihood/PairedSiteLikelihoods.cpp b/src/Bpp/Phyl/Likelihood/PairedSiteLikelihoods.cpp
index 231e4b5..e092684 100644
--- a/src/Bpp/Phyl/Likelihood/PairedSiteLikelihoods.cpp
+++ b/src/Bpp/Phyl/Likelihood/PairedSiteLikelihoods.cpp
@@ -181,7 +181,7 @@ std::vector<int> PairedSiteLikelihoods::bootstrap(std::size_t length, double sca
 
   for (size_t i = 0; i < static_cast<size_t>(static_cast<double>(length) * scaling + 0.5); ++i)
   {
-    ++v.at(RandomTools::giveIntRandomNumberBetweenZeroAndEntry(static_cast<int>(length)));
+    ++v[RandomTools::giveIntRandomNumberBetweenZeroAndEntry<size_t>(length)];
   }
 
   return v;
diff --git a/src/Bpp/Phyl/Likelihood/RHomogeneousTreeLikelihood.cpp b/src/Bpp/Phyl/Likelihood/RHomogeneousTreeLikelihood.cpp
index bee2be7..f3422f1 100644
--- a/src/Bpp/Phyl/Likelihood/RHomogeneousTreeLikelihood.cpp
+++ b/src/Bpp/Phyl/Likelihood/RHomogeneousTreeLikelihood.cpp
@@ -235,14 +235,14 @@ double RHomogeneousTreeLikelihood::getLogLikelihoodForASiteForARateClass(size_t
 
 double RHomogeneousTreeLikelihood::getLikelihoodForASiteForARateClassForAState(size_t site, size_t rateClass, int state) const
 {
-  return likelihoodData_->getLikelihoodArray(tree_->getRootNode()->getId())[likelihoodData_->getRootArrayPosition(site)][rateClass][state];
+  return likelihoodData_->getLikelihoodArray(tree_->getRootNode()->getId())[likelihoodData_->getRootArrayPosition(site)][rateClass][static_cast<size_t>(state)];
 }
 
 /******************************************************************************/
 
 double RHomogeneousTreeLikelihood::getLogLikelihoodForASiteForARateClassForAState(size_t site, size_t rateClass, int state) const
 {
-  return log(likelihoodData_->getLikelihoodArray(tree_->getRootNode()->getId())[likelihoodData_->getRootArrayPosition(site)][rateClass][state]);
+  return log(likelihoodData_->getLikelihoodArray(tree_->getRootNode()->getId())[likelihoodData_->getRootArrayPosition(site)][rateClass][static_cast<size_t>(state)]);
 }
 
 /******************************************************************************/
diff --git a/src/Bpp/Phyl/Likelihood/RNonHomogeneousMixedTreeLikelihood.cpp b/src/Bpp/Phyl/Likelihood/RNonHomogeneousMixedTreeLikelihood.cpp
index d0a5722..d727d92 100644
--- a/src/Bpp/Phyl/Likelihood/RNonHomogeneousMixedTreeLikelihood.cpp
+++ b/src/Bpp/Phyl/Likelihood/RNonHomogeneousMixedTreeLikelihood.cpp
@@ -150,7 +150,7 @@ void RNonHomogeneousMixedTreeLikelihood::init(bool usePatterns)
   vector<int> vn;
   size_t nbmodels = modelSet_->getNumberOfModels();
 
-  const SiteContainer* pdata=getData();
+  const SiteContainer* pdata = getData();
   
   const Tree& tree = getTree();
   
@@ -213,8 +213,8 @@ void RNonHomogeneousMixedTreeLikelihood::init(bool usePatterns)
       size_t ttmodels = 1;
       for (vector<int>::iterator it = vExpMod.begin(); it != vExpMod.end(); it++)
       {
-        mapmodels[*it] = static_cast<int>(hyperNode_.getNode(*it).size());
-        ttmodels *= mapmodels[*it];
+        mapmodels[*it] = static_cast<int>(hyperNode_.getNode(static_cast<size_t>(*it)).size());
+        ttmodels *= static_cast<size_t>(mapmodels[*it]);
       }
 
       for (size_t i = 0; i < ttmodels; i++)
@@ -226,7 +226,7 @@ void RNonHomogeneousMixedTreeLikelihood::init(bool usePatterns)
         {
           if ((hyperNode_.getNode(j).size() >= 1) && find(vExpMod.begin(), vExpMod.end(), static_cast<int>(j)) != vExpMod.end())
           {
-            hn.setModel(j, Vint(1, hyperNode_.getNode(j)[s % mapmodels[static_cast<int>(j)]]));
+            hn.setModel(j, Vint(1, hyperNode_.getNode(j)[static_cast<size_t>(s % mapmodels[static_cast<int>(j)])]));
             s /= mapmodels[static_cast<int>(j)];
           }
         }
@@ -726,22 +726,22 @@ void RNonHomogeneousMixedTreeLikelihood::computeTransitionProbabilitiesForNode(c
   vector<const SubstitutionModel*> vModel;
   vector<double> vProba;
   
-  const MixedSubstitutionModelSet::HyperNode::Node& nd=hyperNode_.getNode(modelnum);
+  const MixedSubstitutionModelSet::HyperNode::Node& nd = hyperNode_.getNode(modelnum);
   if (nd.size() == 0) {
     vModel.push_back(model);
     vProba.push_back(1);
   }
   else {
     const MixedSubstitutionModel* mmodel = dynamic_cast<const MixedSubstitutionModel*>(model);
-    double x=0;
-    for (size_t i=0;i<nd.size();i++){
-      vModel.push_back(mmodel->getNModel(nd[i]));
-      vProba.push_back(mmodel->getNProbability(nd[i]));
-      x+=vProba[i];
+    double x = 0;
+    for (size_t i = 0; i < nd.size(); ++i){
+      vModel.push_back(mmodel->getNModel(static_cast<size_t>(nd[i])));
+      vProba.push_back(mmodel->getNProbability(static_cast<size_t>(nd[i])));
+      x += vProba[i];
     }
-    if (x!=0)
-      for (size_t i=0;i<nd.size();i++)
-        vProba[i]/=x;
+    if (x != 0)
+      for (size_t i = 0; i < nd.size(); ++i)
+        vProba[i] /= x;
   }
 
   double l = node->getDistanceToFather();
diff --git a/src/Bpp/Phyl/Likelihood/RNonHomogeneousTreeLikelihood.cpp b/src/Bpp/Phyl/Likelihood/RNonHomogeneousTreeLikelihood.cpp
index acd7572..f736bf4 100644
--- a/src/Bpp/Phyl/Likelihood/RNonHomogeneousTreeLikelihood.cpp
+++ b/src/Bpp/Phyl/Likelihood/RNonHomogeneousTreeLikelihood.cpp
@@ -6,7 +6,7 @@
 //
 
 /*
-   Copyright or © or Copr. CNRS, (November 16, 2004)
+   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.
@@ -239,14 +239,14 @@ double RNonHomogeneousTreeLikelihood::getLogLikelihoodForASiteForARateClass(size
 
 double RNonHomogeneousTreeLikelihood::getLikelihoodForASiteForARateClassForAState(size_t site, size_t rateClass, int state) const
 {
-  return likelihoodData_->getLikelihoodArray(tree_->getRootNode()->getId())[likelihoodData_->getRootArrayPosition(site)][rateClass][state];
+  return likelihoodData_->getLikelihoodArray(tree_->getRootNode()->getId())[likelihoodData_->getRootArrayPosition(site)][rateClass][static_cast<size_t>(state)];
 }
 
 /******************************************************************************/
 
 double RNonHomogeneousTreeLikelihood::getLogLikelihoodForASiteForARateClassForAState(size_t site, size_t rateClass, int state) const
 {
-  return log(likelihoodData_->getLikelihoodArray(tree_->getRootNode()->getId())[likelihoodData_->getRootArrayPosition(site)][rateClass][state]);
+  return log(likelihoodData_->getLikelihoodArray(tree_->getRootNode()->getId())[likelihoodData_->getRootArrayPosition(site)][rateClass][static_cast<size_t>(state)]);
 }
 
 /******************************************************************************/
diff --git a/src/Bpp/Phyl/Likelihood/RNonHomogeneousTreeLikelihood.h b/src/Bpp/Phyl/Likelihood/RNonHomogeneousTreeLikelihood.h
index d84b351..4148f43 100644
--- a/src/Bpp/Phyl/Likelihood/RNonHomogeneousTreeLikelihood.h
+++ b/src/Bpp/Phyl/Likelihood/RNonHomogeneousTreeLikelihood.h
@@ -6,7 +6,7 @@
 //
 
 /*
-  Copyright or © or Copr. CNRS, (November 16, 2004)
+  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.
diff --git a/src/Bpp/Phyl/Likelihood/SitePartitionTreeLikelihood.h b/src/Bpp/Phyl/Likelihood/SitePartitionTreeLikelihood.h
index 72c9e97..81dc253 100644
--- a/src/Bpp/Phyl/Likelihood/SitePartitionTreeLikelihood.h
+++ b/src/Bpp/Phyl/Likelihood/SitePartitionTreeLikelihood.h
@@ -5,7 +5,7 @@
 //
 
 /*
-Copyright or © or Copr. CNRS, (November 16, 2004)
+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.
@@ -51,23 +51,23 @@ namespace bpp
  *
  * These models allow the distinct sites of an alignment to have a different model.
  * The substitution model is however assumed to be the same along the tree.
- * suche models are hence homogeneous in time.
+ * Such models are hence homogeneous in time.
  */
 class SitePartitionHomogeneousTreeLikelihood :
-	public virtual TreeLikelihood
+  public virtual TreeLikelihood
 {
-	public:
+  public:
 #ifndef NO_VIRTUAL_COV
     SitePartitionHomogeneousTreeLikelihood* clone() const = 0;
 #endif
 
   public:
-    const SubstitutionModel* getSubstitutionModel(int nodeId, unsigned int siteIndex) const throw (NodeNotFoundException)
+    const SubstitutionModel* getSubstitutionModel(int nodeId, size_t siteIndex) const throw (NodeNotFoundException)
     {
       return getSubstitutionModelForSite(siteIndex);
     }
 
-    SubstitutionModel* getSubstitutionModel(int nodeId, unsigned int siteIndex) throw (NodeNotFoundException)
+    SubstitutionModel* getSubstitutionModel(int nodeId, size_t siteIndex) throw (NodeNotFoundException)
     {
       return getSubstitutionModelForSite(siteIndex);
     }
@@ -78,7 +78,7 @@ class SitePartitionHomogeneousTreeLikelihood :
      * @param siteIndex The position in the alignment.
      * @return A pointer toward the corresponding model.
      */
-    virtual const SubstitutionModel* getSubstitutionModelForSite(int siteIndex) const = 0;
+    virtual const SubstitutionModel* getSubstitutionModelForSite(size_t siteIndex) const = 0;
 
     /**
      * @brief Get the substitution model associated to a given node.
@@ -86,11 +86,11 @@ class SitePartitionHomogeneousTreeLikelihood :
      * @param siteIndex The position in the alignment.
      * @return A pointer toward the corresponding model.
      */
-    virtual SubstitutionModel* getSubstitutionModelForSite(unsigned int siteIndex) = 0;
+    virtual SubstitutionModel* getSubstitutionModelForSite(size_t siteIndex) = 0;
 
 };
 
 } //end of namespace bpp.
 
-#endif	//_SITEPARTITIONTREELIKELIHOOD_H_
+#endif  //_SITEPARTITIONTREELIKELIHOOD_H_
 
diff --git a/src/Bpp/Phyl/Likelihood/TreeLikelihood.h b/src/Bpp/Phyl/Likelihood/TreeLikelihood.h
index c9cfc65..7fb8f53 100755
--- a/src/Bpp/Phyl/Likelihood/TreeLikelihood.h
+++ b/src/Bpp/Phyl/Likelihood/TreeLikelihood.h
@@ -299,13 +299,26 @@ class TreeLikelihood:
     virtual size_t getNumberOfSites() const = 0;
 
     /**
-     * @brief Get the number of states in the alphabet associated to the dataset.
-     *
-     * @return the number of states in the alphabet associated to the dataset.
+     * @return the number of model states of the underlying Markov chain.
      */    
     virtual size_t getNumberOfStates() const = 0;
     
     /**
+     * @return the alphabet state corresponding to the given model state.
+     */    
+    virtual int getAlphabetStateAsInt(size_t i) const = 0;
+  
+    /**
+     * @return the alphabet state corresponding to the given model state.
+     */    
+    virtual std::string getAlphabetStateAsChar(size_t i) const = 0;
+ 
+    /**
+     * @return the alphabet states corresponding to all model states.
+     */    
+    virtual const std::vector<int>& getAlphabetStates() const = 0;
+  
+    /**
      * @brief Get the alphabet associated to the dataset.
      *
      * @return the alphabet associated to the dataset.
diff --git a/src/Bpp/Phyl/Mapping/DecompositionReward.cpp b/src/Bpp/Phyl/Mapping/DecompositionReward.cpp
new file mode 100644
index 0000000..3dcf9e8
--- /dev/null
+++ b/src/Bpp/Phyl/Mapping/DecompositionReward.cpp
@@ -0,0 +1,214 @@
+//
+// File: DecompositionReward.h
+// Created by: Laurent Guéguen
+// Created on: mercredi 27 mars 2013, à 12h 36
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 16, 2004, 2005, 2006)
+
+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 "DecompositionReward.h"
+
+#include "Bpp/Numeric/Matrix/MatrixTools.h"
+#include <vector>
+
+using namespace bpp;
+using namespace std;
+
+/******************************************************************************/
+
+DecompositionReward::DecompositionReward(const SubstitutionModel* model, AlphabetIndex1* alphIndex) :
+  AbstractReward(alphIndex),
+  model_(dynamic_cast<const ReversibleSubstitutionModel*>(model)),
+  nbStates_(model->getNumberOfStates()),
+  jMat_(nbStates_, nbStates_),
+  v_(nbStates_, nbStates_),
+  vInv_(nbStates_, nbStates_),
+  lambda_(nbStates_, nbStates_),
+  bMatrice_(nbStates_, nbStates_),
+  insideProduct_(nbStates_, nbStates_),
+  rewards_(nbStates_, nbStates_),
+  currentLength_(-1.)
+{
+  //Check compatiblity between model and alphabet Index:
+  if (model->getAlphabet()->getAlphabetType() != alphIndex_->getAlphabet()->getAlphabetType())
+    throw Exception("DecompositionReward (constructor): alphabets do not match between alphabet index and model.");
+  if (!dynamic_cast<const ReversibleSubstitutionModel*>(model))
+    throw Exception("DecompositionReward::DecompositionReward. Only works with declared reversible models for now.");
+
+  //Initialize the B matrice. This is done once for all,
+  //unless the number of states changes:
+  computeBMatrice_();
+  computeEigen_();
+  computeProducts_();
+}				
+    
+/******************************************************************************/
+
+void DecompositionReward::computeBMatrice_()
+{
+  vector<int> supportedStates = model_->getAlphabetStates();
+  for (size_t j = 0; j < nbStates_; ++j) 
+    bMatrice_(j, j) = getAlphabetIndex()->getIndex(supportedStates[j]);
+}
+
+void DecompositionReward::computeEigen_()
+{
+  v_      = model_->getColumnRightEigenVectors();
+  vInv_   = model_->getRowLeftEigenVectors();
+  lambda_ = model_->getEigenValues();
+}
+
+void DecompositionReward::computeProducts_()
+{
+  RowMatrix<double> tmp(nbStates_, nbStates_);
+  MatrixTools::mult(vInv_, bMatrice_, tmp);
+  MatrixTools::mult(tmp, v_, insideProduct_);
+}
+
+void DecompositionReward::resetStates_()
+{
+  jMat_.resize(nbStates_, nbStates_);
+  v_.resize(nbStates_, nbStates_);
+  vInv_.resize(nbStates_, nbStates_);
+  lambda_.resize(nbStates_);
+  bMatrice_.resize(nbStates_, nbStates_);
+  insideProduct_.resize(nbStates_, nbStates_);
+  rewards_.resize(nbStates_, nbStates_);
+}
+
+void DecompositionReward::jFunction_(const std::vector<double>& lambda, double t, RowMatrix<double>& result) const
+{
+  vector<double> expLam = VectorTools::exp(lambda * t);
+  for (unsigned int i = 0; i < nbStates_; ++i) {
+    for (unsigned int j = 0; j < nbStates_; ++j) {
+      double dd = lambda[i] - lambda[j];
+      if (dd == 0) {
+        result(i, j) = t * expLam[i];
+      } else {
+        result(i, j) = (expLam[i] - expLam[j]) / dd;
+      }
+    }
+  }
+}
+
+/******************************************************************************/
+
+void DecompositionReward::computeRewards_(double length) const
+{
+  jFunction_(lambda_, length, jMat_);
+  RowMatrix<double> tmp1(nbStates_, nbStates_), tmp2(nbStates_, nbStates_);
+  MatrixTools::hadamardMult(jMat_, insideProduct_, tmp1);
+  MatrixTools::mult(v_, tmp1, tmp2);
+  MatrixTools::mult(tmp2, vInv_, rewards_);
+
+  // Now we must divide by pijt:
+  RowMatrix<double> P = model_->getPij_t(length);
+  for (size_t j = 0; j < nbStates_; j++) {
+    for (size_t k = 0; k < nbStates_; k++) {
+      rewards_(j, k) /= P(j, k);
+      if (isnan(rewards_(j, k)))
+        rewards_(j, k) = 0.;
+    }
+  }
+}
+
+/******************************************************************************/
+
+Matrix<double>* DecompositionReward::getAllRewards(double length) const
+{
+  if (length < 0)
+    throw Exception("DecompositionReward::getAllRewards. Negative branch length: " + TextTools::toString(length) + ".");
+  if (length != currentLength_)
+    {
+      computeRewards_(length);
+      currentLength_ = length;
+    }
+  return new RowMatrix<double>(rewards_);
+}
+
+/******************************************************************************/
+
+double DecompositionReward::getReward(size_t initialState, size_t finalState, double length) const
+{
+  if (length < 0)
+    throw Exception("DecompositionReward::getRewards. Negative branch length: " + TextTools::toString(length) + ".");
+  if (length != currentLength_)
+  {
+    computeRewards_(length);
+    currentLength_ = length;
+  }
+  return rewards_(initialState, finalState);
+}
+
+/******************************************************************************/
+
+void DecompositionReward::setSubstitutionModel(const SubstitutionModel* model)
+{
+  const ReversibleSubstitutionModel* rModel = dynamic_cast<const ReversibleSubstitutionModel*>(model);
+  if (!rModel)
+    throw Exception("DecompositionReward::setSubstitutionModel. Only works with reversible models for now.");
+
+  //Check compatiblity between model and substitution register:
+  if (model->getAlphabet()->getAlphabetType() != alphIndex_->getAlphabet()->getAlphabetType())
+    throw Exception("DecompositionReward::setSubstitutionModel: alphabets do not match between alphabet index and model.");
+  model_ = rModel;
+  unsigned int n = model->getAlphabet()->getSize();
+  if (n != nbStates_) {
+    nbStates_ = n;
+    resetStates_();
+  }
+  computeEigen_();
+  computeProducts_();
+
+  //Recompute rewards:
+  computeRewards_(currentLength_);
+}
+
+/******************************************************************************/
+
+void DecompositionReward::alphabetIndexHasChanged() throw (Exception)
+{
+  //Check compatiblity between model and substitution register:
+  if (model_->getAlphabet()->getAlphabetType() != alphIndex_->getAlphabet()->getAlphabetType())
+    throw Exception("DecompositionReward::AlphabetIndexHasChanged: alphabets do not match between alphbaet index and model.");
+
+  computeBMatrice_();
+  computeProducts_();
+
+  //Recompute rewards:
+  if (currentLength_ > 0)
+   computeRewards_(currentLength_);
+}
+
+
diff --git a/src/Bpp/Phyl/Mapping/DecompositionReward.h b/src/Bpp/Phyl/Mapping/DecompositionReward.h
new file mode 100644
index 0000000..acbfde4
--- /dev/null
+++ b/src/Bpp/Phyl/Mapping/DecompositionReward.h
@@ -0,0 +1,144 @@
+//
+// File: DecompositionReward.h
+// Created by: Laurent Guéguen
+// Created on: mercredi 27 mars 2013, à 12h 29
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 16, 2004, 2005, 2006)
+
+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 _DECOMPOSITIONREWARD_H_
+#define _DECOMPOSITIONREWARD_H_
+
+#include "Reward.h"
+
+#include <Bpp/Numeric/Matrix/Matrix.h>
+
+namespace bpp
+{
+
+/**
+ * @brief Analytical reward using the eigen decomposition method.
+ *
+ * The codes is adapted from the original R code by Paula Tataru and
+ * Asger Hobolth to the formula in the article of Minin & Suchard.
+ *
+ * Minin, V.N. and Suchard, M.A., 
+ * Fast, accurate and simulation-free stochastic mapping
+ * Philosophical Transactions of the Royal Society B 2008 363:3985-95.
+ *
+ * Only reversible models are supported for now.
+ *
+ * @author Laurent Guéguen
+ */
+  
+class DecompositionReward:
+  public AbstractReward
+{
+private:
+  const ReversibleSubstitutionModel* model_;
+  size_t nbStates_;
+  mutable RowMatrix<double> jMat_, v_, vInv_;
+  mutable std::vector<double> lambda_;
+  RowMatrix<double> bMatrice_, insideProduct_;
+  mutable RowMatrix<double> rewards_;
+  mutable double currentLength_;
+	
+public:
+  DecompositionReward(const SubstitutionModel* model, AlphabetIndex1* alphIndex);
+		
+  DecompositionReward(const DecompositionReward& dr) :
+    AbstractReward(dr),
+    model_(dr.model_),
+    nbStates_(dr.nbStates_),
+    jMat_(dr.jMat_),
+    v_(dr.v_),
+    vInv_(dr.vInv_),
+    lambda_(dr.lambda_),
+    bMatrice_(dr.bMatrice_),
+    insideProduct_(dr.insideProduct_),
+    rewards_(dr.rewards_),
+    currentLength_(dr.currentLength_)
+  {}
+    
+  DecompositionReward& operator=(const DecompositionReward& dr)
+  {
+    AbstractReward::operator=(dr);
+    model_          = dr.model_;
+    nbStates_       = dr.nbStates_;
+    jMat_           = dr.jMat_;
+    v_              = dr.v_;
+    vInv_           = dr.vInv_;
+    lambda_         = dr.lambda_;
+    bMatrice_       = dr.bMatrice_;
+    insideProduct_  = dr.insideProduct_;
+    rewards_        = dr.rewards_;
+    currentLength_  = dr.currentLength_;
+    return *this;
+  }				
+		
+  virtual ~DecompositionReward() {}
+		
+  DecompositionReward* clone() const { return new DecompositionReward(*this); }
+
+public:
+  double getReward(size_t initialState, size_t finalState, double length) const;
+
+  Matrix<double>* getAllRewards(double length) const;
+    
+  /**
+   * @brief Set the substitution model.
+   *
+   * @param model A pointer toward the substitution model to use. Only
+   * reversible models are currently supported. Setting a
+   * non-reversible model will throw an exception.
+   *
+   */
+  void setSubstitutionModel(const SubstitutionModel* model);
+
+protected:
+  void computeRewards_(double length) const;
+  void jFunction_(const std::vector<double>& lambda, double t, RowMatrix<double>& result) const;
+  void alphabetIndexHasChanged() throw (Exception);
+
+private:
+  void resetStates_();
+  void computeBMatrice_();
+  void computeEigen_();
+  void computeProducts_();
+};
+
+} //end of namespace bpp.
+
+#endif // _DECOMPOSITIONREWARD_H_
+
diff --git a/src/Bpp/Phyl/Mapping/DecompositionSubstitutionCount.cpp b/src/Bpp/Phyl/Mapping/DecompositionSubstitutionCount.cpp
index 6a4a090..69001b7 100644
--- a/src/Bpp/Phyl/Mapping/DecompositionSubstitutionCount.cpp
+++ b/src/Bpp/Phyl/Mapping/DecompositionSubstitutionCount.cpp
@@ -77,12 +77,14 @@ DecompositionSubstitutionCount::DecompositionSubstitutionCount(const ReversibleS
 
 void DecompositionSubstitutionCount::fillBMatrices_()
 {
-  int n = static_cast<int>(nbStates_); //Note jdutheil 20/01/13: shoudl be generalized in case sattes are not 0:n !
-  for (int j = 0; j < n; ++j) {
-    for (int k = 0; k < n; ++k) {
+  vector<int> supportedStates = model_->getAlphabetStates();
+  for (size_t j = 0; j < nbStates_; ++j) {
+    for (size_t k = 0; k < nbStates_; ++k) {
       size_t i = register_->getType(j, k);
       if (i > 0 && k != j) {
-        bMatrices_[i - 1](j, k) = model_->Qij(j, k) * (weights_ ? weights_->getIndex(j, k) : 1);
+        //jdutheil on 25/07/14: I think this is incorrect, weights should only come at the end.
+        //bMatrices_[i - 1](j, k) = model_->Qij(j, k) * (weights_ ? weights_->getIndex(fromState, toState) : 1);
+        bMatrices_[i - 1](j, k) = model_->Qij(j, k);
       }
     }
   }
@@ -90,9 +92,9 @@ void DecompositionSubstitutionCount::fillBMatrices_()
 
 void DecompositionSubstitutionCount::computeEigen_()
 {
-	v_      = model_->getColumnRightEigenVectors();
+  v_      = model_->getColumnRightEigenVectors();
   vInv_   = model_->getRowLeftEigenVectors();
-	lambda_ = model_->getEigenValues();
+  lambda_ = model_->getEigenValues();
 }
 
 void DecompositionSubstitutionCount::computeProducts_()
@@ -157,7 +159,8 @@ void DecompositionSubstitutionCount::computeCounts_(double length) const
     MatrixTools::mult(v_, tmp1, tmp2);
     MatrixTools::mult(tmp2, vInv_, counts_[i]);
 	}
-  // Now we must divide by pijt:
+  // Now we must divide by pijt and account for putative weights:
+  vector<int> supportedStates = model_->getAlphabetStates();
   RowMatrix<double> P = model_->getPij_t(length);
   for (size_t i = 0; i < register_->getNumberOfSubstitutionTypes(); i++) {
     for (size_t j = 0; j < nbStates_; j++) {
@@ -165,6 +168,9 @@ void DecompositionSubstitutionCount::computeCounts_(double length) const
         counts_[i](j, k) /= P(j, k);
         if (isnan(counts_[i](j, k)) || counts_[i](j, k) < 0.) {
           counts_[i](j, k) = 0.;
+        //Weights:
+        if (weights_)
+          counts_[i](j, k) *= weights_->getIndex(supportedStates[j], supportedStates[k]);
         }
       }
     }
@@ -203,7 +209,7 @@ Matrix<double>* DecompositionSubstitutionCount::getAllNumbersOfSubstitutions(dou
 
 /******************************************************************************/
 
-double DecompositionSubstitutionCount::getNumberOfSubstitutions(int initialState, int finalState, double length, size_t type) const
+double DecompositionSubstitutionCount::getNumberOfSubstitutions(size_t initialState, size_t finalState, double length, size_t type) const
 {
   if (length < 0)
     throw Exception("DecompositionSubstitutionCount::getNumbersOfSubstitutions. Negative branch length: " + TextTools::toString(length) + ".");
@@ -217,7 +223,7 @@ double DecompositionSubstitutionCount::getNumberOfSubstitutions(int initialState
 
 /******************************************************************************/
 
-std::vector<double> DecompositionSubstitutionCount::getNumberOfSubstitutionsForEachType(int initialState, int finalState, double length) const
+std::vector<double> DecompositionSubstitutionCount::getNumberOfSubstitutionsForEachType(size_t initialState, size_t finalState, double length) const
 {
   if (length < 0)
     throw Exception("DecompositionSubstitutionCount::getNumbersOfSubstitutions. Negative branch length: " + TextTools::toString(length) + ".");
@@ -227,7 +233,7 @@ std::vector<double> DecompositionSubstitutionCount::getNumberOfSubstitutionsForE
     currentLength_ = length;
   }
   std::vector<double> v(getNumberOfSubstitutionTypes());
-  for (unsigned int t = 0; t < getNumberOfSubstitutionTypes(); ++t) {
+  for (size_t t = 0; t < getNumberOfSubstitutionTypes(); ++t) {
     v[t] = counts_[t](initialState, finalState);
   }
   return v;
@@ -284,7 +290,8 @@ void DecompositionSubstitutionCount::weightsHaveChanged() throw (Exception)
   if (weights_->getAlphabet()->getAlphabetType() != register_->getAlphabet()->getAlphabetType())
     throw Exception("DecompositionSubstitutionCount::weightsHaveChanged. Incorrect alphabet type.");
 
-  fillBMatrices_();
+  //jdutheil on 25/07/14: not necessary if weights are only accounted for in the end.
+  //fillBMatrices_();
   
   //Recompute counts:
   if (currentLength_ > 0)
diff --git a/src/Bpp/Phyl/Mapping/DecompositionSubstitutionCount.h b/src/Bpp/Phyl/Mapping/DecompositionSubstitutionCount.h
index 6831349..9f5b133 100644
--- a/src/Bpp/Phyl/Mapping/DecompositionSubstitutionCount.h
+++ b/src/Bpp/Phyl/Mapping/DecompositionSubstitutionCount.h
@@ -107,12 +107,12 @@ class DecompositionSubstitutionCount:
 		
     DecompositionSubstitutionCount* clone() const { return new DecompositionSubstitutionCount(*this); }
 
-	public:
-		double getNumberOfSubstitutions(int initialState, int finalState, double length, size_t type = 1) const;
+  public:
+    double getNumberOfSubstitutions(size_t initialState, size_t finalState, double length, size_t type = 1) const;
 
     Matrix<double>* getAllNumbersOfSubstitutions(double length, size_t type = 1) const;
     
-    std::vector<double> getNumberOfSubstitutionsForEachType(int initialState, int finalState, double length) const;
+    std::vector<double> getNumberOfSubstitutionsForEachType(size_t initialState, size_t finalState, double length) const;
    
     /**
      * @brief Set the substitution model.
diff --git a/src/Bpp/Phyl/Mapping/LaplaceSubstitutionCount.cpp b/src/Bpp/Phyl/Mapping/LaplaceSubstitutionCount.cpp
index beee183..cfc4619 100644
--- a/src/Bpp/Phyl/Mapping/LaplaceSubstitutionCount.cpp
+++ b/src/Bpp/Phyl/Mapping/LaplaceSubstitutionCount.cpp
@@ -64,10 +64,10 @@ void LaplaceSubstitutionCount::computeCounts(double length) const
   RowMatrix<double> M3(s, s);
   RowMatrix<double> M4(s, s);
   RowMatrix<double> M5(s, s);
-  for (int n = 1; n < cutOff_; n++)
+  for (size_t n = 1; n < cutOff_; ++n)
   {
     MatrixTools::fill(M2, 0.);
-    for (int p = 0; p < n; p++)
+    for (size_t p = 0; p < n; ++p)
     {
       MatrixTools::pow(Q, p, M3);         // Q^p -> M5
       MatrixTools::mult(M3, QL, M4);      // Q^p . QL -> M4
@@ -75,7 +75,7 @@ void LaplaceSubstitutionCount::computeCounts(double length) const
       MatrixTools::mult(M4, M3, M5);      // Q^p . QL . Q^(n-p-1) -> M5
       MatrixTools::add(M2, M5);
     }
-    MatrixTools::scale(M2, pow(length, n) / NumTools::fact(n));
+    MatrixTools::scale(M2, pow(length, static_cast<double>(n)) / static_cast<double>(NumTools::fact(n)));
     MatrixTools::add(m_, M2);
   }
 
@@ -92,7 +92,7 @@ void LaplaceSubstitutionCount::computeCounts(double length) const
 
 /******************************************************************************/
 
-double LaplaceSubstitutionCount::getNumberOfSubstitutions(int initialState, int finalState, double length, size_t type) const
+double LaplaceSubstitutionCount::getNumberOfSubstitutions(size_t initialState, size_t finalState, double length, size_t type) const
 {
   if (length == currentLength_)
     return m_(initialState, finalState);
diff --git a/src/Bpp/Phyl/Mapping/LaplaceSubstitutionCount.h b/src/Bpp/Phyl/Mapping/LaplaceSubstitutionCount.h
index e54e1d9..e386265 100644
--- a/src/Bpp/Phyl/Mapping/LaplaceSubstitutionCount.h
+++ b/src/Bpp/Phyl/Mapping/LaplaceSubstitutionCount.h
@@ -63,13 +63,13 @@ namespace bpp
   {
   private:
     const SubstitutionModel* model_;
-    int cutOff_;
+    size_t cutOff_;
     mutable double currentLength_;
     mutable RowMatrix<double> m_;
 	
   public:
-    LaplaceSubstitutionCount(const SubstitutionModel* model, int cutOff) :
-      AbstractSubstitutionCount(new TotalSubstitutionRegister(model->getAlphabet())),
+    LaplaceSubstitutionCount(const SubstitutionModel* model, size_t cutOff) :
+      AbstractSubstitutionCount(new TotalSubstitutionRegister(model)),
       model_        (model),
       cutOff_       (cutOff),
       currentLength_(-1),
@@ -99,9 +99,9 @@ namespace bpp
     LaplaceSubstitutionCount* clone() const { return new LaplaceSubstitutionCount(*this); }
 	
   public:
-    double getNumberOfSubstitutions(int initialState, int finalState, double length, size_t type = 1) const;
+    double getNumberOfSubstitutions(size_t initialState, size_t finalState, double length, size_t type = 1) const;
     Matrix<double>* getAllNumbersOfSubstitutions(double length, size_t type = 1) const;
-    std::vector<double> getNumberOfSubstitutionsForEachType(int initialState, int finalState, double length) const
+    std::vector<double> getNumberOfSubstitutionsForEachType(size_t initialState, size_t finalState, double length) const
     {
       std::vector<double> v(0);
       v[0] = getNumberOfSubstitutions(initialState, finalState, length, 0);
diff --git a/src/Bpp/Phyl/Mapping/SubstitutionMapping.h b/src/Bpp/Phyl/Mapping/Mapping.h
similarity index 52%
copy from src/Bpp/Phyl/Mapping/SubstitutionMapping.h
copy to src/Bpp/Phyl/Mapping/Mapping.h
index c983768..8198a9f 100644
--- a/src/Bpp/Phyl/Mapping/SubstitutionMapping.h
+++ b/src/Bpp/Phyl/Mapping/Mapping.h
@@ -1,50 +1,50 @@
 //
-// File: SubstitutionMapping.h
+// File: Mapping.h
 // Created by: Julien Dutheil
 // Created on: Wed Apr 5 09:51 2005
 //
 
 /*
-Copyright or © or Copr. Bio++ Development Team, (November 16, 2004, 2005, 2006)
-
-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.
+  Copyright or © or Copr. Bio++ Development Team, (November 16, 2004, 2005, 2006)
+
+  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 _SUBSTITUTIONMAPPING_H_
-#define _SUBSTITUTIONMAPPING_H_
+#ifndef _MAPPING_H_
+#define _MAPPING_H_
+
+#include <Bpp/Clonable.h>
 
 #include "../Tree.h"
 #include "../TreeTemplate.h"
 
-#include <Bpp/Clonable.h>
-
 //From the STL:
 #include <vector>
 #include <memory>
@@ -52,27 +52,20 @@ knowledge of the CeCILL license and that you accept its terms.
 namespace bpp
 {
 
-/**
- * @brief General interface for storing mapping data.
- *
- * There are several kinds of mapping:
- * - Exact mapping, storing the positions of each substitution onto each branch,
- * - Probabilistic mapping, storing the number of substitutions onto each branch.
- *
- * Since only probabilistic substitution mapping is implemented for now, the basal 
- * interface only contains a few methods.
- * More methods are expected to be added later.
- */
-class SubstitutionMapping:
-  public virtual Clonable
-{
+  /**
+   * @brief General interface for storing mapping data.
+   *
+   */
+  class Mapping:
+    public virtual Clonable
+  {
 
   public:
-    SubstitutionMapping() {}
-    virtual ~SubstitutionMapping() {}
+    Mapping() {}
+    virtual ~Mapping() {}
 
 #ifndef NO_VIRTUAL_COV
-    SubstitutionMapping* clone() const = 0;
+    Mapping* clone() const = 0;
 #endif
 
   public:
@@ -98,11 +91,6 @@ class SubstitutionMapping:
     virtual size_t getNumberOfBranches() const = 0;
     
     /**
-     * @return The number of distinct types of substitutions mapped.
-     */
-    virtual size_t getNumberOfSubstitutionTypes() const = 0;
-    
-    /**
      * @param index The site index.
      * @return The site position corresponding to the index.
      */
@@ -127,24 +115,21 @@ class SubstitutionMapping:
      * @param position The position of the site.
      */
     virtual void setSitePosition(size_t index, int position) = 0;
+  };
 
-    virtual double& operator()(size_t nodeIndex, size_t siteIndex, size_t type) = 0;
-    virtual const double& operator()(size_t nodeIndex, size_t siteIndex, size_t type) const = 0;
-};
 
 
 
 
 
-
-/**
- * @brief Partial implementation of the substitution mapping interface.
- *
- * This implementation copies the input tree in a TreeTemplate<Node> object.
- */
-class AbstractSubstitutionMapping:
-  public SubstitutionMapping
-{
+  /**
+   * @brief Partial implementation of the mapping interface.
+   *
+   * This implementation copies the input tree in a TreeTemplate<Node> object.
+   */
+  class AbstractMapping:
+    virtual public Mapping
+  {
   private:
     std::auto_ptr<const TreeTemplate<Node> > tree_;
     std::vector<int> sitesPositions_;
@@ -153,16 +138,16 @@ class AbstractSubstitutionMapping:
     size_t nbBranches_;
 
   public:
-    AbstractSubstitutionMapping() : tree_(0), sitesPositions_(), nodes_(), nbSites_(0), nbBranches_(0) {}
+    //    AbstractMapping() : tree_(0), sitesPositions_(), nodes_(), nbSites_(0), nbBranches_(0) {}
 
-    AbstractSubstitutionMapping(const Tree& tree) : tree_(new TreeTemplate<Node>(tree)), sitesPositions_(), nodes_(), nbSites_(0), nbBranches_(0)
+    AbstractMapping(const Tree& tree) : tree_(new TreeTemplate<Node>(tree)), sitesPositions_(), nodes_(), nbSites_(0), nbBranches_(0)
     {
       nodes_ = tree_->getNodes();
       nodes_.pop_back(); // remove root node.
       nbBranches_ = nodes_.size();
     }
 
-    AbstractSubstitutionMapping(const AbstractSubstitutionMapping& absm):
+    AbstractMapping(const AbstractMapping& absm):
       tree_(dynamic_cast<const TreeTemplate<Node>*>(absm.tree_->clone())),
       sitesPositions_(absm.sitesPositions_),
       nodes_(),
@@ -173,7 +158,7 @@ class AbstractSubstitutionMapping:
       nodes_.pop_back(); // remove root node.
     }
 
-    AbstractSubstitutionMapping& operator=(const AbstractSubstitutionMapping& absm)
+    AbstractMapping& operator=(const AbstractMapping& absm)
     {
       tree_.reset(dynamic_cast<const TreeTemplate<Node>*>(absm.tree_->clone()));
       sitesPositions_ = absm.sitesPositions_;
@@ -184,18 +169,22 @@ class AbstractSubstitutionMapping:
       return *this;
     }
 
-    virtual ~AbstractSubstitutionMapping() {}
-
+#ifndef NO_VIRTUAL_COV
+    AbstractMapping* clone() const = 0;
+#endif
+  
+    virtual ~AbstractMapping() {}
+  
   public:
-
+  
     bool isEmpty() const { return tree_.get() == 0; }
 
-		const	TreeTemplate<Node>& getTree() const throw (Exception)
+    const TreeTemplate<Node>& getTree() const throw (Exception)
     {
       if (isEmpty()) throw Exception("AbstractSubstitutionMapping::getSitePosition. No tree is assigned to this map yet.");
       return *tree_.get();
     }
-
+  
     void setTree(const Tree& tree)
     {
       tree_.reset(new TreeTemplate<Node>(tree));
@@ -206,13 +195,13 @@ class AbstractSubstitutionMapping:
  
     int getSitePosition(size_t index) const throw (Exception)
     {
-      if (isEmpty()) throw Exception("AbstractSubstitutionMapping::getSitePosition. No tree is assigned to this map yet.");
+      if (isEmpty()) throw Exception("AbstractMapping::getSitePosition. No tree is assigned to this map yet.");
       return sitesPositions_[index];
     }
     
     void setSitePosition(size_t index, int position) throw (Exception)
     {
-      if (isEmpty()) throw Exception("AbstractSubstitutionMapping::setSitePosition. No tree is assigned to this map yet.");
+      if (isEmpty()) throw Exception("AbstractMapping::setSitePosition. No tree is assigned to this map yet.");
       sitesPositions_[index] = position;
     }
 		
@@ -242,13 +231,13 @@ class AbstractSubstitutionMapping:
     {
       for (size_t i = 0; i < nbBranches_; i++)
         if(nodes_[i]->getId() == nodeId) return i;
-      throw NodeNotFoundException("ProbabilisticSubstitutionMapping::getNodeIndex(nodeId).", TextTools::toString(nodeId));
+      throw NodeNotFoundException("AbstractMapping::getNodeIndex(nodeId).", TextTools::toString(nodeId));
     }
 
 
-};
+  };
 
 } //end of namespace bpp.
 
-#endif //_SUBSTITUTIONMAPPING_H_
+#endif //_MAPPING_H_
 
diff --git a/src/Bpp/Phyl/Mapping/NaiveSubstitutionCount.cpp b/src/Bpp/Phyl/Mapping/NaiveSubstitutionCount.cpp
index d22750c..29e3283 100644
--- a/src/Bpp/Phyl/Mapping/NaiveSubstitutionCount.cpp
+++ b/src/Bpp/Phyl/Mapping/NaiveSubstitutionCount.cpp
@@ -43,25 +43,28 @@ using namespace bpp;
 
 Matrix<double>* NaiveSubstitutionCount::getAllNumbersOfSubstitutions(double length, size_t type) const
 { 
-  int n = static_cast<int>(register_->getAlphabet()->getSize()); //Note jdutheil 20/01/13: shoudl be generalized in case sattes are not 0:n !
+  size_t n = supportedChars_.size();
   RowMatrix<double>* mat = new RowMatrix<double>(n, n);
-  for (int i = 0; i < n; ++i)
+  for (size_t i = 0; i < n; ++i)
   {
-    for (int j = 0; j < n; ++j)
+    for (size_t j = 0; j < n; ++j)
     {
-      (*mat)(i, j) = (register_->getType(i, j) == type ? (weights_ ? weights_->getIndex(i, j) : 1.) : 0.);
+      (*mat)(i, j) = (register_->getType(i, j) == type ? (weights_ ? weights_->getIndex(supportedChars_[i], supportedChars_[j]) : 1.) : 0.);
     }
   }
   return mat;
 }
 
-LabelSubstitutionCount::LabelSubstitutionCount(const Alphabet* alphabet) :
-  AbstractSubstitutionCount(new TotalSubstitutionRegister(alphabet)), label_(alphabet->getSize(), alphabet->getSize())
+LabelSubstitutionCount::LabelSubstitutionCount(const SubstitutionModel* model) :
+  AbstractSubstitutionCount(
+      new TotalSubstitutionRegister(model)),
+  label_(model->getNumberOfStates(), model->getNumberOfStates()),
+  supportedChars_(model->getAlphabetStates())
 {
-  int n = static_cast<int>(register_->getAlphabet()->getSize()); //Note jdutheil 20/01/13: shoudl be generalized in case sattes are not 0:n !
+  size_t n = supportedChars_.size();
   double count = 0;
-  for (int i = 0; i < n; ++i) {
-    for (int j = 0; j < n; ++j) {
+  for (size_t i = 0; i < n; ++i) {
+    for (size_t j = 0; j < n; ++j) {
       if (i == j) label_(i, j) = 0;
       else label_(i, j) = ++count;
     }
diff --git a/src/Bpp/Phyl/Mapping/NaiveSubstitutionCount.h b/src/Bpp/Phyl/Mapping/NaiveSubstitutionCount.h
index e258655..d8d1fba 100644
--- a/src/Bpp/Phyl/Mapping/NaiveSubstitutionCount.h
+++ b/src/Bpp/Phyl/Mapping/NaiveSubstitutionCount.h
@@ -67,37 +67,44 @@ namespace bpp
   {
   private:
     bool allowSelf_;
+    std::vector<int> supportedChars_;
 
   public:
     /**
      * @brief Build a new simple substitution count.
      *
+     * @param model The substitution model for which this substitution count is parametrized.
+     *              The model is not used in the calculation, only for specifying the modeled states.
      * @param reg A pointer toward a substitution register object which discribes the type of substitutions to map.
      * @param allowSelf Tells if "self" mutations, from X to X should be counted together with the ones of type X to Y where X and Y are in the same category, if relevent.
      * The default is "no", to be consistent with other types of substitution counts which account for multiple substitutions, in which case it does not make sense to count "X to X".
      * @param weights the weights of the counts
      */
-    NaiveSubstitutionCount(SubstitutionRegister* reg, bool allowSelf = false, const AlphabetIndex2* weights = 0) :
+    NaiveSubstitutionCount(const SubstitutionModel* model, SubstitutionRegister* reg, bool allowSelf = false, const AlphabetIndex2* weights = 0) :
       AbstractSubstitutionCount(reg),
       AbstractWeightedSubstitutionCount(weights, true),
-      allowSelf_(allowSelf) {}				
+      allowSelf_(allowSelf),
+      supportedChars_(model->getAlphabetStates()) {}				
 		
     virtual ~NaiveSubstitutionCount() {}
 	
     NaiveSubstitutionCount* clone() const { return new NaiveSubstitutionCount(*this); }
 
   public:
-    double getNumberOfSubstitutions(int initialState, int finalState, double length, size_t type = 1) const
+    double getNumberOfSubstitutions(size_t initialState, size_t finalState, double length, size_t type = 1) const
     {
       if (initialState == finalState && !allowSelf_)
         return 0;
-      else
-        return (register_->getType(initialState, finalState) == type ? (weights_ ? weights_->getIndex(initialState, finalState) : 1.) : 0.);
+      else {
+        int alphabetState1 = supportedChars_[initialState]; 
+        int alphabetState2 = supportedChars_[finalState]; 
+        return (register_->getType(initialState, finalState) == type ? (weights_ ? weights_->getIndex(alphabetState1, alphabetState2) : 1.) : 0.);
+      }
     }
 
     Matrix<double>* getAllNumbersOfSubstitutions(double length, size_t type = 1) const;
     
-    std::vector<double> getNumberOfSubstitutionsForEachType(int initialState, int finalState, double length) const
+    std::vector<double> getNumberOfSubstitutionsForEachType(size_t initialState, size_t finalState, double length) const
     {
       std::vector<double> v(getNumberOfSubstitutionTypes());
       for (size_t t = 1; t <= getNumberOfSubstitutionTypes(); ++t) {
@@ -106,7 +113,10 @@ namespace bpp
       return v;
     }
     
-    void setSubstitutionModel(const SubstitutionModel* model) {}
+    void setSubstitutionModel(const SubstitutionModel* model)
+    {
+      supportedChars_ = model->getAlphabetStates();
+    }
 
   private:
     void substitutionRegisterHasChanged() {}
@@ -126,16 +136,17 @@ namespace bpp
   {
   private:
     LinearMatrix<double> label_;
+    std::vector<int> supportedChars_;
     
   public:
-    LabelSubstitutionCount(const Alphabet* alphabet);
+    LabelSubstitutionCount(const SubstitutionModel* model);
 
     virtual ~LabelSubstitutionCount() {}
 
     LabelSubstitutionCount* clone() const { return new LabelSubstitutionCount(*this); }
 			
   public:
-    double getNumberOfSubstitutions(int initialState, int finalState, double length, size_t type = 1) const
+    double getNumberOfSubstitutions(size_t initialState, size_t finalState, double length, size_t type = 1) const
     {
       return label_(initialState, finalState);
     }
@@ -145,14 +156,17 @@ namespace bpp
       return dynamic_cast<Matrix<double>*>(label_.clone());
     }
     
-    std::vector<double> getNumberOfSubstitutionsForEachType(int initialState, int finalState, double length) const
+    std::vector<double> getNumberOfSubstitutionsForEachType(size_t initialState, size_t finalState, double length) const
     {
       std::vector<double> v(1);
       v[0] = label_(initialState, finalState);
       return v;
     }
 
-    void setSubstitutionModel(const SubstitutionModel* model) {}
+    void setSubstitutionModel(const SubstitutionModel* model)
+    {
+      supportedChars_ = model->getAlphabetStates();
+    }
 
     void setSubstitutionRegister(SubstitutionRegister* reg) throw (Exception) {
       throw Exception("OneJumpSubstitutionCount::setSubstitutionRegister. This SubstitutionsCount only works with a TotalSubstitutionRegister.");
diff --git a/src/Bpp/Phyl/Mapping/OneJumpSubstitutionCount.h b/src/Bpp/Phyl/Mapping/OneJumpSubstitutionCount.h
index 2af4c42..dc4ae69 100644
--- a/src/Bpp/Phyl/Mapping/OneJumpSubstitutionCount.h
+++ b/src/Bpp/Phyl/Mapping/OneJumpSubstitutionCount.h
@@ -59,19 +59,19 @@ namespace bpp
 class OneJumpSubstitutionCount:
   public AbstractSubstitutionCount
 {
-	private:
-		const SubstitutionModel* model_;
-		mutable RowMatrix<double> tmp_;
-	
-	public:
-		OneJumpSubstitutionCount(const SubstitutionModel* model) :
-      AbstractSubstitutionCount(new TotalSubstitutionRegister(model->getAlphabet())),
+  private:
+    const SubstitutionModel* model_;
+    mutable RowMatrix<double> tmp_;
+  
+  public:
+    OneJumpSubstitutionCount(const SubstitutionModel* model) :
+      AbstractSubstitutionCount(new TotalSubstitutionRegister(model)),
       model_(model), tmp_() {}
-		
+    
     OneJumpSubstitutionCount(const OneJumpSubstitutionCount& ojsc) :
       AbstractSubstitutionCount(ojsc),
       model_(ojsc.model_), tmp_(ojsc.tmp_) {}
-				
+        
     OneJumpSubstitutionCount& operator=(const OneJumpSubstitutionCount& ojsc)
     {
       AbstractSubstitutionCount::operator=(ojsc),
@@ -79,13 +79,13 @@ class OneJumpSubstitutionCount:
       tmp_      = ojsc.tmp_;
       return *this;
     }
-				
-		virtual ~OneJumpSubstitutionCount() {}
-		
+        
+    virtual ~OneJumpSubstitutionCount() {}
+    
     virtual OneJumpSubstitutionCount* clone() const { return new OneJumpSubstitutionCount(*this); }
 
-	public:
-		double getNumberOfSubstitutions(int initialState, int finalState, double length, size_t type = 1) const
+  public:
+    double getNumberOfSubstitutions(size_t initialState, size_t finalState, double length, size_t type = 1) const
     {
       if (finalState != initialState) return 1.;
       else return 1. - model_->Pij_t(initialState, finalState, length);
@@ -93,7 +93,7 @@ class OneJumpSubstitutionCount:
 
     Matrix<double>* getAllNumbersOfSubstitutions(double length, size_t type = 1) const;
     
-    std::vector<double> getNumberOfSubstitutionsForEachType(int initialState, int finalState, double length) const
+    std::vector<double> getNumberOfSubstitutionsForEachType(size_t initialState, size_t finalState, double length) const
     {
       std::vector<double> v(0);
       v[0] = getNumberOfSubstitutions(initialState, finalState, length, 0);
diff --git a/src/Bpp/Phyl/Model/Nucleotide/NucleotideSubstitutionModel.h b/src/Bpp/Phyl/Mapping/ProbabilisticRewardMapping.cpp
old mode 100755
new mode 100644
similarity index 68%
copy from src/Bpp/Phyl/Model/Nucleotide/NucleotideSubstitutionModel.h
copy to src/Bpp/Phyl/Mapping/ProbabilisticRewardMapping.cpp
index 0862fa8..984a7bb
--- a/src/Bpp/Phyl/Model/Nucleotide/NucleotideSubstitutionModel.h
+++ b/src/Bpp/Phyl/Mapping/ProbabilisticRewardMapping.cpp
@@ -1,11 +1,11 @@
 //
-// File: NucleicSubstitutionModel.h
-// Created by: Julien Dutheil
-// Created on: Tue May 27 11:03:53 2003
+// File: ProbabilisticRewardMapping.cpp
+// Created by: Laurent Guéguen
+// Created on: vendredi 29 mars 2013, à 11h 37
 //
 
 /*
-Copyright or © or Copr. Bio++ Development Team, (November 16, 2004)
+Copyright or © or Copr. Bio++ Development Team, (November 16, 2004, 2005, 2006)
 
 This software is a computer program whose purpose is to provide classes
 for phylogenetic data analysis.
@@ -37,39 +37,23 @@ 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 _NUCLEICSUBSTITUTIONMODEL_H_
-#define _NUCLEICSUBSTITUTIONMODEL_H_
+#include "ProbabilisticRewardMapping.h"
 
-#include "../SubstitutionModel.h"
+using namespace bpp;
 
-// From SeqLib:
-#include <Bpp/Seq/Alphabet/NucleicAlphabet.h>
-
-namespace bpp
+void ProbabilisticRewardMapping::setTree(const Tree& tree)
 {
+  AbstractRewardMapping::setTree(tree);
+  for (size_t i = 0; i < getNumberOfSites(); i++) 
+    mapping_[i].resize(getNumberOfBranches());
+}
 
-/**
- * @brief Specialisation interface for nucleotide substitution model.
- */
-class NucleotideSubstitutionModel :
-  public virtual SubstitutionModel
+void ProbabilisticRewardMapping::setNumberOfSites(size_t numberOfSites)
 {
-	public:
-		virtual ~NucleotideSubstitutionModel() {}
-
-#ifndef NO_VIRTUAL_COV
-    NucleotideSubstitutionModel*
-#else
-    Clonable*
-#endif
-    clone() const = 0;
-
-  public:
-    virtual size_t getNumberOfStates() const { return 4; }
-
-};
-
-} //end of namespace bpp.
-
-#endif	//_NUCLEICSUBSTITUTIONMODEL_H_
-
+  AbstractRewardMapping::setNumberOfSites(numberOfSites);
+  mapping_.resize(numberOfSites);
+  for (size_t i = 0; i < numberOfSites; i++) {
+    mapping_[i].resize(getNumberOfBranches());
+  }
+}
+ 
diff --git a/src/Bpp/Phyl/Mapping/ProbabilisticRewardMapping.h b/src/Bpp/Phyl/Mapping/ProbabilisticRewardMapping.h
new file mode 100644
index 0000000..4255bf8
--- /dev/null
+++ b/src/Bpp/Phyl/Mapping/ProbabilisticRewardMapping.h
@@ -0,0 +1,177 @@
+//
+// File: ProbabilisticRewardMapping.h
+// Created by: Laurent Guéguen
+// Created on: mercredi 27 mars 2013, à 15h 20
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 16, 2004, 2005, 2006)
+
+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 _PROBABILISTICREWARDMAPPING_H_
+#define _PROBABILISTICREWARDMAPPING_H_
+
+#include "RewardMapping.h"
+#include "Reward.h"
+#include "../TreeExceptions.h"
+
+#include <Bpp/Text/TextTools.h>
+
+// From the STL:
+#include <vector>
+
+namespace bpp
+{
+
+/**
+ * @brief Data storage class for probabilistic rewards mappings.
+ *
+ * A 'probabilistic' mapping contains an single value for each branch and each site.
+ * This number is an average reward.
+ * Probabilistic was coined there by opposition to the'stochastic'
+ * mapping, where a path (sequence of rewards along the branch) is
+ * available for each branch and site.
+ */
+  class ProbabilisticRewardMapping:
+    public AbstractRewardMapping
+  {
+  private:
+    const Reward* reward_;
+    /**
+     * @brief Rewards storage.
+     *
+     * Rewards are stored by sites.
+     */
+    std::vector< std::vector<double> > mapping_;
+    
+  public:
+    
+    /**
+     * @brief Build a new ProbabilisticRewardMapping object.
+     *
+     * @param tree The tree object to use. It will be cloned for internal use.
+     * @param reward A pointer toward the Reward object that has been used for the mapping, if any.
+     * @param numberOfSites The number of sites to map.
+     */
+    ProbabilisticRewardMapping(const Tree& tree, const Reward* reward, size_t numberOfSites) :
+      AbstractMapping(tree), AbstractRewardMapping(tree), reward_(reward), mapping_(0)
+    {
+      setNumberOfSites(numberOfSites);
+    }
+    
+    /**
+     * @brief Build a new ProbabilisticRewardMapping object.
+     *
+     * @param tree The tree object to use. It will be cloned for internal use.
+     */
+    ProbabilisticRewardMapping(const Tree& tree) :
+    AbstractMapping(tree), AbstractRewardMapping(tree), reward_(0), mapping_(0)
+    {}
+    
+
+    ProbabilisticRewardMapping* clone() const { return new ProbabilisticRewardMapping(*this); }
+
+    ProbabilisticRewardMapping(const ProbabilisticRewardMapping& prm):
+    AbstractMapping(prm), AbstractRewardMapping(prm), reward_(prm.reward_), mapping_(prm.mapping_)
+    {}
+
+    ProbabilisticRewardMapping& operator=(const ProbabilisticRewardMapping& prm)
+    {
+      AbstractRewardMapping::operator=(prm);
+      reward_  = prm.reward_;
+      mapping_ = prm.mapping_;
+      return *this;
+    }
+
+    virtual ~ProbabilisticRewardMapping() {}
+
+  public:
+
+    virtual double getReward(int nodeId, size_t siteIndex) const
+    {
+      return mapping_[siteIndex][getNodeIndex(nodeId)];
+    }
+    
+    /**
+     * @brief (Re)-set the phylogenetic tree associated to this mapping.
+     *
+     * @param tree The new tree.
+     */
+    virtual void setTree(const Tree& tree);
+
+    virtual void setNumberOfSites(size_t numberOfSites);
+    
+    /**
+     * @brief Direct access to rewards.
+     *
+     * @warning No index checking is performed, use with care!
+     */
+    virtual double& operator()(size_t nodeIndex, size_t siteIndex)
+    {
+      return mapping_[siteIndex][nodeIndex];
+    }
+
+    /**
+     * @brief Direct access to rewards.
+     *
+     * @warning No index checking is performed, use with care!
+     */
+    virtual const double& operator()(size_t nodeIndex, size_t siteIndex) const
+    {
+      return mapping_[siteIndex][nodeIndex];
+    }
+     
+    /**
+     * @brief Direct access to rewards.
+     *
+     * @warning No index checking is performed, use with care!
+     */
+    std::vector<double>& operator[](size_t siteIndex)
+    {
+      return mapping_[siteIndex];
+    }
+
+    /**
+     * @brief Direct access to rewards.
+     *
+     * @warning No index checking is performed, use with care!
+     */
+    const std::vector<double>& operator[](size_t siteIndex) const
+    {
+      return mapping_[siteIndex];
+    }
+};
+
+} //end of namespace bpp.
+
+#endif //_PROBABILISTICREWARDMAPPING_H_
+
diff --git a/src/Bpp/Phyl/Mapping/ProbabilisticSubstitutionMapping.h b/src/Bpp/Phyl/Mapping/ProbabilisticSubstitutionMapping.h
index 94b85c3..58f9e46 100644
--- a/src/Bpp/Phyl/Mapping/ProbabilisticSubstitutionMapping.h
+++ b/src/Bpp/Phyl/Mapping/ProbabilisticSubstitutionMapping.h
@@ -84,7 +84,7 @@ class ProbabilisticSubstitutionMapping:
      * @param numberOfSites The number of sites to map.
      */
     ProbabilisticSubstitutionMapping(const Tree& tree, const SubstitutionCount* sc, size_t numberOfSites) :
-      AbstractSubstitutionMapping(tree), substitutionCount_(sc), mapping_(0)
+      AbstractMapping(tree), AbstractSubstitutionMapping(tree), substitutionCount_(sc), mapping_(0)
     {
       setNumberOfSites(numberOfSites);
     }
@@ -95,14 +95,14 @@ class ProbabilisticSubstitutionMapping:
      * @param tree The tree object to use. It will be cloned for internal use.
      */
     ProbabilisticSubstitutionMapping(const Tree& tree) :
-      AbstractSubstitutionMapping(tree), substitutionCount_(0), mapping_(0)
+    AbstractMapping(tree), AbstractSubstitutionMapping(tree), substitutionCount_(0), mapping_(0)
     {}
     
 
     ProbabilisticSubstitutionMapping* clone() const { return new ProbabilisticSubstitutionMapping(*this); }
 
     ProbabilisticSubstitutionMapping(const ProbabilisticSubstitutionMapping& psm):
-      AbstractSubstitutionMapping(psm), substitutionCount_(psm.substitutionCount_), mapping_(psm.mapping_)
+    AbstractMapping(psm), AbstractSubstitutionMapping(psm), substitutionCount_(psm.substitutionCount_), mapping_(psm.mapping_)
     {}
 
     ProbabilisticSubstitutionMapping& operator=(const ProbabilisticSubstitutionMapping& psm)
diff --git a/src/Bpp/Phyl/Mapping/Reward.h b/src/Bpp/Phyl/Mapping/Reward.h
new file mode 100644
index 0000000..91b863e
--- /dev/null
+++ b/src/Bpp/Phyl/Mapping/Reward.h
@@ -0,0 +1,205 @@
+//
+// File: Reward.h
+// Created by: Laurent Guéguen
+// Created on: mercredi 27 mars 2013, à 09h 58
+//
+
+/*
+  Copyright or © or Copr. Bio++ Development Team, (November 16, 2004, 2005, 2006)
+
+  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 _REWARD_H_
+#define _REWARD_H_
+
+#include "../Model/SubstitutionModel.h"
+
+#include <Bpp/Numeric/Matrix/Matrix.h>
+#include <Bpp/Seq/AlphabetIndex/AlphabetIndex1.h>
+
+//From the STL:
+#include <vector>
+
+namespace bpp
+{
+
+  /**
+   * @brief The Reward interface.
+   *
+   * Provide a method to compute the reward of a real-valued function
+   * @f$f at f$ of the states on a branch. Namely, on a branch of length
+   * @f$t at f$, with initial state @f$x at f$ and final state @f$y at f$, if
+   * @f$t_s at f$ is the time spent in each state @f$s at f$, the reward of
+   * @f$f at f$ is @f$\sum_{s} f(s).E(t_s) @f$.
+   * 
+   * @author Laurent Guéguen
+   *
+   * See:
+   * Minin, V.N. and Suchard, M.A., 
+   * Fast, accurate and simulation-free stochastic mapping
+   * Philosophical Transactions of the Royal Society B 2008 363:3985-95.
+   */
+  class Reward:
+    public virtual Clonable
+  {
+  public:
+    Reward() {}
+    virtual ~Reward() {}
+    virtual Reward* clone() const = 0;
+	
+  public:
+    /**
+     * @return Tell if an alphabet index  has been attached to this class.
+     */
+    virtual bool hasAlphabetIndex() const = 0;
+
+    /**
+     * @return The AlphabetIndex1 object associated to this instance.
+     * The alphabet index contains the value associated to each state.
+     */
+    virtual const AlphabetIndex1* getAlphabetIndex() const = 0;
+
+    /**
+     * @return The AlphabetIndex1 object associated to this instance.
+     * The alphabet index contains the value associated to each state.
+     */
+    
+    virtual AlphabetIndex1* getAlphabetIndex() = 0;
+
+    /**
+     * @param alphind The new AlphabetIndex1 object to be associated to this instance.
+     */
+    
+    virtual void setAlphabetIndex(AlphabetIndex1* alphind) = 0;
+
+    /**
+     * @brief Short cut function, equivalent to getSubstitutionRegister()->getAlphabet().
+     *
+     * @return The alphabet associated to this substitution count.
+     */
+    virtual const Alphabet* getAlphabet() const { return getAlphabetIndex()->getAlphabet(); }
+
+    /**
+     * @brief Short cut function, equivalent to getSubstitutionRegister()->getAlphabet()->getSize().
+     *
+     * @return The number of states in the model/alphabet.
+     */
+    virtual size_t getNumberOfStates() const { return getAlphabet()->getSize(); }
+
+
+    /**
+     * @brief Get the reward of susbstitutions on a branch, given the initial and final states, and the branch length.
+     *
+     * @param initialState The initial state.
+     * @param finalState   The final state.
+     * @param length       The length of the branch.
+     * @return The reward of the function on a branch of specified length and
+     * according to initial and final states.
+     */
+    virtual double getReward(size_t initialState, size_t finalState, double length) const = 0;
+		
+    /**
+     * @brief Get the rewards on a branch, for each initial and final
+     * states, and given the branch length.
+     *
+     * @param length       The length of the branch.
+     * @return A matrix with all rewards for each initial and final states.
+     */
+    virtual Matrix<double>* getAllRewards(double length) const = 0;
+
+    /**
+     * @brief Set the substitution model associated with this reward, if relevant.
+     *
+     * @param model The substitution model to use with this reward.
+     */
+    virtual void setSubstitutionModel(const SubstitutionModel* model) = 0;
+  };
+
+  /**
+   * @brief Basic implementation of the the Reward interface.
+   *
+   * This partial implementation deals with the AlphabetIndex1 gestion, by maintaining a pointer.
+   */
+  class AbstractReward:
+    public virtual Reward
+  {
+  protected:
+    AlphabetIndex1* alphIndex_;
+
+  public:
+    AbstractReward(AlphabetIndex1* alphIndex):
+      alphIndex_(alphIndex)
+    {}
+
+    AbstractReward(const AbstractReward& ar):
+      alphIndex_(ar.alphIndex_)//dynamic_cast<AlphabetIndex1*>(ar.alphIndex_->clone()))
+    {}
+
+    AbstractReward& operator=(const AbstractReward& ar) {
+      // if (alphIndex_)
+      //   delete alphIndex_;
+      alphIndex_ = ar.alphIndex_; //dynamic_cast<AlphabetIndex1*>(ar.alphIndex_->clone());
+      return *this;
+    }
+
+    ~AbstractReward() {
+      // if (alphIndex_)
+      //   delete alphIndex_;
+    }
+
+  public:
+    bool hasAlphabetIndex() const { return (alphIndex_ != 0); }
+
+    /*
+     *@brief attribution of an AlphabetIndex1
+     *
+     *@param alphIndex pointer to a AlphabetIndex1
+     *
+     */
+    
+    void setAlphabetIndex(AlphabetIndex1* alphIndex) {
+//      if (alphIndex_) delete alphIndex_;
+      alphIndex_ = alphIndex;
+      alphabetIndexHasChanged();
+    }
+
+    const AlphabetIndex1* getAlphabetIndex() const { return alphIndex_; }
+    
+    AlphabetIndex1* getAlphabetIndex() { return alphIndex_; }
+
+  protected:
+    virtual void alphabetIndexHasChanged() = 0;
+  };
+
+} //end of namespace bpp.
+
+#endif //_REWARD_H_
+
diff --git a/src/Bpp/Phyl/Simulation/SequenceSimulator.h b/src/Bpp/Phyl/Mapping/RewardMapping.h
old mode 100755
new mode 100644
similarity index 52%
copy from src/Bpp/Phyl/Simulation/SequenceSimulator.h
copy to src/Bpp/Phyl/Mapping/RewardMapping.h
index 599c3db..f61e681
--- a/src/Bpp/Phyl/Simulation/SequenceSimulator.h
+++ b/src/Bpp/Phyl/Mapping/RewardMapping.h
@@ -1,11 +1,11 @@
 //
-// File: SequenceSimulator.h
-// Created by: Julien Dutheil
-// Created on: Wed Feb  4 16:30:51 2004
+// File: RewardMapping.h
+// Created by: Laurent Guéguen
+// Created on: vendredi 29 mars 2013, à 11h 32
 //
 
 /*
-Copyright or © or Copr. Bio++ Development Team, (November 16, 2004)
+Copyright or © or Copr. Bio++ Development Team, (November 16, 2004, 2005, 2006)
 
 This software is a computer program whose purpose is to provide classes
 for phylogenetic data analysis.
@@ -37,38 +37,80 @@ 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 _SEQUENCESIMULATOR_H_
-#define _SEQUENCESIMULATOR_H_
+#ifndef _REWARDMAPPING_H_
+#define _REWARDMAPPING_H_
+
+#include "Mapping.h"
 
 #include <Bpp/Clonable.h>
 
-// From SeqLib:
-#include <Bpp/Seq/Container/SiteContainer.h>
+//From the STL:
+#include <vector>
+#include <memory>
 
 namespace bpp
 {
 
 /**
- * @brief The SequenceSimulator interface.
- * SequenceSimulator classes can simulate whole datasets.
+ * @brief General interface for storing reward mapping data.
+ *
+ * Since only probabilistic reward mapping is implemented for now, the basal 
+ * interface only contains a few methods.
+ * More methods are expected to be added later.
  */
-class SequenceSimulator:
-  public virtual Clonable
-{
+  
+  class RewardMapping:
+    virtual public Mapping
+  {
+    
   public:
-    SequenceSimulator() {}
-    virtual ~SequenceSimulator() {}
+    RewardMapping() {}
+    virtual ~RewardMapping() {}
 
 #ifndef NO_VIRTUAL_COV
-    SequenceSimulator * clone() const = 0;
+    RewardMapping* clone() const = 0;
 #endif
-  
+
   public:
-    virtual SiteContainer * simulate(size_t numberOfSites) const = 0;
-    virtual const Alphabet * getAlphabet() const = 0;  
+    
+    virtual double& operator()(size_t nodeIndex, size_t siteIndex) = 0;
+    virtual const double& operator()(size_t nodeIndex, size_t siteIndex) const = 0;
+};
+
+
+
+/**
+ * @brief Partial implementation of the reward mapping interface.
+ *
+ * This implementation copies the input tree in a TreeTemplate<Node> object.
+ */
+class AbstractRewardMapping:
+    virtual public RewardMapping,
+    virtual public AbstractMapping
+{
+public:
+  //  AbstractRewardMapping() : AbstractMapping(){}
+
+  AbstractRewardMapping(const Tree& tree) : AbstractMapping(tree){}
+
+  AbstractRewardMapping(const AbstractRewardMapping& arm):
+    AbstractMapping(arm) {}
+
+#ifndef NO_VIRTUAL_COV
+  AbstractRewardMapping* clone() const = 0;
+#endif
+
+  AbstractRewardMapping& operator=(const AbstractRewardMapping& arm)
+    {
+      AbstractMapping::operator=(arm);
+      return *this;
+    }
+
+  virtual ~AbstractRewardMapping() {}
+
 };
 
 } //end of namespace bpp.
 
-#endif  //_SEQUENCESIMULATOR_H_
+#endif //_REWARDMAPPING_H_
 
diff --git a/src/Bpp/Phyl/Mapping/RewardMappingTools.cpp b/src/Bpp/Phyl/Mapping/RewardMappingTools.cpp
new file mode 100644
index 0000000..e574b07
--- /dev/null
+++ b/src/Bpp/Phyl/Mapping/RewardMappingTools.cpp
@@ -0,0 +1,447 @@
+//
+// File: RewardMappingTools.cpp
+// Created by: Laurent Guéguen
+// Created on: vendredi 29 mars 2013, à 15h 01
+//
+
+/*
+   Copyright or © or Copr. Bio++ Development Team, (November 16, 2004, 2005, 2006)
+
+   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 "RewardMappingTools.h"
+#include "../Likelihood/DRTreeLikelihoodTools.h"
+#include "../Likelihood/MarginalAncestralStateReconstruction.h"
+
+#include <Bpp/Text/TextTools.h>
+#include <Bpp/App/ApplicationTools.h>
+#include <Bpp/Numeric/Matrix/MatrixTools.h>
+#include <Bpp/Numeric/DataTable.h>
+
+using namespace bpp;
+
+// From the STL:
+#include <iomanip>
+
+using namespace std;
+
+/******************************************************************************/
+
+ProbabilisticRewardMapping* RewardMappingTools::computeRewardVectors(
+  const DRTreeLikelihood& drtl,
+  const vector<int>& nodeIds,
+  Reward& reward,
+  bool verbose) throw (Exception)
+{
+  // Preamble:
+  if (!drtl.isInitialized())
+    throw Exception("RewardMappingTools::computeRewardVectors(). Likelihood object is not initialized.");
+
+  // A few variables we'll need:
+
+  const TreeTemplate<Node> tree(drtl.getTree());
+  const SiteContainer*    sequences = drtl.getData();
+  const DiscreteDistribution* rDist = drtl.getRateDistribution();
+
+  size_t nbSites         = sequences->getNumberOfSites();
+  size_t nbDistinctSites = drtl.getLikelihoodData()->getNumberOfDistinctSites();
+  size_t nbStates        = sequences->getAlphabet()->getSize();
+  size_t nbClasses       = rDist->getNumberOfCategories();
+  vector<const Node*> nodes    = tree.getNodes();
+  const vector<size_t>* rootPatternLinks
+    = &drtl.getLikelihoodData()->getRootArrayPositions();
+  nodes.pop_back(); // Remove root node.
+  size_t nbNodes         = nodes.size();
+
+  // We create a new ProbabilisticRewardMapping object:
+  ProbabilisticRewardMapping* rewards = new ProbabilisticRewardMapping(tree, &reward, nbSites);
+
+  // Store likelihood for each rate for each site:
+  VVVdouble lik;
+  drtl.computeLikelihoodAtNode(tree.getRootId(), lik);
+  Vdouble Lr(nbDistinctSites, 0);
+  Vdouble rcProbs = rDist->getProbabilities();
+  Vdouble rcRates = rDist->getCategories();
+  for (size_t i = 0; i < nbDistinctSites; i++)
+  {
+    VVdouble* lik_i = &lik[i];
+    for (size_t c = 0; c < nbClasses; c++)
+    {
+      Vdouble* lik_i_c = &(*lik_i)[c];
+      double rc = rDist->getProbability(c);
+      for (size_t s = 0; s < nbStates; s++)
+      {
+        Lr[i] += (*lik_i_c)[s] * rc;
+      }
+    }
+  }
+
+  // Compute the reward for each class and each branch in the tree:
+  if (verbose)
+    ApplicationTools::displayTask("Compute joint node-pairs likelihood", true);
+
+  for (size_t l = 0; l < nbNodes; ++l)
+  {
+    // For each node,
+    const Node* currentNode = nodes[l];
+    if (nodeIds.size() > 0 && !VectorTools::contains(nodeIds, currentNode->getId()))
+      continue;
+
+    const Node* father = currentNode->getFather();
+
+    double d = currentNode->getDistanceToFather();
+
+    if (verbose)
+      ApplicationTools::displayGauge(l, nbNodes - 1);
+    Vdouble rewardsForCurrentNode(nbDistinctSites);
+
+    // Now we've got to compute likelihoods in a smart manner... ;)
+    VVVdouble likelihoodsFatherConstantPart(nbDistinctSites);
+    for (size_t i = 0; i < nbDistinctSites; i++)
+    {
+      VVdouble* likelihoodsFatherConstantPart_i = &likelihoodsFatherConstantPart[i];
+      likelihoodsFatherConstantPart_i->resize(nbClasses);
+      for (size_t c = 0; c < nbClasses; c++)
+      {
+        Vdouble* likelihoodsFatherConstantPart_i_c = &(*likelihoodsFatherConstantPart_i)[c];
+        likelihoodsFatherConstantPart_i_c->resize(nbStates);
+        double rc = rDist->getProbability(c);
+        for (size_t s = 0; s < nbStates; s++)
+        {
+          // (* likelihoodsFatherConstantPart_i_c)[s] = rc * model->freq(s);
+          // freq is already accounted in the array
+          (*likelihoodsFatherConstantPart_i_c)[s] = rc;
+        }
+      }
+    }
+
+    // First, what will remain constant:
+    size_t nbSons =  father->getNumberOfSons();
+    for (size_t n = 0; n < nbSons; n++)
+    {
+      const Node* currentSon = father->getSon(n);
+      if (currentSon->getId() != currentNode->getId())
+      {
+        const VVVdouble* likelihoodsFather_son = &drtl.getLikelihoodData()->getLikelihoodArray(father->getId(), currentSon->getId());
+
+        // Now iterate over all site partitions:
+        auto_ptr<TreeLikelihood::ConstBranchModelIterator> mit(drtl.getNewBranchModelIterator(currentSon->getId()));
+        VVVdouble pxy;
+        bool first;
+        while (mit->hasNext())
+        {
+          TreeLikelihood::ConstBranchModelDescription* bmd = mit->next();
+          auto_ptr<TreeLikelihood::SiteIterator> sit(bmd->getNewSiteIterator());
+          first = true;
+          while (sit->hasNext())
+          {
+            size_t i = sit->next();
+            // We retrieve the transition probabilities for this site partition:
+            if (first)
+            {
+              pxy = drtl.getTransitionProbabilitiesPerRateClass(currentSon->getId(), i);
+              first = false;
+            }
+            const VVdouble* likelihoodsFather_son_i = &(*likelihoodsFather_son)[i];
+            VVdouble* likelihoodsFatherConstantPart_i = &likelihoodsFatherConstantPart[i];
+            for (size_t c = 0; c < nbClasses; c++)
+            {
+              const Vdouble* likelihoodsFather_son_i_c = &(*likelihoodsFather_son_i)[c];
+              Vdouble* likelihoodsFatherConstantPart_i_c = &(*likelihoodsFatherConstantPart_i)[c];
+              VVdouble* pxy_c = &pxy[c];
+              for (size_t x = 0; x < nbStates; x++)
+              {
+                Vdouble* pxy_c_x = &(*pxy_c)[x];
+                double likelihood = 0.;
+                for (size_t y = 0; y < nbStates; y++)
+                {
+                  likelihood += (*pxy_c_x)[y] * (*likelihoodsFather_son_i_c)[y];
+                }
+                (*likelihoodsFatherConstantPart_i_c)[x] *= likelihood;
+              }
+            }
+          }
+        }
+      }
+    }
+    if (father->hasFather())
+    {
+      const Node* currentSon = father->getFather();
+      const VVVdouble* likelihoodsFather_son = &drtl.getLikelihoodData()->getLikelihoodArray(father->getId(), currentSon->getId());
+      // Now iterate over all site partitions:
+      auto_ptr<TreeLikelihood::ConstBranchModelIterator> mit(drtl.getNewBranchModelIterator(father->getId()));
+      VVVdouble pxy;
+      bool first;
+      while (mit->hasNext())
+      {
+        TreeLikelihood::ConstBranchModelDescription* bmd = mit->next();
+        auto_ptr<TreeLikelihood::SiteIterator> sit(bmd->getNewSiteIterator());
+        first = true;
+        while (sit->hasNext())
+        {
+          size_t i = sit->next();
+          // We retrieve the transition probabilities for this site partition:
+          if (first)
+          {
+            pxy = drtl.getTransitionProbabilitiesPerRateClass(father->getId(), i);
+            first = false;
+          }
+          const VVdouble* likelihoodsFather_son_i = &(*likelihoodsFather_son)[i];
+          VVdouble* likelihoodsFatherConstantPart_i = &likelihoodsFatherConstantPart[i];
+          for (size_t c = 0; c < nbClasses; c++)
+          {
+            const Vdouble* likelihoodsFather_son_i_c = &(*likelihoodsFather_son_i)[c];
+            Vdouble* likelihoodsFatherConstantPart_i_c = &(*likelihoodsFatherConstantPart_i)[c];
+            VVdouble* pxy_c = &pxy[c];
+            for (size_t x = 0; x < nbStates; x++)
+            {
+              double likelihood = 0.;
+              for (size_t y = 0; y < nbStates; y++)
+              {
+                Vdouble* pxy_c_x = &(*pxy_c)[y];
+                likelihood += (*pxy_c_x)[x] * (*likelihoodsFather_son_i_c)[y];
+              }
+              (*likelihoodsFatherConstantPart_i_c)[x] *= likelihood;
+            }
+          }
+        }
+      }
+    }
+    else
+    {
+      // Account for root frequencies:
+      for (size_t i = 0; i < nbDistinctSites; i++)
+      {
+        vector<double> freqs = drtl.getRootFrequencies(i);
+        VVdouble* likelihoodsFatherConstantPart_i = &likelihoodsFatherConstantPart[i];
+        for (size_t c = 0; c < nbClasses; c++)
+        {
+          Vdouble* likelihoodsFatherConstantPart_i_c = &(*likelihoodsFatherConstantPart_i)[c];
+          for (size_t x = 0; x < nbStates; x++)
+          {
+            (*likelihoodsFatherConstantPart_i_c)[x] *= freqs[x];
+          }
+        }
+      }
+    }
+
+    // Then, we deal with the node of interest.
+    // We first average upon 'y' to save computations, and then upon 'x'.
+    // ('y' is the state at 'node' and 'x' the state at 'father'.)
+
+    // Iterate over all site partitions:
+    const VVVdouble* likelihoodsFather_node = &(drtl.getLikelihoodData()->getLikelihoodArray(father->getId(), currentNode->getId()));
+    auto_ptr<TreeLikelihood::ConstBranchModelIterator> mit(drtl.getNewBranchModelIterator(currentNode->getId()));
+    VVVdouble pxy;
+    bool first;
+    while (mit->hasNext())
+    {
+      TreeLikelihood::ConstBranchModelDescription* bmd = mit->next();
+      reward.setSubstitutionModel(bmd->getModel());
+      // compute all nxy first:
+      VVVdouble nxy(nbClasses);
+      for (size_t c = 0; c < nbClasses; ++c)
+      {
+        VVdouble* nxy_c = &nxy[c];
+        double rc = rcRates[c];
+        Matrix<double>* nij = reward.getAllRewards(d * rc);
+        nxy_c->resize(nbStates);
+        for (size_t x = 0; x < nbStates; ++x)
+        {
+          Vdouble* nxy_c_x = &(*nxy_c)[x];
+          nxy_c_x->resize(nbStates);
+          for (size_t y = 0; y < nbStates; ++y)
+          {
+            (*nxy_c_x)[y] = (*nij)(x, y);
+          }
+        }
+        delete nij;
+      }
+
+      // Now loop over sites:
+      auto_ptr<TreeLikelihood::SiteIterator> sit(bmd->getNewSiteIterator());
+      first = true;
+      while (sit->hasNext())
+      {
+        size_t i = sit->next();
+        // We retrieve the transition probabilities and substitution counts for this site partition:
+        if (first)
+        {
+          pxy = drtl.getTransitionProbabilitiesPerRateClass(currentNode->getId(), i);
+          first = false;
+        }
+        const VVdouble* likelihoodsFather_node_i = &(*likelihoodsFather_node)[i];
+        VVdouble* likelihoodsFatherConstantPart_i = &likelihoodsFatherConstantPart[i];
+        for (size_t c = 0; c < nbClasses; ++c)
+        {
+          const Vdouble* likelihoodsFather_node_i_c = &(*likelihoodsFather_node_i)[c];
+          Vdouble* likelihoodsFatherConstantPart_i_c = &(*likelihoodsFatherConstantPart_i)[c];
+          const VVdouble* pxy_c = &pxy[c];
+          VVdouble* nxy_c = &nxy[c];
+          for (size_t x = 0; x < nbStates; ++x)
+          {
+            double* likelihoodsFatherConstantPart_i_c_x = &(*likelihoodsFatherConstantPart_i_c)[x];
+            const Vdouble* pxy_c_x = &(*pxy_c)[x];
+            for (size_t y = 0; y < nbStates; ++y)
+            {
+              double likelihood_cxy = (*likelihoodsFatherConstantPart_i_c_x)
+                                      * (*pxy_c_x)[y]
+                                      * (*likelihoodsFather_node_i_c)[y];
+
+              // Now the vector computation:
+              rewardsForCurrentNode[i] += likelihood_cxy * (*nxy_c)[x][y];
+              //                       <------------>   <--------------->
+              // Posterior probability         |                 |
+              // for site i and rate class c * |                 |
+              // likelihood for this site------+                 |
+              //                                                 |
+              // Reward function for site i and rate class c------+
+            }
+          }
+        }
+      }
+    }
+
+    // Now we just have to copy the substitutions into the result vector:
+    for (size_t i = 0; i < nbSites; ++i)
+    {
+      (*rewards)(l, i) = rewardsForCurrentNode[(*rootPatternLinks)[i]] / Lr[(*rootPatternLinks)[i]];
+    }
+  }
+  if (verbose)
+  {
+    if (ApplicationTools::message)
+      *ApplicationTools::message << " ";
+    ApplicationTools::displayTaskDone();
+  }
+  return rewards;
+}
+
+/**************************************************************************************************/
+
+void RewardMappingTools::writeToStream(
+  const ProbabilisticRewardMapping& rewards,
+  const SiteContainer& sites,
+  ostream& out)
+throw (IOException)
+{
+  if (!out)
+    throw IOException("RewardMappingTools::writeToFile. Can't write to stream.");
+  out << "Branches";
+  out << "\tMean";
+  for (size_t i = 0; i < rewards.getNumberOfSites(); i++)
+  {
+    out << "\tSite" << sites.getSite(i).getPosition();
+  }
+  out << endl;
+
+  for (size_t j = 0; j < rewards.getNumberOfBranches(); j++)
+  {
+    out << rewards.getNode(j)->getId() << "\t" << rewards.getNode(j)->getDistanceToFather();
+    for (size_t i = 0; i < rewards.getNumberOfSites(); i++)
+    {
+      out << "\t" << rewards(j, i);
+    }
+    out << endl;
+  }
+}
+
+/**************************************************************************************************/
+
+void RewardMappingTools::readFromStream(istream& in, ProbabilisticRewardMapping& rewards)
+throw (IOException)
+{
+  try
+  {
+    DataTable* data = DataTable::read(in, "\t", true, -1);
+    vector<string> ids = data->getColumn(0);
+    data->deleteColumn(0); // Remove ids
+    data->deleteColumn(0); // Remove means
+    // Now parse the table:
+    size_t nbSites = data->getNumberOfColumns();
+    rewards.setNumberOfSites(nbSites);
+    size_t nbBranches = data->getNumberOfRows();
+    for (size_t i = 0; i < nbBranches; i++)
+    {
+      int id = TextTools::toInt(ids[i]);
+      size_t br = rewards.getNodeIndex(id);
+      for (size_t j = 0; j < nbSites; j++)
+      {
+        rewards(br, j) = TextTools::toDouble((*data)(i, j));
+      }
+    }
+    // Parse the header:
+    for (size_t i = 0; i < nbSites; i++)
+    {
+      string siteTxt = data->getColumnName(i);
+      int site = 0;
+      if (siteTxt.substr(0, 4) == "Site")
+        site = TextTools::to<int>(siteTxt.substr(4));
+      else
+        site = TextTools::to<int>(siteTxt);
+      rewards.setSitePosition(i, site);
+    }
+
+    delete data;
+  }
+  catch (Exception& e)
+  {
+    throw IOException(string("Bad input file. ") + e.what());
+  }
+}
+
+/**************************************************************************************************/
+
+double RewardMappingTools::computeSumForBranch(const RewardMapping& smap, size_t branchIndex)
+{
+  size_t nbSites = smap.getNumberOfSites();
+  double v = 0;
+  for (size_t i = 0; i < nbSites; ++i)
+  {
+    v += smap(branchIndex, i);
+  }
+  return v;
+}
+
+/**************************************************************************************************/
+
+double RewardMappingTools::computeSumForSite(const RewardMapping& smap, size_t siteIndex)
+{
+  size_t nbBranches = smap.getNumberOfBranches();
+  double v = 0;
+  for (size_t i = 0; i < nbBranches; ++i)
+  {
+    v += smap(i, siteIndex);
+  }
+  return v;
+}
+
+/**************************************************************************************************/
diff --git a/src/Bpp/Phyl/Mapping/RewardMappingTools.h b/src/Bpp/Phyl/Mapping/RewardMappingTools.h
new file mode 100644
index 0000000..bc601a3
--- /dev/null
+++ b/src/Bpp/Phyl/Mapping/RewardMappingTools.h
@@ -0,0 +1,136 @@
+//
+// File: RewardMappingTools.h
+// Created by: Laurent Guéguen
+// Created on: vendredi 29 mars 2013, à 14h 08
+//
+
+/*
+   Copyright or © or Copr. Bio++ Development Team, (November 16, 2004, 2005, 2006)
+
+   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 _REWARDMAPPINGTOOLS_H_
+#define _REWARDMAPPINGTOOLS_H_
+
+#include "ProbabilisticRewardMapping.h"
+#include "Reward.h"
+
+#include "../Likelihood/DRTreeLikelihood.h"
+
+namespace bpp
+{
+/**
+ * @brief Provide methods to compute reward mappings.
+ *
+ * For now, 4 methods are implemented, and provide reward mappings.
+ *
+ * See:
+ * Minin, V.N. and Suchard, M.A.,
+ * Fast, accurate and simulation-free stochastic mapping
+ * Philosophical Transactions of the Royal Society B 2008 363:3985-95.
+ *
+ * @author Laurent Guéguen
+ */
+class RewardMappingTools
+{
+public:
+  RewardMappingTools() {}
+  virtual ~RewardMappingTools() {}
+
+public:
+  /**
+   * @brief Compute the reward vectors for a particular dataset
+   * using the double-recursive likelihood computation.
+   *
+   * @param drtl              A DRTreeLikelihood object.
+   * @param nodeIds           The Ids of the nodes the reward vectors
+   *                          are computed on.
+   * @param reward            The Reward to use.
+   * @param verbose           Print info to screen.
+   * @return A vector of reward vectors (one for each site).
+   * @throw Exception If the likelihood object is not initialized.
+   */
+  static ProbabilisticRewardMapping* computeRewardVectors(
+    const DRTreeLikelihood& drtl,
+    const std::vector<int>& nodeIds,
+    Reward& reward,
+    bool verbose = true) throw (Exception);
+
+
+  /**
+   * @brief Write the reward vectors to a stream.
+   *
+   * @param rewards The reward vectors to write.
+   * @param sites         The dataset associated to the vectors
+   * (needed to know the position of each site in the dataset).
+   * @param out           The output stream where to write the vectors.
+   * @throw IOException If an output error happens.
+   */
+  static void writeToStream(
+    const ProbabilisticRewardMapping& rewards,
+    const SiteContainer& sites,
+    std::ostream& out)
+  throw (IOException);
+
+
+  /**
+   * @brief Read the reward vectors from a stream.
+   *
+   * @param in            The input stream where to read the vectors.
+   * @param rewards       The mapping object to fill.
+   * @throw IOException If an input error happens.
+   */
+  static void readFromStream(std::istream& in, ProbabilisticRewardMapping& rewards)
+  throw (IOException);
+
+
+  /**
+   * @brief Sum all rewards of a given branch (specified by its index).
+   *
+   * @param smap The reward map to use.
+   * @param branchIndex The index of the reward vector for which the counts should be computed.
+   * @return A vector will all rewards summed.
+   */
+  static double computeSumForBranch(const RewardMapping& smap, size_t branchIndex);
+
+
+  /**
+   * @brief Sum all substitutions for each type of a given site (specified by its index).
+   *
+   * @param smap The substitution map to use.
+   * @param siteIndex The index of the substitution vector for which the counts should be computed.
+   * @return A vector will all counts summed for each types of substitutions.
+   */
+  static double computeSumForSite(const RewardMapping& smap, size_t siteIndex);
+};
+} // end of namespace bpp.
+
+#endif // _REWARDMAPPINGTOOLS_H_
diff --git a/src/Bpp/Phyl/Mapping/SubstitutionCount.h b/src/Bpp/Phyl/Mapping/SubstitutionCount.h
index 468ec63..1ef0ef6 100644
--- a/src/Bpp/Phyl/Mapping/SubstitutionCount.h
+++ b/src/Bpp/Phyl/Mapping/SubstitutionCount.h
@@ -129,7 +129,7 @@ namespace bpp
      * @return The number of substitutions on a branch of specified length and
      * according to initial and final states.
      */
-    virtual double getNumberOfSubstitutions(int initialState, int finalState, double length, size_t type) const = 0;
+    virtual double getNumberOfSubstitutions(size_t initialState, size_t finalState, double length, size_t type) const = 0;
 		
     /**
      * @brief Get the numbers of susbstitutions on a branch, for each initial and final states, and given the branch length.
@@ -148,7 +148,7 @@ namespace bpp
      * @param length       The length of the branch.
      * @return A matrix with all numbers of substitutions for each initial and final states.
      */
-    virtual std::vector<double> getNumberOfSubstitutionsForEachType(int initialState, int finalState, double length) const = 0;
+    virtual std::vector<double> getNumberOfSubstitutionsForEachType(size_t initialState, size_t finalState, double length) const = 0;
 
     /**
      * @brief Set the substitution model associated with this count, if relevent.
@@ -167,7 +167,7 @@ namespace bpp
     public virtual SubstitutionCount
   {
   protected:
-    SubstitutionRegister* register_;
+    std::auto_ptr<SubstitutionRegister> register_;
 
   public:
     AbstractSubstitutionCount(SubstitutionRegister* reg):
@@ -175,40 +175,37 @@ namespace bpp
     {}
 
     AbstractSubstitutionCount(const AbstractSubstitutionCount& asc):
-      register_(dynamic_cast<SubstitutionRegister*>(register_->clone()))
+      register_(asc.register_.get() ? asc.register_->clone() : 0)
     {}
 
     AbstractSubstitutionCount& operator=(const AbstractSubstitutionCount& asc) {
-      if (register_)
-        delete register_;
-      register_ = dynamic_cast<SubstitutionRegister*>(register_->clone());
+      if (asc.register_.get())
+        register_.reset(asc.register_->clone());
+      else
+        register_.reset();
       return *this;
     }
 
-    ~AbstractSubstitutionCount() {
-      if (register_)
-        delete register_;
-    }
+    ~AbstractSubstitutionCount() {}
 
   public:
-    bool hasSubstitutionRegister() const { return (register_ != 0); }
+    bool hasSubstitutionRegister() const { return (register_.get() != 0); }
 
-    /*
-     *@brief attribution of a SubstitutionRegister
+    /**
+     * @brief attribution of a SubstitutionRegister
      *
-     *@param reg pointer to a SubstitutionRegister
+     * @param reg pointer to a SubstitutionRegister
      *
      */
     
     void setSubstitutionRegister(SubstitutionRegister* reg) {
-      if (register_) delete register_;
-      register_ = reg;
+      register_.reset(reg);
       substitutionRegisterHasChanged();
     }
 
-    const SubstitutionRegister* getSubstitutionRegister() const { return register_; }
+    const SubstitutionRegister* getSubstitutionRegister() const { return register_.get(); }
     
-    SubstitutionRegister* getSubstitutionRegister() { return register_; }
+    SubstitutionRegister* getSubstitutionRegister() { return register_.get(); }
 
   protected:
     virtual void substitutionRegisterHasChanged() = 0;
diff --git a/src/Bpp/Phyl/Mapping/SubstitutionMapping.h b/src/Bpp/Phyl/Mapping/SubstitutionMapping.h
index c983768..a9fd011 100644
--- a/src/Bpp/Phyl/Mapping/SubstitutionMapping.h
+++ b/src/Bpp/Phyl/Mapping/SubstitutionMapping.h
@@ -40,8 +40,7 @@ knowledge of the CeCILL license and that you accept its terms.
 #ifndef _SUBSTITUTIONMAPPING_H_
 #define _SUBSTITUTIONMAPPING_H_
 
-#include "../Tree.h"
-#include "../TreeTemplate.h"
+#include "Mapping.h"
 
 #include <Bpp/Clonable.h>
 
@@ -63,10 +62,10 @@ namespace bpp
  * interface only contains a few methods.
  * More methods are expected to be added later.
  */
-class SubstitutionMapping:
-  public virtual Clonable
-{
-
+  class SubstitutionMapping:
+    virtual public Mapping
+  {
+    
   public:
     SubstitutionMapping() {}
     virtual ~SubstitutionMapping() {}
@@ -76,175 +75,45 @@ class SubstitutionMapping:
 #endif
 
   public:
-    
-    /**
-     * @return Get the phylogenetic tree associated to this mapping.
-     */
-    virtual const Tree& getTree() const = 0;
-    
-    /**
-     * @return True is the map is empty, that is, if no tree is associated to the map yet.
-     */
-    virtual bool isEmpty() const = 0;
-
-    /**
-     * @return The number of sites mapped.
-     */
-    virtual size_t getNumberOfSites() const = 0;
-    
-    /**
-     * @return The number of branches mapped.
-     */
-    virtual size_t getNumberOfBranches() const = 0;
-    
     /**
      * @return The number of distinct types of substitutions mapped.
      */
     virtual size_t getNumberOfSubstitutionTypes() const = 0;
     
-    /**
-     * @param index The site index.
-     * @return The site position corresponding to the index.
-     */
-    virtual int getSitePosition(size_t index) const = 0;
-    
-    /**
-     * @return A vector with all tree branch lengths.
-     */
-    virtual std::vector<double> getBranchLengths() const = 0;
-    
-    /**
-     * @param nodeId An id of the node to look for in the map.
-     * @return The mapping index for the specified node id.
-     */
-    virtual size_t getNodeIndex(int nodeId) const throw (NodeNotFoundException) = 0;
-
-    /**
-     * @brief Set the position of a given site.
-     *
-     * @warning No index checking is performed, use with care!
-     * @param index The site index.
-     * @param position The position of the site.
-     */
-    virtual void setSitePosition(size_t index, int position) = 0;
-
     virtual double& operator()(size_t nodeIndex, size_t siteIndex, size_t type) = 0;
     virtual const double& operator()(size_t nodeIndex, size_t siteIndex, size_t type) const = 0;
 };
 
 
 
-
-
-
 /**
  * @brief Partial implementation of the substitution mapping interface.
  *
  * This implementation copies the input tree in a TreeTemplate<Node> object.
  */
 class AbstractSubstitutionMapping:
-  public SubstitutionMapping
+    virtual public SubstitutionMapping,
+    virtual public AbstractMapping
 {
-  private:
-    std::auto_ptr<const TreeTemplate<Node> > tree_;
-    std::vector<int> sitesPositions_;
-    std::vector<const Node *> nodes_;
-    size_t nbSites_;
-    size_t nbBranches_;
+public:
+  //  AbstractSubstitutionMapping() : AbstractMapping(){}
 
-  public:
-    AbstractSubstitutionMapping() : tree_(0), sitesPositions_(), nodes_(), nbSites_(0), nbBranches_(0) {}
+  AbstractSubstitutionMapping(const Tree& tree) : AbstractMapping(tree){}
 
-    AbstractSubstitutionMapping(const Tree& tree) : tree_(new TreeTemplate<Node>(tree)), sitesPositions_(), nodes_(), nbSites_(0), nbBranches_(0)
-    {
-      nodes_ = tree_->getNodes();
-      nodes_.pop_back(); // remove root node.
-      nbBranches_ = nodes_.size();
-    }
+  AbstractSubstitutionMapping(const AbstractSubstitutionMapping& absm):
+    AbstractMapping(absm) {}
 
-    AbstractSubstitutionMapping(const AbstractSubstitutionMapping& absm):
-      tree_(dynamic_cast<const TreeTemplate<Node>*>(absm.tree_->clone())),
-      sitesPositions_(absm.sitesPositions_),
-      nodes_(),
-      nbSites_(absm.nbSites_),
-      nbBranches_(absm.nbBranches_)
-    {
-      nodes_ = tree_->getNodes();
-      nodes_.pop_back(); // remove root node.
-    }
+#ifndef NO_VIRTUAL_COV
+  AbstractSubstitutionMapping* clone() const = 0;
+#endif
 
-    AbstractSubstitutionMapping& operator=(const AbstractSubstitutionMapping& absm)
+  AbstractSubstitutionMapping& operator=(const AbstractSubstitutionMapping& absm)
     {
-      tree_.reset(dynamic_cast<const TreeTemplate<Node>*>(absm.tree_->clone()));
-      sitesPositions_ = absm.sitesPositions_;
-      nbSites_        = absm.nbSites_;
-      nbBranches_     = absm.nbBranches_;
-      nodes_          = tree_->getNodes();
-      nodes_.pop_back(); // remove root node.
+      AbstractMapping::operator=(absm);
       return *this;
     }
 
-    virtual ~AbstractSubstitutionMapping() {}
-
-  public:
-
-    bool isEmpty() const { return tree_.get() == 0; }
-
-		const	TreeTemplate<Node>& getTree() const throw (Exception)
-    {
-      if (isEmpty()) throw Exception("AbstractSubstitutionMapping::getSitePosition. No tree is assigned to this map yet.");
-      return *tree_.get();
-    }
-
-    void setTree(const Tree& tree)
-    {
-      tree_.reset(new TreeTemplate<Node>(tree));
-      nodes_ = tree_->getNodes();
-      nodes_.pop_back(); // remove root node.
-      nbBranches_ = nodes_.size();
-    }
- 
-    int getSitePosition(size_t index) const throw (Exception)
-    {
-      if (isEmpty()) throw Exception("AbstractSubstitutionMapping::getSitePosition. No tree is assigned to this map yet.");
-      return sitesPositions_[index];
-    }
-    
-    void setSitePosition(size_t index, int position) throw (Exception)
-    {
-      if (isEmpty()) throw Exception("AbstractSubstitutionMapping::setSitePosition. No tree is assigned to this map yet.");
-      sitesPositions_[index] = position;
-    }
-		
-    size_t getNumberOfSites() const { return nbSites_; }
-
-    size_t getNumberOfBranches() const { return nbBranches_; }
-    
-    virtual const Node* getNode(size_t nodeIndex) const { return nodes_[nodeIndex]; }
-
-    virtual void setNumberOfSites(size_t numberOfSites)
-    {
-      nbSites_ = numberOfSites;
-      sitesPositions_.resize(numberOfSites);
-      for (size_t i = 0; i < numberOfSites; i++)
-        sitesPositions_[i] = static_cast<int>(i + 1); //Default: all sizes numbered for 1 to n.
-    }
-
-    virtual std::vector<double> getBranchLengths() const
-    {
-      std::vector<double> brLen(nbBranches_);
-      for (size_t i = 0; i < nbBranches_; i++)
-        brLen[i] = nodes_[i]->getDistanceToFather();
-      return brLen;
-    }
-
-    virtual size_t getNodeIndex(int nodeId) const throw (NodeNotFoundException)
-    {
-      for (size_t i = 0; i < nbBranches_; i++)
-        if(nodes_[i]->getId() == nodeId) return i;
-      throw NodeNotFoundException("ProbabilisticSubstitutionMapping::getNodeIndex(nodeId).", TextTools::toString(nodeId));
-    }
-
+  virtual ~AbstractSubstitutionMapping() {}
 
 };
 
diff --git a/src/Bpp/Phyl/Mapping/SubstitutionMappingTools.cpp b/src/Bpp/Phyl/Mapping/SubstitutionMappingTools.cpp
index 6e5f192..97850fc 100644
--- a/src/Bpp/Phyl/Mapping/SubstitutionMappingTools.cpp
+++ b/src/Bpp/Phyl/Mapping/SubstitutionMappingTools.cpp
@@ -5,39 +5,43 @@
 //
 
 /*
-Copyright or © or Copr. Bio++ Development Team, (November 16, 2004, 2005, 2006)
-
-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.
-*/
+   Copyright or © or Copr. Bio++ Development Team, (November 16, 2004, 2005, 2006)
+
+   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 "SubstitutionMappingTools.h"
+#include "UniformizationSubstitutionCount.h"
+#include "DecompositionReward.h"
+#include "ProbabilisticRewardMapping.h"
+#include "RewardMappingTools.h"
 #include "../Likelihood/DRTreeLikelihoodTools.h"
 #include "../Likelihood/MarginalAncestralStateReconstruction.h"
 
@@ -45,6 +49,7 @@ knowledge of the CeCILL license and that you accept its terms.
 #include <Bpp/App/ApplicationTools.h>
 #include <Bpp/Numeric/Matrix/MatrixTools.h>
 #include <Bpp/Numeric/DataTable.h>
+#include <Bpp/Seq/AlphabetIndex/UserAlphabetIndex1.h>
 
 using namespace bpp;
 
@@ -57,18 +62,20 @@ using namespace std;
 
 ProbabilisticSubstitutionMapping* SubstitutionMappingTools::computeSubstitutionVectors(
   const DRTreeLikelihood& drtl,
+  const vector<int>& nodeIds,
   SubstitutionCount& substitutionCount,
   bool verbose) throw (Exception)
 {
-  //Preamble:
-  if (!drtl.isInitialized()) throw Exception("SubstitutionMappingTools::computeSubstitutionVectors(). Likelihood object is not initialized.");
-                                   
-  //A few variables we'll need:
-  
+  // Preamble:
+  if (!drtl.isInitialized())
+    throw Exception("SubstitutionMappingTools::computeSubstitutionVectors(). Likelihood object is not initialized.");
+
+  // A few variables we'll need:
+
   const TreeTemplate<Node> tree(drtl.getTree());
   const SiteContainer*    sequences = drtl.getData();
   const DiscreteDistribution* rDist = drtl.getRateDistribution();
-    
+
   size_t nbSites         = sequences->getNumberOfSites();
   size_t nbDistinctSites = drtl.getLikelihoodData()->getNumberOfDistinctSites();
   size_t nbStates        = sequences->getAlphabet()->getSize();
@@ -76,13 +83,13 @@ ProbabilisticSubstitutionMapping* SubstitutionMappingTools::computeSubstitutionV
   size_t nbTypes         = substitutionCount.getNumberOfSubstitutionTypes();
   vector<const Node*> nodes    = tree.getNodes();
   const vector<size_t>* rootPatternLinks
-                               = &drtl.getLikelihoodData()->getRootArrayPositions();
+    = &drtl.getLikelihoodData()->getRootArrayPositions();
   nodes.pop_back(); // Remove root node.
   size_t nbNodes         = nodes.size();
-  
+
   // We create a new ProbabilisticSubstitutionMapping object:
   ProbabilisticSubstitutionMapping* substitutions = new ProbabilisticSubstitutionMapping(tree, &substitutionCount, nbSites);
-                                   
+
   // Store likelihood for each rate for each site:
   VVVdouble lik;
   drtl.computeLikelihoodAtNode(tree.getRootId(), lik);
@@ -104,21 +111,27 @@ ProbabilisticSubstitutionMapping* SubstitutionMappingTools::computeSubstitutionV
   }
 
   // Compute the number of substitutions for each class and each branch in the tree:
-  if (verbose) ApplicationTools::displayTask("Compute joint node-pairs likelihood", true);
-  
-  for (size_t l = 0; l < nbNodes; l++)
+  if (verbose)
+    ApplicationTools::displayTask("Compute joint node-pairs likelihood", true);
+
+  for (size_t l = 0; l < nbNodes; ++l)
   {
-    //For each node,
+    // For each node,
     const Node* currentNode = nodes[l];
+    if (nodeIds.size() > 0 && !VectorTools::contains(nodeIds, currentNode->getId()))
+      continue;
 
     const Node* father = currentNode->getFather();
 
     double d = currentNode->getDistanceToFather();
- 
-    if (verbose) ApplicationTools::displayGauge(l, nbNodes-1, '>');
+
+    if (verbose)
+      ApplicationTools::displayGauge(l, nbNodes - 1);
     VVdouble substitutionsForCurrentNode(nbDistinctSites);
     for (size_t i = 0; i < nbDistinctSites; ++i)
+    {
       substitutionsForCurrentNode[i].resize(nbTypes);
+    }
 
     // Now we've got to compute likelihoods in a smart manner... ;)
     VVVdouble likelihoodsFatherConstantPart(nbDistinctSites);
@@ -133,13 +146,13 @@ ProbabilisticSubstitutionMapping* SubstitutionMappingTools::computeSubstitutionV
         double rc = rDist->getProbability(c);
         for (size_t s = 0; s < nbStates; s++)
         {
-          //(* likelihoodsFatherConstantPart_i_c)[s] = rc * model->freq(s);
-          //freq is already accounted in the array
-          (* likelihoodsFatherConstantPart_i_c)[s] = rc;
+          // (* likelihoodsFatherConstantPart_i_c)[s] = rc * model->freq(s);
+          // freq is already accounted in the array
+          (*likelihoodsFatherConstantPart_i_c)[s] = rc;
         }
       }
     }
-    
+
     // First, what will remain constant:
     size_t nbSons =  father->getNumberOfSons();
     for (size_t n = 0; n < nbSons; n++)
@@ -149,7 +162,7 @@ ProbabilisticSubstitutionMapping* SubstitutionMappingTools::computeSubstitutionV
       {
         const VVVdouble* likelihoodsFather_son = &drtl.getLikelihoodData()->getLikelihoodArray(father->getId(), currentSon->getId());
 
-        //Now iterate over all site partitions:
+        // Now iterate over all site partitions:
         auto_ptr<TreeLikelihood::ConstBranchModelIterator> mit(drtl.getNewBranchModelIterator(currentSon->getId()));
         VVVdouble pxy;
         bool first;
@@ -161,7 +174,7 @@ ProbabilisticSubstitutionMapping* SubstitutionMappingTools::computeSubstitutionV
           while (sit->hasNext())
           {
             size_t i = sit->next();
-            //We retrieve the transition probabilities for this site partition:
+            // We retrieve the transition probabilities for this site partition:
             if (first)
             {
               pxy = drtl.getTransitionProbabilitiesPerRateClass(currentSon->getId(), i);
@@ -186,14 +199,14 @@ ProbabilisticSubstitutionMapping* SubstitutionMappingTools::computeSubstitutionV
               }
             }
           }
-        }      
+        }
       }
     }
     if (father->hasFather())
     {
       const Node* currentSon = father->getFather();
       const VVVdouble* likelihoodsFather_son = &drtl.getLikelihoodData()->getLikelihoodArray(father->getId(), currentSon->getId());
-      //Now iterate over all site partitions:
+      // Now iterate over all site partitions:
       auto_ptr<TreeLikelihood::ConstBranchModelIterator> mit(drtl.getNewBranchModelIterator(father->getId()));
       VVVdouble pxy;
       bool first;
@@ -205,7 +218,7 @@ ProbabilisticSubstitutionMapping* SubstitutionMappingTools::computeSubstitutionV
         while (sit->hasNext())
         {
           size_t i = sit->next();
-          //We retrieve the transition probabilities for this site partition:
+          // We retrieve the transition probabilities for this site partition:
           if (first)
           {
             pxy = drtl.getTransitionProbabilitiesPerRateClass(father->getId(), i);
@@ -217,7 +230,7 @@ ProbabilisticSubstitutionMapping* SubstitutionMappingTools::computeSubstitutionV
           {
             const Vdouble* likelihoodsFather_son_i_c = &(*likelihoodsFather_son_i)[c];
             Vdouble* likelihoodsFatherConstantPart_i_c = &(*likelihoodsFatherConstantPart_i)[c];
-            VVdouble* pxy_c = &pxy[c]; 
+            VVdouble* pxy_c = &pxy[c];
             for (size_t x = 0; x < nbStates; x++)
             {
               double likelihood = 0.;
@@ -230,11 +243,11 @@ ProbabilisticSubstitutionMapping* SubstitutionMappingTools::computeSubstitutionV
             }
           }
         }
-      }      
+      }
     }
     else
     {
-      //Account for root frequencies:
+      // Account for root frequencies:
       for (size_t i = 0; i < nbDistinctSites; i++)
       {
         vector<double> freqs = drtl.getRootFrequencies(i);
@@ -247,15 +260,16 @@ ProbabilisticSubstitutionMapping* SubstitutionMappingTools::computeSubstitutionV
             (*likelihoodsFatherConstantPart_i_c)[x] *= freqs[x];
           }
         }
-      }      
+      }
     }
 
+
     // Then, we deal with the node of interest.
-    // We first average uppon 'y' to save computations, and then uppon 'x'.
+    // We first average upon 'y' to save computations, and then upon 'x'.
     // ('y' is the state at 'node' and 'x' the state at 'father'.)
 
-    //Iterate over all site partitions:
-		const VVVdouble* likelihoodsFather_node = &(drtl.getLikelihoodData()->getLikelihoodArray(father->getId(), currentNode->getId()));
+    // Iterate over all site partitions:
+    const VVVdouble* likelihoodsFather_node = &(drtl.getLikelihoodData()->getLikelihoodArray(father->getId(), currentNode->getId()));
     auto_ptr<TreeLikelihood::ConstBranchModelIterator> mit(drtl.getNewBranchModelIterator(currentNode->getId()));
     VVVdouble pxy;
     bool first;
@@ -263,7 +277,7 @@ ProbabilisticSubstitutionMapping* SubstitutionMappingTools::computeSubstitutionV
     {
       TreeLikelihood::ConstBranchModelDescription* bmd = mit->next();
       substitutionCount.setSubstitutionModel(bmd->getModel());
-      //compute all nxy first:
+      // compute all nxy first:
       VVVVdouble nxy(nbClasses);
       for (size_t c = 0; c < nbClasses; ++c)
       {
@@ -280,22 +294,24 @@ ProbabilisticSubstitutionMapping* SubstitutionMappingTools::computeSubstitutionV
             Vdouble* nxy_c_t_x = &(*nxy_c_t)[x];
             nxy_c_t_x->resize(nbStates);
             for (size_t y = 0; y < nbStates; ++y)
+            {
               (*nxy_c_t_x)[y] = (*nijt)(x, y);
+            }
           }
           delete nijt;
         }
       }
 
-      //Now loop over sites:
+      // Now loop over sites:
       auto_ptr<TreeLikelihood::SiteIterator> sit(bmd->getNewSiteIterator());
       first = true;
       while (sit->hasNext())
       {
         size_t i = sit->next();
-        //We retrieve the transition probabilities and substitution counts for this site partition:
+        // We retrieve the transition probabilities and substitution counts for this site partition:
         if (first)
         {
-          pxy = drtl.getTransitionProbabilitiesPerRateClass(currentNode->getId(), i);  
+          pxy = drtl.getTransitionProbabilitiesPerRateClass(currentNode->getId(), i);
           first = false;
         }
         const VVdouble* likelihoodsFather_node_i = &(*likelihoodsFather_node)[i];
@@ -313,116 +329,151 @@ ProbabilisticSubstitutionMapping* SubstitutionMappingTools::computeSubstitutionV
             for (size_t y = 0; y < nbStates; ++y)
             {
               double likelihood_cxy = (*likelihoodsFatherConstantPart_i_c_x)
-                 *(*pxy_c_x)[y]
-                 *(*likelihoodsFather_node_i_c)[y];
+                                      * (*pxy_c_x)[y]
+                                      * (*likelihoodsFather_node_i_c)[y];
 
-              for (size_t t = 0; t < nbTypes; ++t) {
+              for (size_t t = 0; t < nbTypes; ++t)
+              {
                 // Now the vector computation:
                 substitutionsForCurrentNode[i][t] += likelihood_cxy * (*nxy_c)[t][x][y];
                 //                                   <------------>   <--------------->
-                // Posterior probability                   |                 | 
+                // Posterior probability                   |                 |
                 // for site i and rate class c *           |                 |
                 // likelihood for this site----------------+                 |
                 //                                                           |
-                //Substitution function for site i and rate class c----------+
+                // Substitution function for site i and rate class c----------+
               }
-            }          
+            }
           }
         }
       }
     }
-    
-    //Now we just have to copy the substitutions into the result vector:
+
+    // Now we just have to copy the substitutions into the result vector:
     for (size_t i = 0; i < nbSites; ++i)
+    {
       for (size_t t = 0; t < nbTypes; ++t)
-        (*substitutions)(l, i, t) = substitutionsForCurrentNode[(* rootPatternLinks)[i]][t] / Lr[(* rootPatternLinks)[i]];
+      {
+        (*substitutions)(l, i, t) = substitutionsForCurrentNode[(*rootPatternLinks)[i]][t] / Lr[(*rootPatternLinks)[i]];
+      }
+    }
   }
   if (verbose)
   {
-    if (ApplicationTools::message) *ApplicationTools::message << " ";
+    if (ApplicationTools::message)
+      *ApplicationTools::message << " ";
     ApplicationTools::displayTaskDone();
   }
+
   return substitutions;
 }
 
-/**************************************************************************************************/
+/******************************************************************************/
 
-ProbabilisticSubstitutionMapping* SubstitutionMappingTools::computeSubstitutionVectorsNoAveraging(
+ProbabilisticSubstitutionMapping* SubstitutionMappingTools::computeSubstitutionVectors(
   const DRTreeLikelihood& drtl,
+  const SubstitutionModelSet& modelSet,
+  const vector<int>& nodeIds,
   SubstitutionCount& substitutionCount,
   bool verbose) throw (Exception)
 {
-  //Preamble:
-  if (!drtl.isInitialized()) throw Exception("SubstitutionMappingTools::computeSubstitutionVectorsNoAveraging(). Likelihood object is not initialized.");
-                                   
-  //A few variables we'll need:
+  // Preamble:
+  if (!drtl.isInitialized())
+    throw Exception("SubstitutionMappingTools::computeSubstitutionVectors(). Likelihood object is not initialized.");
+
+  // A few variables we'll need:
+
   const TreeTemplate<Node> tree(drtl.getTree());
   const SiteContainer*    sequences = drtl.getData();
   const DiscreteDistribution* rDist = drtl.getRateDistribution();
-    
+
   size_t nbSites         = sequences->getNumberOfSites();
   size_t nbDistinctSites = drtl.getLikelihoodData()->getNumberOfDistinctSites();
   size_t nbStates        = sequences->getAlphabet()->getSize();
   size_t nbClasses       = rDist->getNumberOfCategories();
   size_t nbTypes         = substitutionCount.getNumberOfSubstitutionTypes();
-  vector<const Node *> nodes   = tree.getNodes();
-  const vector<size_t> * rootPatternLinks
-                               = &drtl.getLikelihoodData()->getRootArrayPositions();
+  vector<const Node*> nodes    = tree.getNodes();
+  const vector<size_t>* rootPatternLinks
+    = &drtl.getLikelihoodData()->getRootArrayPositions();
   nodes.pop_back(); // Remove root node.
-  size_t nbNodes = nodes.size();
-  
+  size_t nbNodes         = nodes.size();
+
   // We create a new ProbabilisticSubstitutionMapping object:
   ProbabilisticSubstitutionMapping* substitutions = new ProbabilisticSubstitutionMapping(tree, &substitutionCount, nbSites);
-                                   
+
+  // Store likelihood for each rate for each site:
+  VVVdouble lik;
+  drtl.computeLikelihoodAtNode(tree.getRootId(), lik);
+  Vdouble Lr(nbDistinctSites, 0);
+  Vdouble rcProbs = rDist->getProbabilities();
   Vdouble rcRates = rDist->getCategories();
+  for (size_t i = 0; i < nbDistinctSites; i++)
+  {
+    VVdouble* lik_i = &lik[i];
+    for (size_t c = 0; c < nbClasses; c++)
+    {
+      Vdouble* lik_i_c = &(*lik_i)[c];
+      double rc = rDist->getProbability(c);
+      for (size_t s = 0; s < nbStates; s++)
+      {
+        Lr[i] += (*lik_i_c)[s] * rc;
+      }
+    }
+  }
 
   // Compute the number of substitutions for each class and each branch in the tree:
-  if (verbose) ApplicationTools::displayTask("Compute joint node-pairs likelihood", true);
-  
+  if (verbose)
+    ApplicationTools::displayTask("Compute joint node-pairs likelihood", true);
+
   for (size_t l = 0; l < nbNodes; ++l)
   {
     // For each node,
     const Node* currentNode = nodes[l];
+    if (nodeIds.size() > 0 && !VectorTools::contains(nodeIds, currentNode->getId()))
+      continue;
 
     const Node* father = currentNode->getFather();
 
     double d = currentNode->getDistanceToFather();
-    
-    if (verbose) ApplicationTools::displayGauge(l, nbNodes-1, '>');
+
+    if (verbose)
+      ApplicationTools::displayGauge(l, nbNodes - 1);
     VVdouble substitutionsForCurrentNode(nbDistinctSites);
     for (size_t i = 0; i < nbDistinctSites; ++i)
+    {
       substitutionsForCurrentNode[i].resize(nbTypes);
+    }
 
     // Now we've got to compute likelihoods in a smart manner... ;)
     VVVdouble likelihoodsFatherConstantPart(nbDistinctSites);
-    for (size_t i = 0; i < nbDistinctSites; ++i)
+    for (size_t i = 0; i < nbDistinctSites; i++)
     {
       VVdouble* likelihoodsFatherConstantPart_i = &likelihoodsFatherConstantPart[i];
       likelihoodsFatherConstantPart_i->resize(nbClasses);
-      for (size_t c = 0; c < nbClasses; ++c)
+      for (size_t c = 0; c < nbClasses; c++)
       {
         Vdouble* likelihoodsFatherConstantPart_i_c = &(*likelihoodsFatherConstantPart_i)[c];
         likelihoodsFatherConstantPart_i_c->resize(nbStates);
         double rc = rDist->getProbability(c);
-        for (size_t s = 0; s < nbStates; ++s)
+        for (size_t s = 0; s < nbStates; s++)
         {
-          //(* likelihoodsFatherConstantPart_i_c)[s] = rc * model->freq(s);
-          //freq is already accounted in the array
-          (* likelihoodsFatherConstantPart_i_c)[s] = rc;
+          // (* likelihoodsFatherConstantPart_i_c)[s] = rc * model->freq(s);
+          // freq is already accounted in the array
+          (*likelihoodsFatherConstantPart_i_c)[s] = rc;
         }
       }
     }
-    
+
     // First, what will remain constant:
     size_t nbSons =  father->getNumberOfSons();
-    for (size_t n = 0; n < nbSons; ++n)
+    for (size_t n = 0; n < nbSons; n++)
     {
-      const Node* currentSon = father->getSon(n);    
+      const Node* currentSon = father->getSon(n);
       if (currentSon->getId() != currentNode->getId())
       {
         const VVVdouble* likelihoodsFather_son = &drtl.getLikelihoodData()->getLikelihoodArray(father->getId(), currentSon->getId());
 
-        //Now iterate over all site partitions:
+        // Now iterate over all site partitions:
         auto_ptr<TreeLikelihood::ConstBranchModelIterator> mit(drtl.getNewBranchModelIterator(currentSon->getId()));
         VVVdouble pxy;
         bool first;
@@ -434,7 +485,7 @@ ProbabilisticSubstitutionMapping* SubstitutionMappingTools::computeSubstitutionV
           while (sit->hasNext())
           {
             size_t i = sit->next();
-            //We retrieve the transition probabilities for this site partition:
+            // We retrieve the transition probabilities for this site partition:
             if (first)
             {
               pxy = drtl.getTransitionProbabilitiesPerRateClass(currentSon->getId(), i);
@@ -442,16 +493,16 @@ ProbabilisticSubstitutionMapping* SubstitutionMappingTools::computeSubstitutionV
             }
             const VVdouble* likelihoodsFather_son_i = &(*likelihoodsFather_son)[i];
             VVdouble* likelihoodsFatherConstantPart_i = &likelihoodsFatherConstantPart[i];
-            for (size_t c = 0; c < nbClasses; ++c)
+            for (size_t c = 0; c < nbClasses; c++)
             {
               const Vdouble* likelihoodsFather_son_i_c = &(*likelihoodsFather_son_i)[c];
               Vdouble* likelihoodsFatherConstantPart_i_c = &(*likelihoodsFatherConstantPart_i)[c];
-              VVdouble* pxy_c = & pxy[c]; 
-              for (size_t x = 0; x < nbStates; ++x)
+              VVdouble* pxy_c = &pxy[c];
+              for (size_t x = 0; x < nbStates; x++)
               {
                 Vdouble* pxy_c_x = &(*pxy_c)[x];
                 double likelihood = 0.;
-                for (size_t y = 0; y < nbStates; ++y)
+                for (size_t y = 0; y < nbStates; y++)
                 {
                   likelihood += (*pxy_c_x)[y] * (*likelihoodsFather_son_i_c)[y];
                 }
@@ -459,14 +510,14 @@ ProbabilisticSubstitutionMapping* SubstitutionMappingTools::computeSubstitutionV
               }
             }
           }
-        }      
+        }
       }
     }
     if (father->hasFather())
     {
       const Node* currentSon = father->getFather();
       const VVVdouble* likelihoodsFather_son = &drtl.getLikelihoodData()->getLikelihoodArray(father->getId(), currentSon->getId());
-      //Now iterate over all site partitions:
+      // Now iterate over all site partitions:
       auto_ptr<TreeLikelihood::ConstBranchModelIterator> mit(drtl.getNewBranchModelIterator(father->getId()));
       VVVdouble pxy;
       bool first;
@@ -478,7 +529,7 @@ ProbabilisticSubstitutionMapping* SubstitutionMappingTools::computeSubstitutionV
         while (sit->hasNext())
         {
           size_t i = sit->next();
-          //We retrieve the transition probabilities for this site partition:
+          // We retrieve the transition probabilities for this site partition:
           if (first)
           {
             pxy = drtl.getTransitionProbabilitiesPerRateClass(father->getId(), i);
@@ -486,15 +537,15 @@ ProbabilisticSubstitutionMapping* SubstitutionMappingTools::computeSubstitutionV
           }
           const VVdouble* likelihoodsFather_son_i = &(*likelihoodsFather_son)[i];
           VVdouble* likelihoodsFatherConstantPart_i = &likelihoodsFatherConstantPart[i];
-          for (size_t c = 0; c < nbClasses; ++c)
+          for (size_t c = 0; c < nbClasses; c++)
           {
             const Vdouble* likelihoodsFather_son_i_c = &(*likelihoodsFather_son_i)[c];
             Vdouble* likelihoodsFatherConstantPart_i_c = &(*likelihoodsFatherConstantPart_i)[c];
-            VVdouble* pxy_c = &pxy[c]; 
-            for (size_t x = 0; x < nbStates; ++x)
+            VVdouble* pxy_c = &pxy[c];
+            for (size_t x = 0; x < nbStates; x++)
             {
               double likelihood = 0.;
-              for (size_t y = 0; y < nbStates; ++y)
+              for (size_t y = 0; y < nbStates; y++)
               {
                 Vdouble* pxy_c_x = &(*pxy_c)[y];
                 likelihood += (*pxy_c_x)[x] * (*likelihoodsFather_son_i_c)[y];
@@ -503,51 +554,53 @@ ProbabilisticSubstitutionMapping* SubstitutionMappingTools::computeSubstitutionV
             }
           }
         }
-      }      
+      }
     }
     else
     {
-      //Account for root frequencies:
-      for (size_t i = 0; i < nbDistinctSites; ++i)
+      // Account for root frequencies:
+      for (size_t i = 0; i < nbDistinctSites; i++)
       {
         vector<double> freqs = drtl.getRootFrequencies(i);
         VVdouble* likelihoodsFatherConstantPart_i = &likelihoodsFatherConstantPart[i];
-        for (size_t c = 0; c < nbClasses; ++c)
+        for (size_t c = 0; c < nbClasses; c++)
         {
           Vdouble* likelihoodsFatherConstantPart_i_c = &(*likelihoodsFatherConstantPart_i)[c];
-          for (size_t x = 0; x < nbStates; ++x)
+          for (size_t x = 0; x < nbStates; x++)
           {
-            (*likelihoodsFatherConstantPart_i_c)[x] *= freqs[x]; 
+            (*likelihoodsFatherConstantPart_i_c)[x] *= freqs[x];
           }
         }
-      }      
+      }
     }
 
+
     // Then, we deal with the node of interest.
-    // We first average uppon 'y' to save computations, and then uppon 'x'.
+    // We first average upon 'y' to save computations, and then upon 'x'.
     // ('y' is the state at 'node' and 'x' the state at 'father'.)
 
-    //Iterate over all site partitions:
-		const VVVdouble* likelihoodsFather_node = &drtl.getLikelihoodData()->getLikelihoodArray(father->getId(), currentNode->getId());
+    // Iterate over all site partitions:
+    const VVVdouble* likelihoodsFather_node = &(drtl.getLikelihoodData()->getLikelihoodArray(father->getId(), currentNode->getId()));
     auto_ptr<TreeLikelihood::ConstBranchModelIterator> mit(drtl.getNewBranchModelIterator(currentNode->getId()));
     VVVdouble pxy;
     bool first;
     while (mit->hasNext())
     {
       TreeLikelihood::ConstBranchModelDescription* bmd = mit->next();
-      substitutionCount.setSubstitutionModel(bmd->getModel());
-      //compute all nxy first:
+      substitutionCount.setSubstitutionModel(modelSet.getModelForNode(currentNode->getId()));
+
+      // compute all nxy first:
       VVVVdouble nxy(nbClasses);
       for (size_t c = 0; c < nbClasses; ++c)
       {
-        double rc = rcRates[c];
         VVVdouble* nxy_c = &nxy[c];
+        double rc = rcRates[c];
         nxy_c->resize(nbTypes);
         for (size_t t = 0; t < nbTypes; ++t)
         {
           VVdouble* nxy_c_t = &(*nxy_c)[t];
-          nxy_c_t->resize(nbStates);
           Matrix<double>* nijt = substitutionCount.getAllNumbersOfSubstitutions(d * rc, t + 1);
+          nxy_c_t->resize(nbStates);
           for (size_t x = 0; x < nbStates; ++x)
           {
             Vdouble* nxy_c_t_x = &(*nxy_c_t)[x];
@@ -561,29 +614,20 @@ ProbabilisticSubstitutionMapping* SubstitutionMappingTools::computeSubstitutionV
         }
       }
 
-      //Now loop over sites:
+      // Now loop over sites:
       auto_ptr<TreeLikelihood::SiteIterator> sit(bmd->getNewSiteIterator());
       first = true;
       while (sit->hasNext())
       {
         size_t i = sit->next();
-        //We retrieve the transition probabilities and substitution counts for this site partition:
+        // We retrieve the transition probabilities and substitution counts for this site partition:
         if (first)
         {
-          pxy = drtl.getTransitionProbabilitiesPerRateClass(currentNode->getId(), i);  
+          pxy = drtl.getTransitionProbabilitiesPerRateClass(currentNode->getId(), i);
           first = false;
         }
         const VVdouble* likelihoodsFather_node_i = &(*likelihoodsFather_node)[i];
         VVdouble* likelihoodsFatherConstantPart_i = &likelihoodsFatherConstantPart[i];
-        RowMatrix<double> pairProbabilities(nbStates, nbStates);
-        MatrixTools::fill(pairProbabilities, 0.);
-        VVVdouble subsCounts(nbStates);
-        for (size_t j = 0; j < nbStates; ++j) {
-          subsCounts[j].resize(nbStates);
-          for (size_t k = 0; k < nbStates; ++k) {
-            subsCounts[j][k].resize(nbTypes);
-          }
-        }
         for (size_t c = 0; c < nbClasses; ++c)
         {
           const Vdouble* likelihoodsFather_node_i_c = &(*likelihoodsFather_node_i)[c];
@@ -597,214 +641,542 @@ ProbabilisticSubstitutionMapping* SubstitutionMappingTools::computeSubstitutionV
             for (size_t y = 0; y < nbStates; ++y)
             {
               double likelihood_cxy = (*likelihoodsFatherConstantPart_i_c_x)
-                 *(*pxy_c_x)[y]
-                 *(*likelihoodsFather_node_i_c)[y];
-              pairProbabilities(x, y) += likelihood_cxy; // Sum over all rate classes.
-              for (size_t t = 0; t < nbTypes; ++t) {
-                subsCounts[x][y][t] += likelihood_cxy * (* nxy_c)[t][x][y];
+                                      * (*pxy_c_x)[y]
+                                      * (*likelihoodsFather_node_i_c)[y];
+
+              for (size_t t = 0; t < nbTypes; ++t)
+              {
+                // Now the vector computation:
+                substitutionsForCurrentNode[i][t] += likelihood_cxy * (*nxy_c)[t][x][y];
+                //                                   <------------>   <--------------->
+                // Posterior probability                   |                 |
+                // for site i and rate class c *           |                 |
+                // likelihood for this site----------------+                 |
+                //                                                           |
+                // Substitution function for site i and rate class c----------+
               }
             }
           }
         }
-        // Now the vector computation:
-        // Here we do not average over all possible pair of ancestral states,
-        // We only consider the one with max likelihood:
-        vector<size_t> xy = MatrixTools::whichMax(pairProbabilities);
-        for (size_t t = 0; t < nbTypes; ++t) {
-          substitutionsForCurrentNode[i][t] += subsCounts[xy[0]][xy[1]][t] / pairProbabilities(xy[0], xy[1]);
-        }
       }
     }
-    //Now we just have to copy the substitutions into the result vector:
-    for (size_t i = 0; i < nbSites; i++)
-      for (size_t t = 0; t < nbTypes; t++)
-        (*substitutions)(l, i, t) = substitutionsForCurrentNode[(*rootPatternLinks)[i]][t];
+
+    // Now we just have to copy the substitutions into the result vector:
+    for (size_t i = 0; i < nbSites; ++i)
+    {
+      for (size_t t = 0; t < nbTypes; ++t)
+      {
+        (*substitutions)(l, i, t) = substitutionsForCurrentNode[(*rootPatternLinks)[i]][t] / Lr[(*rootPatternLinks)[i]];
+      }
+    }
   }
   if (verbose)
   {
-    if (ApplicationTools::message) *ApplicationTools::message << " ";
+    if (ApplicationTools::message)
+      *ApplicationTools::message << " ";
     ApplicationTools::displayTaskDone();
   }
+
   return substitutions;
 }
 
 /**************************************************************************************************/
 
-ProbabilisticSubstitutionMapping* SubstitutionMappingTools::computeSubstitutionVectorsNoAveragingMarginal(
+ProbabilisticSubstitutionMapping* SubstitutionMappingTools::computeSubstitutionVectorsNoAveraging(
   const DRTreeLikelihood& drtl,
   SubstitutionCount& substitutionCount,
   bool verbose) throw (Exception)
 {
-  //Preamble:
-  if (!drtl.isInitialized()) throw Exception("SubstitutionMappingTools::computeSubstitutionVectorsNoAveragingMarginal(). Likelihood object is not initialized.");
-                                   
-  //A few variables we'll need:
-  
+  // Preamble:
+  if (!drtl.isInitialized())
+    throw Exception("SubstitutionMappingTools::computeSubstitutionVectorsNoAveraging(). Likelihood object is not initialized.");
+
+  // A few variables we'll need:
   const TreeTemplate<Node> tree(drtl.getTree());
   const SiteContainer*    sequences = drtl.getData();
   const DiscreteDistribution* rDist = drtl.getRateDistribution();
-  const Alphabet*             alpha = sequences->getAlphabet();
-    
+
   size_t nbSites         = sequences->getNumberOfSites();
   size_t nbDistinctSites = drtl.getLikelihoodData()->getNumberOfDistinctSites();
-  size_t nbStates        = alpha->getSize();
+  size_t nbStates        = sequences->getAlphabet()->getSize();
+  size_t nbClasses       = rDist->getNumberOfCategories();
   size_t nbTypes         = substitutionCount.getNumberOfSubstitutionTypes();
-  vector<const Node*> nodes    = tree.getNodes();
+  vector<const Node*> nodes   = tree.getNodes();
   const vector<size_t>* rootPatternLinks
-                               = &drtl.getLikelihoodData()->getRootArrayPositions();
+    = &drtl.getLikelihoodData()->getRootArrayPositions();
   nodes.pop_back(); // Remove root node.
   size_t nbNodes = nodes.size();
-  
+
   // We create a new ProbabilisticSubstitutionMapping object:
   ProbabilisticSubstitutionMapping* substitutions = new ProbabilisticSubstitutionMapping(tree, &substitutionCount, nbSites);
-  
-  // Compute the whole likelihood of the tree according to the specified model:
-  
+
   Vdouble rcRates = rDist->getCategories();
 
   // Compute the number of substitutions for each class and each branch in the tree:
-  if (verbose) ApplicationTools::displayTask("Compute marginal ancestral states");
-  MarginalAncestralStateReconstruction masr(&drtl);
-  map<int, vector<size_t> > ancestors = masr.getAllAncestralStates();
-  if (verbose) ApplicationTools::displayTaskDone();
+  if (verbose)
+    ApplicationTools::displayTask("Compute joint node-pairs likelihood", true);
 
-  // Now we just have to compute the substitution vectors:
-  if (verbose) ApplicationTools::displayTask("Compute substitution vectors", true);
-  
-  for (size_t l = 0; l < nbNodes; l++)
+  for (size_t l = 0; l < nbNodes; ++l)
   {
+    // For each node,
     const Node* currentNode = nodes[l];
-    
+
     const Node* father = currentNode->getFather();
 
     double d = currentNode->getDistanceToFather();
 
-    vector<size_t> nodeStates = ancestors[currentNode->getId()]; //These are not 'true' ancestors ;)
-    vector<size_t> fatherStates = ancestors[father->getId()];
-    
-    //For each node,
-    if (verbose) ApplicationTools::displayGauge(l, nbNodes-1, '>');
+    if (verbose)
+      ApplicationTools::displayGauge(l, nbNodes - 1);
     VVdouble substitutionsForCurrentNode(nbDistinctSites);
     for (size_t i = 0; i < nbDistinctSites; ++i)
+    {
       substitutionsForCurrentNode[i].resize(nbTypes);
-    
-    // Here, we have no likelihood computation to do!
+    }
 
-    // Then, we deal with the node of interest.
-    // ('y' is the state at 'node' and 'x' the state at 'father'.)
-    // Iterate over all site partitions:
-    auto_ptr<TreeLikelihood::ConstBranchModelIterator> mit(drtl.getNewBranchModelIterator(currentNode->getId()));
-    while (mit->hasNext())
+    // Now we've got to compute likelihoods in a smart manner... ;)
+    VVVdouble likelihoodsFatherConstantPart(nbDistinctSites);
+    for (size_t i = 0; i < nbDistinctSites; ++i)
     {
-      TreeLikelihood::ConstBranchModelDescription* bmd = mit->next();
-      substitutionCount.setSubstitutionModel(bmd->getModel());
-      //compute all nxy first:
-      VVVdouble nxyt(nbTypes);
-      for (size_t t = 0; t < nbTypes; ++t)
+      VVdouble* likelihoodsFatherConstantPart_i = &likelihoodsFatherConstantPart[i];
+      likelihoodsFatherConstantPart_i->resize(nbClasses);
+      for (size_t c = 0; c < nbClasses; ++c)
       {
-        nxyt[t].resize(nbStates);
-        Matrix<double>* nxy = substitutionCount.getAllNumbersOfSubstitutions(d, t + 1);
-        for (size_t x = 0; x < nbStates; ++x) {
-          nxyt[t][x].resize(nbStates);
-          for (size_t y = 0; y < nbStates; ++y) {
-            nxyt[t][x][y] = (*nxy)(x, y);
-          }
+        Vdouble* likelihoodsFatherConstantPart_i_c = &(*likelihoodsFatherConstantPart_i)[c];
+        likelihoodsFatherConstantPart_i_c->resize(nbStates);
+        double rc = rDist->getProbability(c);
+        for (size_t s = 0; s < nbStates; ++s)
+        {
+          // (* likelihoodsFatherConstantPart_i_c)[s] = rc * model->freq(s);
+          // freq is already accounted in the array
+          (*likelihoodsFatherConstantPart_i_c)[s] = rc;
         }
-        delete nxy;
-      }
-      //Now loop over sites:
-      auto_ptr<TreeLikelihood::SiteIterator> sit(bmd->getNewSiteIterator());
-      while (sit->hasNext())
-      {
-        size_t i = sit->next();
-        size_t fatherState = fatherStates[i];
-        size_t nodeState   = nodeStates[i];
-        if (fatherState >= nbStates || nodeState >= nbStates)
-          for (size_t t = 0; t < nbTypes; ++t)
-            substitutionsForCurrentNode[i][t] = 0; // To be conservative! Only in case there are generic characters.
-        else
-          for (size_t t = 0; t < nbTypes; ++t)
-            substitutionsForCurrentNode[i][t] = nxyt[t][fatherState][nodeState];
       }
     }
-    
-    //Now we just have to copy the substitutions into the result vector:
-    for (size_t i = 0; i < nbSites; i++)
-      for (size_t t = 0; t < nbTypes; t++)
-        (*substitutions)(l, i, t) = substitutionsForCurrentNode[(*rootPatternLinks)[i]][t];
-  }
-  if (verbose)
-  {
-    if (ApplicationTools::message) *ApplicationTools::message << " ";
-    ApplicationTools::displayTaskDone();
-  }
-  return substitutions;
-}
 
-/**************************************************************************************************/
+    // First, what will remain constant:
+    size_t nbSons =  father->getNumberOfSons();
+    for (size_t n = 0; n < nbSons; ++n)
+    {
+      const Node* currentSon = father->getSon(n);
+      if (currentSon->getId() != currentNode->getId())
+      {
+        const VVVdouble* likelihoodsFather_son = &drtl.getLikelihoodData()->getLikelihoodArray(father->getId(), currentSon->getId());
 
-ProbabilisticSubstitutionMapping* SubstitutionMappingTools::computeSubstitutionVectorsMarginal(
-  const DRTreeLikelihood& drtl,
-  SubstitutionCount& substitutionCount,
-  bool verbose) throw (Exception)
-{
-  //Preamble:
-  if (!drtl.isInitialized()) throw Exception("SubstitutionMappingTools::computeSubstitutionVectorsMarginal(). Likelihood object is not initialized.");
-                                   
-  //A few variables we'll need:
-  
-  const TreeTemplate<Node>tree(drtl.getTree());
-  const SiteContainer*    sequences = drtl.getData();
-  const DiscreteDistribution* rDist = drtl.getRateDistribution();
-    
-  size_t nbSites         = sequences->getNumberOfSites();
-  size_t nbDistinctSites = drtl.getLikelihoodData()->getNumberOfDistinctSites();
-  size_t nbStates        = sequences->getAlphabet()->getSize();
-  size_t nbClasses       = rDist->getNumberOfCategories();
-  size_t nbTypes         = substitutionCount.getNumberOfSubstitutionTypes();
-  vector<const Node*> nodes    = tree.getNodes();
-  const vector<size_t>* rootPatternLinks
-                               = &drtl.getLikelihoodData()->getRootArrayPositions();
-  nodes.pop_back(); // Remove root node.
-  size_t nbNodes = nodes.size();
-  
-  // We create a new ProbabilisticSubstitutionMapping object:
+        // Now iterate over all site partitions:
+        auto_ptr<TreeLikelihood::ConstBranchModelIterator> mit(drtl.getNewBranchModelIterator(currentSon->getId()));
+        VVVdouble pxy;
+        bool first;
+        while (mit->hasNext())
+        {
+          TreeLikelihood::ConstBranchModelDescription* bmd = mit->next();
+          auto_ptr<TreeLikelihood::SiteIterator> sit(bmd->getNewSiteIterator());
+          first = true;
+          while (sit->hasNext())
+          {
+            size_t i = sit->next();
+            // We retrieve the transition probabilities for this site partition:
+            if (first)
+            {
+              pxy = drtl.getTransitionProbabilitiesPerRateClass(currentSon->getId(), i);
+              first = false;
+            }
+            const VVdouble* likelihoodsFather_son_i = &(*likelihoodsFather_son)[i];
+            VVdouble* likelihoodsFatherConstantPart_i = &likelihoodsFatherConstantPart[i];
+            for (size_t c = 0; c < nbClasses; ++c)
+            {
+              const Vdouble* likelihoodsFather_son_i_c = &(*likelihoodsFather_son_i)[c];
+              Vdouble* likelihoodsFatherConstantPart_i_c = &(*likelihoodsFatherConstantPart_i)[c];
+              VVdouble* pxy_c = &pxy[c];
+              for (size_t x = 0; x < nbStates; ++x)
+              {
+                Vdouble* pxy_c_x = &(*pxy_c)[x];
+                double likelihood = 0.;
+                for (size_t y = 0; y < nbStates; ++y)
+                {
+                  likelihood += (*pxy_c_x)[y] * (*likelihoodsFather_son_i_c)[y];
+                }
+                (*likelihoodsFatherConstantPart_i_c)[x] *= likelihood;
+              }
+            }
+          }
+        }
+      }
+    }
+    if (father->hasFather())
+    {
+      const Node* currentSon = father->getFather();
+      const VVVdouble* likelihoodsFather_son = &drtl.getLikelihoodData()->getLikelihoodArray(father->getId(), currentSon->getId());
+      // Now iterate over all site partitions:
+      auto_ptr<TreeLikelihood::ConstBranchModelIterator> mit(drtl.getNewBranchModelIterator(father->getId()));
+      VVVdouble pxy;
+      bool first;
+      while (mit->hasNext())
+      {
+        TreeLikelihood::ConstBranchModelDescription* bmd = mit->next();
+        auto_ptr<TreeLikelihood::SiteIterator> sit(bmd->getNewSiteIterator());
+        first = true;
+        while (sit->hasNext())
+        {
+          size_t i = sit->next();
+          // We retrieve the transition probabilities for this site partition:
+          if (first)
+          {
+            pxy = drtl.getTransitionProbabilitiesPerRateClass(father->getId(), i);
+            first = false;
+          }
+          const VVdouble* likelihoodsFather_son_i = &(*likelihoodsFather_son)[i];
+          VVdouble* likelihoodsFatherConstantPart_i = &likelihoodsFatherConstantPart[i];
+          for (size_t c = 0; c < nbClasses; ++c)
+          {
+            const Vdouble* likelihoodsFather_son_i_c = &(*likelihoodsFather_son_i)[c];
+            Vdouble* likelihoodsFatherConstantPart_i_c = &(*likelihoodsFatherConstantPart_i)[c];
+            VVdouble* pxy_c = &pxy[c];
+            for (size_t x = 0; x < nbStates; ++x)
+            {
+              double likelihood = 0.;
+              for (size_t y = 0; y < nbStates; ++y)
+              {
+                Vdouble* pxy_c_x = &(*pxy_c)[y];
+                likelihood += (*pxy_c_x)[x] * (*likelihoodsFather_son_i_c)[y];
+              }
+              (*likelihoodsFatherConstantPart_i_c)[x] *= likelihood;
+            }
+          }
+        }
+      }
+    }
+    else
+    {
+      // Account for root frequencies:
+      for (size_t i = 0; i < nbDistinctSites; ++i)
+      {
+        vector<double> freqs = drtl.getRootFrequencies(i);
+        VVdouble* likelihoodsFatherConstantPart_i = &likelihoodsFatherConstantPart[i];
+        for (size_t c = 0; c < nbClasses; ++c)
+        {
+          Vdouble* likelihoodsFatherConstantPart_i_c = &(*likelihoodsFatherConstantPart_i)[c];
+          for (size_t x = 0; x < nbStates; ++x)
+          {
+            (*likelihoodsFatherConstantPart_i_c)[x] *= freqs[x];
+          }
+        }
+      }
+    }
+
+    // Then, we deal with the node of interest.
+    // We first average uppon 'y' to save computations, and then uppon 'x'.
+    // ('y' is the state at 'node' and 'x' the state at 'father'.)
+
+    // Iterate over all site partitions:
+    const VVVdouble* likelihoodsFather_node = &drtl.getLikelihoodData()->getLikelihoodArray(father->getId(), currentNode->getId());
+    auto_ptr<TreeLikelihood::ConstBranchModelIterator> mit(drtl.getNewBranchModelIterator(currentNode->getId()));
+    VVVdouble pxy;
+    bool first;
+    while (mit->hasNext())
+    {
+      TreeLikelihood::ConstBranchModelDescription* bmd = mit->next();
+      substitutionCount.setSubstitutionModel(bmd->getModel());
+      // compute all nxy first:
+      VVVVdouble nxy(nbClasses);
+      for (size_t c = 0; c < nbClasses; ++c)
+      {
+        double rc = rcRates[c];
+        VVVdouble* nxy_c = &nxy[c];
+        nxy_c->resize(nbTypes);
+        for (size_t t = 0; t < nbTypes; ++t)
+        {
+          VVdouble* nxy_c_t = &(*nxy_c)[t];
+          nxy_c_t->resize(nbStates);
+          Matrix<double>* nijt = substitutionCount.getAllNumbersOfSubstitutions(d * rc, t + 1);
+          for (size_t x = 0; x < nbStates; ++x)
+          {
+            Vdouble* nxy_c_t_x = &(*nxy_c_t)[x];
+            nxy_c_t_x->resize(nbStates);
+            for (size_t y = 0; y < nbStates; ++y)
+            {
+              (*nxy_c_t_x)[y] = (*nijt)(x, y);
+            }
+          }
+          delete nijt;
+        }
+      }
+
+      // Now loop over sites:
+      auto_ptr<TreeLikelihood::SiteIterator> sit(bmd->getNewSiteIterator());
+      first = true;
+      while (sit->hasNext())
+      {
+        size_t i = sit->next();
+        // We retrieve the transition probabilities and substitution counts for this site partition:
+        if (first)
+        {
+          pxy = drtl.getTransitionProbabilitiesPerRateClass(currentNode->getId(), i);
+          first = false;
+        }
+        const VVdouble* likelihoodsFather_node_i = &(*likelihoodsFather_node)[i];
+        VVdouble* likelihoodsFatherConstantPart_i = &likelihoodsFatherConstantPart[i];
+        RowMatrix<double> pairProbabilities(nbStates, nbStates);
+        MatrixTools::fill(pairProbabilities, 0.);
+        VVVdouble subsCounts(nbStates);
+        for (size_t j = 0; j < nbStates; ++j)
+        {
+          subsCounts[j].resize(nbStates);
+          for (size_t k = 0; k < nbStates; ++k)
+          {
+            subsCounts[j][k].resize(nbTypes);
+          }
+        }
+        for (size_t c = 0; c < nbClasses; ++c)
+        {
+          const Vdouble* likelihoodsFather_node_i_c = &(*likelihoodsFather_node_i)[c];
+          Vdouble* likelihoodsFatherConstantPart_i_c = &(*likelihoodsFatherConstantPart_i)[c];
+          const VVdouble* pxy_c = &pxy[c];
+          VVVdouble* nxy_c = &nxy[c];
+          for (size_t x = 0; x < nbStates; ++x)
+          {
+            double* likelihoodsFatherConstantPart_i_c_x = &(*likelihoodsFatherConstantPart_i_c)[x];
+            const Vdouble* pxy_c_x = &(*pxy_c)[x];
+            for (size_t y = 0; y < nbStates; ++y)
+            {
+              double likelihood_cxy = (*likelihoodsFatherConstantPart_i_c_x)
+                                      * (*pxy_c_x)[y]
+                                      * (*likelihoodsFather_node_i_c)[y];
+              pairProbabilities(x, y) += likelihood_cxy; // Sum over all rate classes.
+              for (size_t t = 0; t < nbTypes; ++t)
+              {
+                subsCounts[x][y][t] += likelihood_cxy * (*nxy_c)[t][x][y];
+              }
+            }
+          }
+        }
+        // Now the vector computation:
+        // Here we do not average over all possible pair of ancestral states,
+        // We only consider the one with max likelihood:
+        vector<size_t> xy = MatrixTools::whichMax(pairProbabilities);
+        for (size_t t = 0; t < nbTypes; ++t)
+        {
+          substitutionsForCurrentNode[i][t] += subsCounts[xy[0]][xy[1]][t] / pairProbabilities(xy[0], xy[1]);
+        }
+      }
+    }
+    // Now we just have to copy the substitutions into the result vector:
+    for (size_t i = 0; i < nbSites; i++)
+    {
+      for (size_t t = 0; t < nbTypes; t++)
+      {
+        (*substitutions)(l, i, t) = substitutionsForCurrentNode[(*rootPatternLinks)[i]][t];
+      }
+    }
+  }
+  if (verbose)
+  {
+    if (ApplicationTools::message)
+      *ApplicationTools::message << " ";
+    ApplicationTools::displayTaskDone();
+  }
+  return substitutions;
+}
+
+/**************************************************************************************************/
+
+ProbabilisticSubstitutionMapping* SubstitutionMappingTools::computeSubstitutionVectorsNoAveragingMarginal(
+  const DRTreeLikelihood& drtl,
+  SubstitutionCount& substitutionCount,
+  bool verbose) throw (Exception)
+{
+  // Preamble:
+  if (!drtl.isInitialized())
+    throw Exception("SubstitutionMappingTools::computeSubstitutionVectorsNoAveragingMarginal(). Likelihood object is not initialized.");
+
+  // A few variables we'll need:
+
+  const TreeTemplate<Node> tree(drtl.getTree());
+  const SiteContainer*    sequences = drtl.getData();
+  const DiscreteDistribution* rDist = drtl.getRateDistribution();
+  const Alphabet*             alpha = sequences->getAlphabet();
+
+  size_t nbSites         = sequences->getNumberOfSites();
+  size_t nbDistinctSites = drtl.getLikelihoodData()->getNumberOfDistinctSites();
+  size_t nbStates        = alpha->getSize();
+  size_t nbTypes         = substitutionCount.getNumberOfSubstitutionTypes();
+  vector<const Node*> nodes    = tree.getNodes();
+  const vector<size_t>* rootPatternLinks
+    = &drtl.getLikelihoodData()->getRootArrayPositions();
+  nodes.pop_back(); // Remove root node.
+  size_t nbNodes = nodes.size();
+
+  // We create a new ProbabilisticSubstitutionMapping object:
+  ProbabilisticSubstitutionMapping* substitutions = new ProbabilisticSubstitutionMapping(tree, &substitutionCount, nbSites);
+
+  // Compute the whole likelihood of the tree according to the specified model:
+
+  Vdouble rcRates = rDist->getCategories();
+
+  // Compute the number of substitutions for each class and each branch in the tree:
+  if (verbose)
+    ApplicationTools::displayTask("Compute marginal ancestral states");
+  MarginalAncestralStateReconstruction masr(&drtl);
+  map<int, vector<size_t> > ancestors = masr.getAllAncestralStates();
+  if (verbose)
+    ApplicationTools::displayTaskDone();
+
+  // Now we just have to compute the substitution vectors:
+  if (verbose)
+    ApplicationTools::displayTask("Compute substitution vectors", true);
+
+  for (size_t l = 0; l < nbNodes; l++)
+  {
+    const Node* currentNode = nodes[l];
+
+    const Node* father = currentNode->getFather();
+
+    double d = currentNode->getDistanceToFather();
+
+    vector<size_t> nodeStates = ancestors[currentNode->getId()]; // These are not 'true' ancestors ;)
+    vector<size_t> fatherStates = ancestors[father->getId()];
+
+    // For each node,
+    if (verbose)
+      ApplicationTools::displayGauge(l, nbNodes - 1);
+    VVdouble substitutionsForCurrentNode(nbDistinctSites);
+    for (size_t i = 0; i < nbDistinctSites; ++i)
+    {
+      substitutionsForCurrentNode[i].resize(nbTypes);
+    }
+
+    // Here, we have no likelihood computation to do!
+
+    // Then, we deal with the node of interest.
+    // ('y' is the state at 'node' and 'x' the state at 'father'.)
+    // Iterate over all site partitions:
+    auto_ptr<TreeLikelihood::ConstBranchModelIterator> mit(drtl.getNewBranchModelIterator(currentNode->getId()));
+    while (mit->hasNext())
+    {
+      TreeLikelihood::ConstBranchModelDescription* bmd = mit->next();
+      substitutionCount.setSubstitutionModel(bmd->getModel());
+      // compute all nxy first:
+      VVVdouble nxyt(nbTypes);
+      for (size_t t = 0; t < nbTypes; ++t)
+      {
+        nxyt[t].resize(nbStates);
+        Matrix<double>* nxy = substitutionCount.getAllNumbersOfSubstitutions(d, t + 1);
+        for (size_t x = 0; x < nbStates; ++x)
+        {
+          nxyt[t][x].resize(nbStates);
+          for (size_t y = 0; y < nbStates; ++y)
+          {
+            nxyt[t][x][y] = (*nxy)(x, y);
+          }
+        }
+        delete nxy;
+      }
+      // Now loop over sites:
+      auto_ptr<TreeLikelihood::SiteIterator> sit(bmd->getNewSiteIterator());
+      while (sit->hasNext())
+      {
+        size_t i = sit->next();
+        size_t fatherState = fatherStates[i];
+        size_t nodeState   = nodeStates[i];
+        if (fatherState >= nbStates || nodeState >= nbStates)
+          for (size_t t = 0; t < nbTypes; ++t)
+          {
+            substitutionsForCurrentNode[i][t] = 0;
+          }                                                    // To be conservative! Only in case there are generic characters.
+        else
+          for (size_t t = 0; t < nbTypes; ++t)
+          {
+            substitutionsForCurrentNode[i][t] = nxyt[t][fatherState][nodeState];
+          }
+      }
+    }
+
+    // Now we just have to copy the substitutions into the result vector:
+    for (size_t i = 0; i < nbSites; i++)
+    {
+      for (size_t t = 0; t < nbTypes; t++)
+      {
+        (*substitutions)(l, i, t) = substitutionsForCurrentNode[(*rootPatternLinks)[i]][t];
+      }
+    }
+  }
+  if (verbose)
+  {
+    if (ApplicationTools::message)
+      *ApplicationTools::message << " ";
+    ApplicationTools::displayTaskDone();
+  }
+  return substitutions;
+}
+
+/**************************************************************************************************/
+
+ProbabilisticSubstitutionMapping* SubstitutionMappingTools::computeSubstitutionVectorsMarginal(
+  const DRTreeLikelihood& drtl,
+  SubstitutionCount& substitutionCount,
+  bool verbose) throw (Exception)
+{
+  // Preamble:
+  if (!drtl.isInitialized())
+    throw Exception("SubstitutionMappingTools::computeSubstitutionVectorsMarginal(). Likelihood object is not initialized.");
+
+  // A few variables we'll need:
+
+  const TreeTemplate<Node> tree(drtl.getTree());
+  const SiteContainer*    sequences = drtl.getData();
+  const DiscreteDistribution* rDist = drtl.getRateDistribution();
+
+  size_t nbSites         = sequences->getNumberOfSites();
+  size_t nbDistinctSites = drtl.getLikelihoodData()->getNumberOfDistinctSites();
+  size_t nbStates        = sequences->getAlphabet()->getSize();
+  size_t nbClasses       = rDist->getNumberOfCategories();
+  size_t nbTypes         = substitutionCount.getNumberOfSubstitutionTypes();
+  vector<const Node*> nodes    = tree.getNodes();
+  const vector<size_t>* rootPatternLinks
+    = &drtl.getLikelihoodData()->getRootArrayPositions();
+  nodes.pop_back(); // Remove root node.
+  size_t nbNodes = nodes.size();
+
+  // We create a new ProbabilisticSubstitutionMapping object:
   ProbabilisticSubstitutionMapping* substitutions = new ProbabilisticSubstitutionMapping(tree, &substitutionCount, nbSites);
-                                     
+
   // Compute the whole likelihood of the tree according to the specified model:
-  
+
   Vdouble rcProbs = rDist->getProbabilities();
   Vdouble rcRates = rDist->getCategories();
 
-  //II) Compute the number of substitutions for each class and each branch in the tree:
-  if (verbose) ApplicationTools::displayTask("Compute marginal node-pairs likelihoods", true);
-  
+  // II) Compute the number of substitutions for each class and each branch in the tree:
+  if (verbose)
+    ApplicationTools::displayTask("Compute marginal node-pairs likelihoods", true);
+
   for (size_t l = 0; l < nbNodes; l++)
   {
     const Node* currentNode = nodes[l];
-    
+
     const Node* father = currentNode->getFather();
 
     double d = currentNode->getDistanceToFather();
-    
-    //For each node,
-    if (verbose) ApplicationTools::displayGauge(l, nbNodes-1, '>');
+
+    // For each node,
+    if (verbose)
+      ApplicationTools::displayGauge(l, nbNodes - 1);
     VVdouble substitutionsForCurrentNode(nbDistinctSites);
     for (size_t i = 0; i < nbDistinctSites; ++i)
+    {
       substitutionsForCurrentNode[i].resize(nbTypes);
+    }
 
     // Then, we deal with the node of interest.
     // ('y' is the state at 'node' and 'x' the state at 'father'.)
     VVVdouble probsNode   = DRTreeLikelihoodTools::getPosteriorProbabilitiesForEachStateForEachRate(drtl, currentNode->getId());
     VVVdouble probsFather = DRTreeLikelihoodTools::getPosteriorProbabilitiesForEachStateForEachRate(drtl, father->getId());
 
-    //Iterate over all site partitions:
+    // Iterate over all site partitions:
     auto_ptr<TreeLikelihood::ConstBranchModelIterator> mit(drtl.getNewBranchModelIterator(currentNode->getId()));
     while (mit->hasNext())
     {
       TreeLikelihood::ConstBranchModelDescription* bmd = mit->next();
       substitutionCount.setSubstitutionModel(bmd->getModel());
-      //compute all nxy first:
+      // compute all nxy first:
       VVVVdouble nxy(nbClasses);
       for (size_t c = 0; c < nbClasses; ++c)
       {
@@ -829,13 +1201,13 @@ ProbabilisticSubstitutionMapping* SubstitutionMappingTools::computeSubstitutionV
         }
       }
 
-      //Now loop over sites:
+      // Now loop over sites:
       auto_ptr<TreeLikelihood::SiteIterator> sit(bmd->getNewSiteIterator());
       while (sit->hasNext())
       {
         size_t i = sit->next();
-        VVdouble* probsNode_i   = & probsNode[i];
-        VVdouble* probsFather_i = & probsFather[i];
+        VVdouble* probsNode_i   = &probsNode[i];
+        VVdouble* probsFather_i = &probsFather[i];
         for (size_t c = 0; c < nbClasses; ++c)
         {
           Vdouble* probsNode_i_c   = &(*probsNode_i)[c];
@@ -847,29 +1219,35 @@ ProbabilisticSubstitutionMapping* SubstitutionMappingTools::computeSubstitutionV
             {
               double prob_cxy = (*probsFather_i_c)[x] * (*probsNode_i_c)[y];
               // Now the vector computation:
-              for (size_t t = 0; t < nbTypes; ++t) {
+              for (size_t t = 0; t < nbTypes; ++t)
+              {
                 substitutionsForCurrentNode[i][t] += prob_cxy * (*nxy_c)[t][x][y];
                 //                                   <------>   <--------------->
-                // Posterior probability                 |                | 
+                // Posterior probability                 |                |
                 // for site i and rate class c *         |                |
                 // likelihood for this site--------------+                |
                 //                                                        |
-                //Substitution function for site i and rate class c-------+
+                // Substitution function for site i and rate class c-------+
               }
             }
           }
         }
       }
     }
-    
-    //Now we just have to copy the substitutions into the result vector:
-    for (size_t i = 0; i < nbSites; ++i)
-      for (size_t t = 0; t < nbTypes; ++t)
-        (*substitutions)(l, i, t) = substitutionsForCurrentNode[(* rootPatternLinks)[i]][t];
+
+    // Now we just have to copy the substitutions into the result vector:
+    for (size_t i = 0; i < nbSites; ++i)
+    {
+      for (size_t t = 0; t < nbTypes; ++t)
+      {
+        (*substitutions)(l, i, t) = substitutionsForCurrentNode[(*rootPatternLinks)[i]][t];
+      }
+    }
   }
   if (verbose)
   {
-    if (ApplicationTools::message) *ApplicationTools::message << " ";
+    if (ApplicationTools::message)
+      *ApplicationTools::message << " ";
     ApplicationTools::displayTaskDone();
   }
   return substitutions;
@@ -882,9 +1260,10 @@ void SubstitutionMappingTools::writeToStream(
   const SiteContainer& sites,
   size_t type,
   ostream& out)
-  throw (IOException) 
+throw (IOException)
 {
-  if (!out) throw IOException("SubstitutionMappingTools::writeToFile. Can't write to stream.");
+  if (!out)
+    throw IOException("SubstitutionMappingTools::writeToFile. Can't write to stream.");
   out << "Branches";
   out << "\tMean";
   for (size_t i = 0; i < substitutions.getNumberOfSites(); i++)
@@ -892,7 +1271,7 @@ void SubstitutionMappingTools::writeToStream(
     out << "\tSite" << sites.getSite(i).getPosition();
   }
   out << endl;
-  
+
   for (size_t j = 0; j < substitutions.getNumberOfBranches(); j++)
   {
     out << substitutions.getNode(j)->getId() << "\t" << substitutions.getNode(j)->getDistanceToFather();
@@ -907,15 +1286,15 @@ void SubstitutionMappingTools::writeToStream(
 /**************************************************************************************************/
 
 void SubstitutionMappingTools::readFromStream(istream& in, ProbabilisticSubstitutionMapping& substitutions, size_t type)
-  throw (IOException)
+throw (IOException)
 {
   try
   {
     DataTable* data = DataTable::read(in, "\t", true, -1);
     vector<string> ids = data->getColumn(0);
-    data->deleteColumn(0);//Remove ids
-    data->deleteColumn(0);//Remove means
-    //Now parse the table:
+    data->deleteColumn(0); // Remove ids
+    data->deleteColumn(0); // Remove means
+    // Now parse the table:
     size_t nbSites = data->getNumberOfColumns();
     substitutions.setNumberOfSites(nbSites);
     size_t nbBranches = data->getNumberOfRows();
@@ -928,16 +1307,18 @@ void SubstitutionMappingTools::readFromStream(istream& in, ProbabilisticSubstitu
         substitutions(br, j, type) = TextTools::toDouble((*data)(i, j));
       }
     }
-    //Parse the header:
+    // Parse the header:
     for (size_t i = 0; i < nbSites; i++)
     {
       string siteTxt = data->getColumnName(i);
       int site = 0;
-      if (siteTxt.substr(0,4) == "Site") site = TextTools::to<int>(siteTxt.substr(4));
-      else site = TextTools::to<int>(siteTxt);
+      if (siteTxt.substr(0, 4) == "Site")
+        site = TextTools::to<int>(siteTxt.substr(4));
+      else
+        site = TextTools::to<int>(siteTxt);
       substitutions.setSitePosition(i, site);
     }
-    
+
     delete data;
   }
   catch (Exception& e)
@@ -947,15 +1328,17 @@ void SubstitutionMappingTools::readFromStream(istream& in, ProbabilisticSubstitu
 }
 
 /**************************************************************************************************/
-    
+
 vector<double> SubstitutionMappingTools::computeTotalSubstitutionVectorForSite(const SubstitutionMapping& smap, size_t siteIndex)
 {
   size_t nbBranches = smap.getNumberOfBranches();
   size_t nbTypes    = smap.getNumberOfSubstitutionTypes();
   Vdouble v(nbBranches);
-  for (size_t l = 0; l < nbBranches; ++l) {
+  for (size_t l = 0; l < nbBranches; ++l)
+  {
     v[l] = 0;
-    for (size_t t = 0; t < nbTypes; ++t) {
+    for (size_t t = 0; t < nbTypes; ++t)
+    {
       v[l] += smap(l, siteIndex, t);
     }
   }
@@ -967,9 +1350,11 @@ vector<double> SubstitutionMappingTools::computeTotalSubstitutionVectorForSite(c
 double SubstitutionMappingTools::computeNormForSite(const SubstitutionMapping& smap, size_t siteIndex)
 {
   double sumSquare = 0;
-  for (size_t l = 0; l < smap.getNumberOfBranches(); ++l) {
+  for (size_t l = 0; l < smap.getNumberOfBranches(); ++l)
+  {
     double sum = 0;
-    for (size_t t = 0; t < smap.getNumberOfSubstitutionTypes(); ++t) {
+    for (size_t t = 0; t < smap.getNumberOfSubstitutionTypes(); ++t)
+    {
       sum += smap(l, siteIndex, t);
     }
     sumSquare += sum * sum;
@@ -978,14 +1363,16 @@ double SubstitutionMappingTools::computeNormForSite(const SubstitutionMapping& s
 }
 
 /**************************************************************************************************/
-    
+
 vector<double> SubstitutionMappingTools::computeSumForBranch(const SubstitutionMapping& smap, size_t branchIndex)
 {
   size_t nbSites = smap.getNumberOfSites();
   size_t nbTypes = smap.getNumberOfSubstitutionTypes();
   Vdouble v(nbTypes, 0);
-  for (size_t i = 0; i < nbSites; ++i) {
-    for (size_t t = 0; t < nbTypes; ++t) {
+  for (size_t i = 0; i < nbSites; ++i)
+  {
+    for (size_t t = 0; t < nbTypes; ++t)
+    {
       v[t] += smap(branchIndex, i, t);
     }
   }
@@ -999,8 +1386,10 @@ vector<double> SubstitutionMappingTools::computeSumForSite(const SubstitutionMap
   size_t nbBranches = smap.getNumberOfBranches();
   size_t nbTypes = smap.getNumberOfSubstitutionTypes();
   Vdouble v(nbTypes, 0);
-  for (size_t i = 0; i < nbBranches; ++i) {
-    for (size_t t = 0; t < nbTypes; ++t) {
+  for (size_t i = 0; i < nbBranches; ++i)
+  {
+    for (size_t t = 0; t < nbTypes; ++t)
+    {
       v[t] += smap(i, siteIndex, t);
     }
   }
@@ -1008,4 +1397,544 @@ vector<double> SubstitutionMappingTools::computeSumForSite(const SubstitutionMap
 }
 
 /**************************************************************************************************/
+vector< vector<double> > SubstitutionMappingTools::getCountsPerBranch(
+  DRTreeLikelihood& drtl,
+  const vector<int>& ids,
+  SubstitutionModel* model,
+  const SubstitutionRegister& reg,
+  double threshold,
+  bool verbose)
+{
+  SubstitutionRegister* reg2 = reg.clone();
+
+  auto_ptr<SubstitutionCount> count(new UniformizationSubstitutionCount(model, reg2));
+
+  auto_ptr<ProbabilisticSubstitutionMapping> mapping(SubstitutionMappingTools::computeSubstitutionVectors(drtl, ids, *count, false));
+
+  vector< vector<double> > counts(ids.size());
+  size_t nbSites = mapping->getNumberOfSites();
+  size_t nbTypes = mapping->getNumberOfSubstitutionTypes();
+
+  for (size_t k = 0; k < ids.size(); ++k)
+  {
+    vector<double> countsf(nbTypes, 0);
+    vector<double> tmp(nbTypes, 0);
+    size_t nbIgnored = 0;
+    bool error = false;
+    for (size_t i = 0; !error && i < nbSites; ++i)
+    {
+      double s = 0;
+      for (size_t t = 0; t < nbTypes; ++t)
+      {
+        tmp[t] = (*mapping)(mapping->getNodeIndex(ids[k]), i, t);
+        error = isnan(tmp[t]);
+        if (error)
+          goto ERROR;
+        s += tmp[t];
+      }
+      if (threshold >= 0)
+      {
+        if (s <= threshold)
+          countsf += tmp;
+        else
+        {
+          nbIgnored++;
+        }
+      }
+      else
+      {
+        countsf += tmp;
+      }
+    }
+
+ERROR:
+    if (error)
+    {
+      // We do nothing. This happens for small branches.
+      if (verbose)
+        ApplicationTools::displayWarning("On branch " + TextTools::toString(ids[k]) + ", counts could not be computed.");
+      for (size_t t = 0; t < nbTypes; ++t)
+      {
+        countsf[t] = 0;
+      }
+    }
+    else
+    {
+      if (nbIgnored > 0)
+      {
+        if (verbose)
+          ApplicationTools::displayWarning("On branch " + TextTools::toString(ids[k]) + ", " + TextTools::toString(nbIgnored) + " sites (" + TextTools::toString(ceil(static_cast<double>(nbIgnored * 100) / static_cast<double>(nbSites))) + "%) have been ignored because they are presumably saturated.");
+      }
+    }
+
+    counts[k].resize(countsf.size());
+    for (size_t j = 0; j < countsf.size(); ++j)
+    {
+      counts[k][j] = countsf[j];
+    }
+  }
+
+  return counts;
+}
+
+/**************************************************************************************************/
+
+vector< vector<double> > SubstitutionMappingTools::getCountsPerBranch(
+  DRTreeLikelihood& drtl,
+  const vector<int>& ids,
+  const SubstitutionModelSet& modelSet,
+  const SubstitutionRegister& reg,
+  double threshold,
+  bool verbose)
+{
+  SubstitutionRegister* reg2 = reg.clone();
+
+  auto_ptr<SubstitutionCount> count(new UniformizationSubstitutionCount(modelSet.getModel(0), reg2));
+
+  auto_ptr<ProbabilisticSubstitutionMapping> mapping(SubstitutionMappingTools::computeSubstitutionVectors(drtl, modelSet, ids, *count, false));
+
+  vector< vector<double> > counts(ids.size());
+  size_t nbSites = mapping->getNumberOfSites();
+  size_t nbTypes = mapping->getNumberOfSubstitutionTypes();
+
+  for (size_t k = 0; k < ids.size(); ++k)
+  {
+    vector<double> countsf(nbTypes, 0);
+    vector<double> tmp(nbTypes, 0);
+    size_t nbIgnored = 0;
+    bool error = false;
+    for (size_t i = 0; !error && i < nbSites; ++i)
+    {
+      double s = 0;
+      for (size_t t = 0; t < nbTypes; ++t)
+      {
+        tmp[t] = (*mapping)(mapping->getNodeIndex(ids[k]), i, t);
+        error = isnan(tmp[t]);
+        if (error)
+          goto ERROR;
+        s += tmp[t];
+      }
+      if (threshold >= 0)
+      {
+        if (s <= threshold)
+          countsf += tmp;
+        else
+        {
+          nbIgnored++;
+        }
+      }
+      else
+      {
+        countsf += tmp;
+      }
+    }
+
+ERROR:
+    if (error)
+    {
+      // We do nothing. This happens for small branches.
+      if (verbose)
+        ApplicationTools::displayWarning("On branch " + TextTools::toString(ids[k]) + ", counts could not be computed.");
+      for (size_t t = 0; t < nbTypes; ++t)
+      {
+        countsf[t] = 0;
+      }
+    }
+    else
+    {
+      if (nbIgnored > 0)
+      {
+        if (verbose)
+          ApplicationTools::displayWarning("On branch " + TextTools::toString(ids[k]) + ", " + TextTools::toString(nbIgnored) + " sites (" + TextTools::toString(ceil(static_cast<double>(nbIgnored * 100) / static_cast<double>(nbSites))) + "%) have been ignored because they are presumably saturated.");
+      }
+    }
+
+    counts[k].resize(countsf.size());
+    for (size_t j = 0; j < countsf.size(); ++j)
+    {
+      counts[k][j] = countsf[j];
+    }
+  }
+
+  return counts;
+}
+
+/**************************************************************************************************/
+
+vector< vector<double> > SubstitutionMappingTools::getNormalizationsPerBranch(
+  DRTreeLikelihood& drtl,
+  const vector<int>& ids,
+  const SubstitutionModel* nullModel,
+  const SubstitutionRegister& reg,
+  bool verbose)
+{
+  size_t nbTypes = reg.getNumberOfSubstitutionTypes();
+  size_t nbStates = nullModel->getAlphabet()->getSize();
+  size_t nbSites = drtl.getNumberOfSites();
+  vector<int> supportedStates = nullModel->getAlphabetStates();
+
+  // compute the AlphabetIndex for each substitutionType
+  vector<UserAlphabetIndex1 > usai(nbTypes, UserAlphabetIndex1(nullModel->getAlphabet()));
+
+  for (size_t i = 0; i < nbStates; i++)
+  {
+    for (size_t j = 0; j < nbStates; j++)
+    {
+      if (i != j)
+      {
+        size_t nbt = reg.getType(i, j);
+        if (nbt != 0)
+          usai[nbt - 1].setIndex(supportedStates[i], usai[nbt - 1].getIndex(supportedStates[i]) + nullModel->Qij(i, j));
+      }
+    }
+  }
+
+  // compute the normalization for each substitutionType
+  vector< vector<double> > rewards(ids.size());
+
+  for (size_t k = 0; k < ids.size(); ++k)
+  {
+    rewards[k].resize(nbTypes);
+  }
+
+  for (size_t nbt = 0; nbt < nbTypes; nbt++)
+  {
+    auto_ptr<Reward> reward(new DecompositionReward(nullModel, &usai[nbt]));
+
+    auto_ptr<ProbabilisticRewardMapping> mapping(RewardMappingTools::computeRewardVectors(drtl, ids, *reward, false));
+
+    for (size_t k = 0; k < ids.size(); ++k)
+    {
+      double s = 0;
+      for (size_t i = 0; i < nbSites; ++i)
+      {
+        double tmp = (*mapping)(k, i);
+        if (isnan(tmp))
+        {
+          if (verbose)
+            ApplicationTools::displayWarning("On branch " + TextTools::toString(ids[k]) + ", reward for type " + reg.getTypeName(nbt + 1) + " could not be computed.");
+          s = 0;
+          break;
+        }
+        s += tmp;
+      }
+      rewards[k][nbt] = s;
+    }
+    reward.release();
+    mapping.release();
+  }
+  return rewards;
+}
+
+/**************************************************************************************************/
+
+vector< vector<double> > SubstitutionMappingTools::getNormalizationsPerBranch(
+  DRTreeLikelihood& drtl,
+  const vector<int>& ids,
+  const SubstitutionModelSet* nullModelSet,
+  const SubstitutionRegister& reg,
+  bool verbose)
+{
+  size_t nbTypes = reg.getNumberOfSubstitutionTypes();
+  size_t nbStates = nullModelSet->getAlphabet()->getSize();
+  size_t nbSites = drtl.getNumberOfSites();
+  size_t nbModels = nullModelSet->getNumberOfModels();
+
+  // compute the AlphabetIndex for each substitutionType
+  // compute the normalization for each substitutionType
+  vector< vector<double> > rewards(ids.size());
+
+  for (size_t k = 0; k < ids.size(); ++k)
+  {
+    rewards[k].resize(nbTypes);
+  }
+
+  vector<UserAlphabetIndex1 >  usai(nbTypes, UserAlphabetIndex1(nullModelSet->getAlphabet()));
+
+  for (size_t nbm = 0; nbm < nbModels; nbm++)
+  {
+    vector<int> mids = VectorTools::vectorIntersection(ids, nullModelSet->getNodesWithModel(nbm));
+    
+    if (mids.size()>0)
+    {
+      const SubstitutionModel* modn = nullModelSet->getModel(nbm);
+      vector<int> supportedStates = modn->getAlphabetStates();
+
+      for (size_t nbt = 0; nbt < nbTypes; nbt++)
+        for (size_t i = 0; i < nbStates; i++)
+          usai[nbt].setIndex(supportedStates[i], 0);
+
+      for (size_t i = 0; i < nbStates; i++)
+      {
+        for (size_t j = 0; j < nbStates; j++)
+        {
+          if (i != j)
+          {
+            size_t nbt = reg.getType(i, j);
+            if (nbt != 0)
+              usai[nbt - 1].setIndex(supportedStates[i], usai[nbt - 1].getIndex(supportedStates[i]) + modn->Qij(i, j));
+          }
+        }
+      }
+
+      for (size_t nbt = 0; nbt < nbTypes; nbt++)
+      {
+        auto_ptr<Reward> reward(new DecompositionReward(nullModelSet->getModel(nbm), &usai[nbt]));
+        
+        auto_ptr<ProbabilisticRewardMapping> mapping(RewardMappingTools::computeRewardVectors(drtl, mids, *reward, false));
+        
+        for (size_t k = 0; k < mids.size(); k++)
+        {
+          double s = 0;
+          for (size_t i = 0; i < nbSites; ++i)
+          {
+            double tmp = (*mapping)(mapping->getNodeIndex(mids[k]), i);
+            if (isnan(tmp))
+            {
+              if (verbose)
+                ApplicationTools::displayWarning("On branch " + TextTools::toString(mids[k]) + ", reward for type " + reg.getTypeName(nbt + 1) + " could not be computed.");
+              s = 0;
+              break;
+            }
+            else
+              s += tmp;
+          }
+          
+          rewards[VectorTools::which(ids, mids[k])][nbt] = s;
+        }
+        reward.release();
+        mapping.release();
+      }
+    }
+  }
+
+  return rewards;
+}
+
+/**************************************************************************************************/
+
+vector< vector<double> > SubstitutionMappingTools::getNormalizedCountsPerBranch(
+  DRTreeLikelihood& drtl,
+  const vector<int>& ids,
+  SubstitutionModel* model,
+  SubstitutionModel* nullModel,
+  const SubstitutionRegister& reg,
+  bool verbose)
+{
+  vector< vector<double> > counts;
+  vector< vector<double> > factors;
+
+  counts = getCountsPerBranch(drtl, ids, model, reg, -1, verbose);
+  factors = getNormalizationsPerBranch(drtl, ids, nullModel, reg, verbose);
+
+  size_t nbTypes = counts[0].size();
+
+  for (size_t k = 0; k < ids.size(); ++k)
+  {
+    for (size_t t = 0; t < nbTypes; ++t)
+    {
+      if (factors[k][t] != 0)
+        counts[k][t] /= factors[k][t];
+    }
+  }
+
+  // Multiply by the lengths of the branches of the input tree
+
+  const TreeTemplate<Node> tree(drtl.getTree());
+
+  for (size_t k = 0; k < ids.size(); ++k)
+  {
+    double l = tree.getNode(ids[k])->getDistanceToFather();
+    for (size_t t = 0; t < nbTypes; ++t)
+    {
+      counts[k][t] *= l;
+    }
+  }
+
+  return counts;
+}
+
+/**************************************************************************************************/
+
+vector< vector<double> > SubstitutionMappingTools::getNormalizedCountsPerBranch(
+  DRTreeLikelihood& drtl,
+  const vector<int>& ids,
+  SubstitutionModelSet* modelSet,
+  SubstitutionModelSet* nullModelSet,
+  const SubstitutionRegister& reg,
+  bool verbose)
+{
+  vector< vector<double> > counts;
+  vector< vector<double> > factors;
+
+  counts = getCountsPerBranch(drtl, ids, modelSet->getModel(0), reg, -1, verbose);
+  factors = getNormalizationsPerBranch(drtl, ids, nullModelSet, reg, verbose);
+
+  size_t nbTypes = counts[0].size();
+
+  for (size_t k = 0; k < ids.size(); ++k)
+  {
+    for (size_t t = 0; t < nbTypes; ++t)
+    {
+      if (factors[k][t] != 0)
+        counts[k][t] /= factors[k][t];
+    }
+  }
+
+  // Multiply by the lengths of the branches of the input tree
+
+  const TreeTemplate<Node> tree(drtl.getTree());
+
+  for (size_t k = 0; k < ids.size(); ++k)
+  {
+    double l = tree.getNode(ids[k])->getDistanceToFather();
+    for (size_t t = 0; t < nbTypes; ++t)
+    {
+      counts[k][t] *= l;
+    }
+  }
+
+  return counts;
+}
+
+/**************************************************************************************************/
+
+vector< vector<double> > SubstitutionMappingTools::getRelativeCountsPerBranch(
+  DRTreeLikelihood& drtl,
+  const vector<int>& ids,
+  SubstitutionModel* model,
+  const SubstitutionRegister& reg,
+  bool stationarity,
+  double threshold)
+{
+  vector< vector<double> > counts = getCountsPerBranch(drtl, ids, model, reg, threshold);
+
+  const CategorySubstitutionRegister* creg;
+  if (!stationarity)
+  {
+    try
+    {
+      creg = &dynamic_cast<const CategorySubstitutionRegister&>(reg);
+    }
+    catch (Exception& ex)
+    {
+      throw Exception("The stationarity option can only be used with a category substitution register.");
+    }
+
+    size_t nbTypes = counts[0].size();
+
+    for (size_t k = 0; k < ids.size(); ++k)
+    {
+      vector<double> freqs = DRTreeLikelihoodTools::getPosteriorStateFrequencies(drtl, ids[k]);
+      // Compute frequencies for types:
+      vector<double> freqsTypes(creg->getNumberOfCategories());
+      for (size_t i = 0; i < freqs.size(); ++i)
+      {
+        size_t c = creg->getCategory(i);
+        freqsTypes[c - 1] += freqs[i];
+      }
+
+      // We devide the counts by the frequencies and rescale:
+      double s = VectorTools::sum(counts[k]);
+      for (size_t t = 0; t < nbTypes; ++t)
+      {
+        counts[k][t] /= freqsTypes[creg->getCategoryFrom(t + 1) - 1];
+      }
+
+      double s2 = VectorTools::sum(counts[k]);
+      // Scale:
+      counts[k] = (counts[k] / s2) * s;
+    }
+  }
+
+  return counts;
+}
+
+/**************************************************************************************************/
+
+void SubstitutionMappingTools::outputTotalCountsPerBranchPerSite(
+  string& filename,
+  DRTreeLikelihood& drtl,
+  const vector<int>& ids,
+  SubstitutionModel* model,
+  const SubstitutionRegister& reg)
+{
+  auto_ptr<SubstitutionCount> count(new UniformizationSubstitutionCount(model, reg.clone()));
+  auto_ptr<ProbabilisticSubstitutionMapping> smap(SubstitutionMappingTools::computeSubstitutionVectors(drtl, ids, *count, false));
+
+  ofstream file;
+  file.open(filename.c_str());
+
+  size_t nbSites = smap->getNumberOfSites();
+  size_t nbBr = ids.size();
+
+  vector<size_t> sdi(nbBr);  // reverse of ids
+  for (size_t i = 0; i < nbBr; ++i)
+  {
+    sdi[i] = smap->getNodeIndex(ids[i]);
+  }
+
+  file << "sites";
+  for (size_t i = 0; i < nbBr; ++i)
+  {
+    file << "\t" << i;
+  }
+  file << endl;
+
+  for (size_t k = 0; k < nbSites; ++k)
+  {
+    vector<double> countsf = SubstitutionMappingTools::computeTotalSubstitutionVectorForSite(*smap, k);
+    file << k;
+    for (size_t i = 0; i < nbBr; ++i)
+    {
+      file << "\t" << countsf[sdi[i]];
+    }
+    file << endl;
+  }
+  file.close();
+}
+
+/**************************************************************************************************/
+
+void SubstitutionMappingTools::outputIndividualCountsPerBranchPerSite(
+  const string& filenamePrefix,
+  DRTreeLikelihood& drtl,
+  const vector<int>& ids,
+  SubstitutionModel* model,
+  const SubstitutionRegister& reg)
+{
+  auto_ptr<SubstitutionCount> count(new UniformizationSubstitutionCount(model, reg.clone()));
+  auto_ptr<ProbabilisticSubstitutionMapping> smap(SubstitutionMappingTools::computeSubstitutionVectors(drtl, ids, *count, false));
+
+  ofstream file;
+
+  size_t nbSites = smap->getNumberOfSites();
+  size_t nbBr = ids.size();
+
+  for (size_t i = 0; i < reg.getNumberOfSubstitutionTypes(); ++i)
+  {
+    string path = filenamePrefix + TextTools::toString(i + 1) + string(".count");
+    ApplicationTools::displayResult(string("Output counts of type ") + TextTools::toString(i + 1) + string(" to file"), path);
+    file.open(path.c_str());
+
+    file << "sites";
+    for (size_t k = 0; k < nbBr; ++k)
+    {
+      file << "\t" << k;
+    }
+    file << endl;
 
+    for (size_t j = 0; j < nbSites; ++j)
+    {
+      file << j;
+      for (size_t k = 0; k < nbBr; ++k)
+      {
+        file << "\t" << (*smap)(smap->getNodeIndex(ids[k]), j, i);
+      }
+      file << endl;
+    }
+    file.close();
+  }
+}
+
+/**************************************************************************************************/
diff --git a/src/Bpp/Phyl/Mapping/SubstitutionMappingTools.h b/src/Bpp/Phyl/Mapping/SubstitutionMappingTools.h
index 9234cf0..b246c54 100644
--- a/src/Bpp/Phyl/Mapping/SubstitutionMappingTools.h
+++ b/src/Bpp/Phyl/Mapping/SubstitutionMappingTools.h
@@ -5,37 +5,37 @@
 //
 
 /*
-Copyright or © or Copr. Bio++ Development Team, (November 16, 2004, 2005, 2006)
-
-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.
-*/
+   Copyright or © or Copr. Bio++ Development Team, (November 16, 2004, 2005, 2006)
+
+   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 _SUBSTITUTIONMAPPINGTOOLS_H_
 #define _SUBSTITUTIONMAPPINGTOOLS_H_
@@ -47,7 +47,6 @@ knowledge of the CeCILL license and that you accept its terms.
 
 namespace bpp
 {
-
 /**
  * @brief Provide methods to compute substitution mappings.
  *
@@ -62,182 +61,382 @@ namespace bpp
  */
 class SubstitutionMappingTools
 {
-  public:
-    SubstitutionMappingTools() {}
-    virtual ~SubstitutionMappingTools() {}
-    
-	public:
-		
-		/**
-		 * @brief Compute the substitutions vectors for a particular dataset using the
-		 * double-recursive likelihood computation.
-		 *
-		 * @param drtl              A DRTreeLikelihood object.
-		 * @param substitutionCount The SubstitutionCount to use.
-		 * @param verbose           Print info to screen.
-		 * @return A vector of substitutions vectors (one for each site).
-     * @throw Exception If the likelihood object is not initialized.
-		 */
-		static ProbabilisticSubstitutionMapping* computeSubstitutionVectors(
-			const DRTreeLikelihood& drtl,
-			SubstitutionCount& substitutionCount,
-			bool verbose = true) throw (Exception);
-		
-		/**
-		 * @brief Compute the substitutions vectors for a particular dataset using the
-		 * double-recursive likelihood computation.
-		 *
-		 * In this method, substitution counts are computed using the pair of ancestral
-		 * states with maximum likelihood.
-		 * This is a kind of joint-pair ancestral reconstruction, as in Galtier and Boursot (1998).
-		 * This reconstruction possibly takes into account several rate classes, and
-		 * substitution counts are averaged over all rate classes, weighted by their conditional
-		 * likelihood.
-		 *
-		 * This function is mainly for testing purpose (see Dutheil et al. 2005).
-		 * For practical use, consider using the 'getSubstitutionVectors' method instead.
-		 *
-		 * @param drtl              A DRTreeLikelihood object.
-		 * @param substitutionCount The substitutionsCount to use.
-		 * @param verbose           Print info to screen.
-		 * @return A vector of substitutions vectors (one for each site).
-     * @throw Exception If the likelihood object is not initialized.
-		 */
-		static ProbabilisticSubstitutionMapping* computeSubstitutionVectorsNoAveraging(
-			const DRTreeLikelihood& drtl,
-			SubstitutionCount& substitutionCount,
-			bool verbose = true) throw (Exception);
-		
-		/**
-		 * @brief Compute the substitutions vectors for a particular dataset using the
-		 * double-recursive likelihood computation.
-		 *
-		 * In this method, all ancestral states are estimated using marginal likelihoods,
-		 * putatively intregated over several rate classes.
-		 * For each branch, the number of substitution given marginal states is used.
-		 * This method, used with a SimpleSubstitutionCount objet is equivalent to
-		 * Tufféry and Darlu's (2000) computation of substitution vectors.
-		 *
-		 * Use with another substitution count objet is in most cases irrelevent.
-		 * 
-		 * @param drtl              A DRTreeLikelihood object.
-		 * @param substitutionCount The substitutionsCount to use.
-		 * @param verbose           Print info to screen.
-		 * @return A vector of substitutions vectors (one for each site).
-     * @throw Exception If the likelihood object is not initialized.
-		 */
-		static ProbabilisticSubstitutionMapping* computeSubstitutionVectorsNoAveragingMarginal(
-			const DRTreeLikelihood& drtl,
-			SubstitutionCount& substitutionCount,
-			bool verbose = true) throw (Exception);
-		
-		/**
-		 * @brief Compute the substitutions vectors for a particular dataset using the
-		 * double-recursive likelihood computation.
-		 *
-		 * The marginal probability is used for weighting, i.e. the product of probabilities for the pair.
-		 *
-		 * This function is mainly for testing purpose (see Dutheil et al. 2005).
-		 * For practical use, consider using the 'getSubstitutionVectors' method instead.
-		 *
-		 * @param drtl              A DRTreeLikelihood object.
-		 * @param substitutionCount The substitutionsCount to use.
-		 * @param verbose           Print info to screen.
-		 * @return A vector of substitutions vectors (one for each site).
-     * @throw Exception If the likelihood object is not initialized.
-		 */
-		static ProbabilisticSubstitutionMapping* computeSubstitutionVectorsMarginal(
-			const DRTreeLikelihood& drtl,
-			SubstitutionCount& substitutionCount,
-			bool verbose = true) throw (Exception);
-	
-
-    /**
-     * @brief This method computes for each site and for each branch the probability that
-     * at least one jump occurred.
-     *
-     * Here 'jump' refer to a change in the model state. Depending on the model, this might
-     * not be the same as a substitution (an alphabet state change).
-     */
-		static ProbabilisticSubstitutionMapping* computeOneJumpProbabilityVectors(
-			const DRTreeLikelihood& drtl,
-			bool verbose = true) throw (Exception)
-    {
-      OneJumpSubstitutionCount ojsm(0);
-      return computeSubstitutionVectors(drtl, ojsm, 0);
-    }
-
-		/**
-		 * @brief Write the substitutions vectors to a stream.
-		 *
-		 * @param substitutions The substitutions vectors to write.
-		 * @param sites         The dataset associated to the vectors
-		 * (needed to know the position of each site in the dataset).
-     * @param type          The type of substitutions to be output. See SubstitutionCount class.
-     * Only one type of substitution can be output at a time.
-		 * @param out           The output stream where to write the vectors.
-		 * @throw IOException If an output error happens.
-		 */
-		static void writeToStream(
-			const ProbabilisticSubstitutionMapping& substitutions,
-			const SiteContainer& sites,
-      size_t type,
-			std::ostream& out)
-			throw (IOException);
-	
-		/**
-		 * @brief Read the substitutions vectors from a stream.
-		 *
-		 * @param in            The input stream where to read the vectors.
-		 * @param substitutions The mapping object to fill.
-     * @param type          The type of substitutions that are read. Should be in supported by the substittuion count obect assiciated to the mapping, if any.
-		 * @throw IOException If an input error happens.
-		 */
-		static void readFromStream(std::istream& in, ProbabilisticSubstitutionMapping& substitutions, size_t type)
-			throw (IOException);
-
-    /**
-     * @brief Sum all type of substitutions for each branch of a given position (specified by its index).
-     *
-     * @param smap The substitution map to use.
-     * @param siteIndex The index of the substitution vector for which the counts should be computed.
-     * @return A vector will all counts for all types of substitutions summed. 
-     */
-    static std::vector<double> computeTotalSubstitutionVectorForSite(const SubstitutionMapping& smap, size_t siteIndex);
-
-    /**
-     * @brief Compute the norm of a substitution vector for a given position (specified by its index).
-     *
-     * The norm is computed as:
-     * @f$ N_i = \sqrt{\left(\sum_l {\left(\sum_t n_{l, i, t}\right)}^2\right)}@f$,
-     * where @f$n_{l, i, t}@f$ is the number of substitutions of type t on site i on branch l, obtained using the () operator for the SubstitutionMapping object.
-     *
-     * @param smap The substitution map to use.
-     * @param siteIndex The index of the substitution vector for which the norm should be computed.
-     * @return The norm of the substitution vector.
-     */
-    static double computeNormForSite(const SubstitutionMapping& smap, size_t siteIndex);
-    
-    /**
-     * @brief Sum all substitutions for each type of a given branch (specified by its index).
-     *
-     * @param smap The substitution map to use.
-     * @param branchIndex The index of the substitution vector for which the counts should be computed.
-     * @return A vector will all counts summed for each types of substitutions. 
-     */
-    static std::vector<double> computeSumForBranch(const SubstitutionMapping& smap, size_t branchIndex);
- 
-    /**
-     * @brief Sum all substitutions for each type of a given site (specified by its index).
-     *
-     * @param smap The substitution map to use.
-     * @param siteIndex The index of the substitution vector for which the counts should be computed.
-     * @return A vector will all counts summed for each types of substitutions. 
-     */
-    static std::vector<double> computeSumForSite(const SubstitutionMapping& smap, size_t siteIndex);
- };
-
-} //end of namespace bpp.
-
-#endif //_SUBSTITUTIONMAPPINGTOOLS_H_
+public:
+  SubstitutionMappingTools() {}
+  virtual ~SubstitutionMappingTools() {}
+
+public:
+  /**
+   * @brief Compute the substitutions vectors for a particular dataset using the
+   * double-recursive likelihood computation.
+   *
+   * @param drtl              A DRTreeLikelihood object.
+   * @param substitutionCount The SubstitutionCount to use.
+   * @param verbose           Print info to screen.
+   * @return A vector of substitutions vectors (one for each site).
+   * @throw Exception If the likelihood object is not initialized.
+   */
+  static ProbabilisticSubstitutionMapping* computeSubstitutionVectors(
+    const DRTreeLikelihood& drtl,
+    SubstitutionCount& substitutionCount,
+    bool verbose = true) throw (Exception)
+  {
+    std::vector<int> nodeIds;
+    return computeSubstitutionVectors(drtl, nodeIds, substitutionCount, verbose);
+  }
+
+  /**
+   * @brief Compute the substitutions vectors for a particular dataset using the
+   * double-recursive likelihood computation.
+   *
+   * @param drtl              A DRTreeLikelihood object.
+   * @param nodeIds           The Ids of the nodes the substitutions
+   *                          are counted on. If empty, count substitutions
+   *                          on all nodes.
+   * @param substitutionCount The SubstitutionCount to use.
+   * @param verbose           Print info to screen.
+   * @return A vector of substitutions vectors (one for each site).
+   * @throw Exception If the likelihood object is not initialized.
+   */
+  static ProbabilisticSubstitutionMapping* computeSubstitutionVectors(
+    const DRTreeLikelihood& drtl,
+    const std::vector<int>& nodeIds,
+    SubstitutionCount& substitutionCount,
+    bool verbose = true) throw (Exception);
+
+  static ProbabilisticSubstitutionMapping* computeSubstitutionVectors(
+    const DRTreeLikelihood& drtl,
+    const SubstitutionModelSet& modelSet,
+    const std::vector<int>& nodeIds,
+    SubstitutionCount& substitutionCount,
+    bool verbose = true) throw (Exception);
+
+  /**
+   * @brief Compute the substitutions vectors for a particular dataset using the
+   * double-recursive likelihood computation.
+   *
+   * In this method, substitution counts are computed using the pair of ancestral
+   * states with maximum likelihood.
+   * This is a kind of joint-pair ancestral reconstruction, as in Galtier and Boursot (1998).
+   * This reconstruction possibly takes into account several rate classes, and
+   * substitution counts are averaged over all rate classes, weighted by their conditional
+   * likelihood.
+   *
+   * This function is mainly for testing purpose (see Dutheil et al. 2005).
+   * For practical use, consider using the 'getSubstitutionVectors' method instead.
+   *
+   * @param drtl              A DRTreeLikelihood object.
+   * @param substitutionCount The substitutionsCount to use.
+   * @param verbose           Print info to screen.
+   * @return A vector of substitutions vectors (one for each site).
+   * @throw Exception If the likelihood object is not initialized.
+   */
+  static ProbabilisticSubstitutionMapping* computeSubstitutionVectorsNoAveraging(
+    const DRTreeLikelihood& drtl,
+    SubstitutionCount& substitutionCount,
+    bool verbose = true) throw (Exception);
+
+
+  /**
+   * @brief Compute the substitutions vectors for a particular dataset using the
+   * double-recursive likelihood computation.
+   *
+   * In this method, all ancestral states are estimated using marginal likelihoods,
+   * putatively intregated over several rate classes.
+   * For each branch, the number of substitution given marginal states is used.
+   * This method, used with a SimpleSubstitutionCount objet is equivalent to
+   * Tufféry and Darlu's (2000) computation of substitution vectors.
+   *
+   * Use with another substitution count objet is in most cases irrelevent.
+   *
+   * @param drtl              A DRTreeLikelihood object.
+   * @param substitutionCount The substitutionsCount to use.
+   * @param verbose           Print info to screen.
+   * @return A vector of substitutions vectors (one for each site).
+   * @throw Exception If the likelihood object is not initialized.
+   */
+  static ProbabilisticSubstitutionMapping* computeSubstitutionVectorsNoAveragingMarginal(
+    const DRTreeLikelihood& drtl,
+    SubstitutionCount& substitutionCount,
+    bool verbose = true) throw (Exception);
+
+
+  /**
+   * @brief Compute the substitutions vectors for a particular dataset using the
+   * double-recursive likelihood computation.
+   *
+   * The marginal probability is used for weighting, i.e. the product of probabilities for the pair.
+   *
+   * This function is mainly for testing purpose (see Dutheil et al. 2005).
+   * For practical use, consider using the 'getSubstitutionVectors' method instead.
+   *
+   * @param drtl              A DRTreeLikelihood object.
+   * @param substitutionCount The substitutionsCount to use.
+   * @param verbose           Print info to screen.
+   * @return A vector of substitutions vectors (one for each site).
+   * @throw Exception If the likelihood object is not initialized.
+   */
+  static ProbabilisticSubstitutionMapping* computeSubstitutionVectorsMarginal(
+    const DRTreeLikelihood& drtl,
+    SubstitutionCount& substitutionCount,
+    bool verbose = true) throw (Exception);
+
+
+  /**
+   * @brief This method computes for each site and for each branch the probability that
+   * at least one jump occurred.
+   *
+   * Here 'jump' refer to a change in the model state. Depending on the model, this might
+   * not be the same as a substitution (an alphabet state change).
+   */
+  static ProbabilisticSubstitutionMapping* computeOneJumpProbabilityVectors(
+    const DRTreeLikelihood& drtl,
+    bool verbose = true) throw (Exception)
+  {
+    OneJumpSubstitutionCount ojsm(0);
+    return computeSubstitutionVectors(drtl, drtl.getTree().getNodesId(), ojsm, 0);
+  }
+
+
+  /**
+   * @brief Write the substitutions vectors to a stream.
+   *
+   * @param substitutions The substitutions vectors to write.
+   * @param sites         The dataset associated to the vectors
+   * (needed to know the position of each site in the dataset).
+   * @param type          The type of substitutions to be output. See SubstitutionCount class.
+   * Only one type of substitution can be output at a time.
+   * @param out           The output stream where to write the vectors.
+   * @throw IOException If an output error happens.
+   */
+  static void writeToStream(
+    const ProbabilisticSubstitutionMapping& substitutions,
+    const SiteContainer& sites,
+    size_t type,
+    std::ostream& out)
+  throw (IOException);
+
+
+  /**
+   * @brief Read the substitutions vectors from a stream.
+   *
+   * @param in            The input stream where to read the vectors.
+   * @param substitutions The mapping object to fill.
+   * @param type          The type of substitutions that are read. Should be in supported by the substittuion count obect assiciated to the mapping, if any.
+   * @throw IOException If an input error happens.
+   */
+  static void readFromStream(std::istream& in, ProbabilisticSubstitutionMapping& substitutions, size_t type)
+  throw (IOException);
+
+
+  /**
+   * @brief Sum all type of substitutions for each branch of a given position (specified by its index).
+   *
+   * @param smap The substitution map to use.
+   * @param siteIndex The index of the substitution vector for which the counts should be computed.
+   * @return A vector will all counts for all types of substitutions summed.
+   */
+  static std::vector<double> computeTotalSubstitutionVectorForSite(const SubstitutionMapping& smap, size_t siteIndex);
+
+
+  /**
+   * @brief Compute the norm of a substitution vector for a given position (specified by its index).
+   *
+   * The norm is computed as:
+   * @f$ N_i = \sqrt{\left(\sum_l {\left(\sum_t n_{l, i, t}\right)}^2\right)}@f$,
+   * where @f$n_{l, i, t}@f$ is the number of substitutions of type t on site i on branch l, obtained using the () operator for the SubstitutionMapping object.
+   *
+   * @param smap The substitution map to use.
+   * @param siteIndex The index of the substitution vector for which the norm should be computed.
+   * @return The norm of the substitution vector.
+   */
+  static double computeNormForSite(const SubstitutionMapping& smap, size_t siteIndex);
+
+
+  /**
+   * @brief Sum all substitutions for each type of a given branch (specified by its index).
+   *
+   * @param smap The substitution map to use.
+   * @param branchIndex The index of the substitution vector for which the counts should be computed.
+   * @return A vector will all counts summed for each types of substitutions.
+   */
+  static std::vector<double> computeSumForBranch(const SubstitutionMapping& smap, size_t branchIndex);
+
+
+  /**
+   * @brief Sum all substitutions for each type of a given site (specified by its index).
+   *
+   * @param smap The substitution map to use.
+   * @param siteIndex The index of the substitution vector for which the counts should be computed.
+   * @return A vector will all counts summed for each types of substitutions.
+   */
+  static std::vector<double> computeSumForSite(const SubstitutionMapping& smap, size_t siteIndex);
+
+
+  /**
+   * @brief Returns the counts on each branch.
+   *
+   * @param drtl              A DRTreeLikelihood object.
+   * @param ids               The numbers of the nodes of the tree
+   * @param model             The model on which the SubstitutionCount is built
+   * @param reg               the Substitution Register
+   * @param threshold         value above which counts are considered saturated
+   *                                        (default: -1 means no threshold).
+   * @param verbose           Display progress messages.
+   * @return A vector of substitutions vectors (one per branch per type).
+   */
+  static std::vector< std::vector<double> > getCountsPerBranch(
+    DRTreeLikelihood& drtl,
+    const std::vector<int>& ids,
+    SubstitutionModel* model,
+    const SubstitutionRegister& reg,
+    double threshold = -1,
+    bool verbose = true);
+
+  static std::vector< std::vector<double> > getCountsPerBranch(
+    DRTreeLikelihood& drtl,
+    const std::vector<int>& ids,
+    const SubstitutionModelSet& modelSet,
+    const SubstitutionRegister& reg,
+    double threshold = -1,
+    bool verbose = true);
+
+
+  /**
+   * @brief Returns the normalization factors due to the null model
+   * on each branch, for each register
+   *
+   *
+   * @param drtl              A DRTreeLikelihood object.
+   * @param ids               The numbers of the nodes of the tree
+   * @param nullModel         The model on which the SubstitutionCount is built
+   * @param reg               the Substitution Register
+   * @param verbose           Display progress messages.
+   * @return A vector of normalization vectors (one per branch per type).
+   */
+  static std::vector< std::vector<double> > getNormalizationsPerBranch(
+    DRTreeLikelihood& drtl,
+    const std::vector<int>& ids,
+    const SubstitutionModel* nullModel,
+    const SubstitutionRegister& reg,
+    bool verbose = true);
+
+
+  /**
+   * @brief Returns the normalization factors due to the set of null
+   * models on each branch, for each register.
+   *
+   *
+   * @param drtl              A DRTreeLikelihood object.
+   * @param ids               The numbers of the nodes of the tree
+   * @param nullModelSet      The model on which the SubstitutionCount is built
+   * @param reg               the Substitution Register
+   * @param verbose           Display progress messages.
+   * @return A vector of normalization vectors (one per branch per type).
+   */
+  static std::vector< std::vector<double> > getNormalizationsPerBranch(
+    DRTreeLikelihood& drtl,
+    const std::vector<int>& ids,
+    const SubstitutionModelSet* nullModelSet,
+    const SubstitutionRegister& reg,
+    bool verbose = true);
+
+
+  /**
+   * @brief Returns the counts normalized by a null model
+   *
+   * @param drtl              A DRTreeLikelihood object.
+   * @param ids               The numbers of the nodes of the tree
+   * @param model             The model on which the SubstitutionCount is built
+   * @param nullModel         The null model used for normalization.
+   * @param reg               the Substitution Register
+   * @param verbose           Display progress messages.
+   */
+  static std::vector< std::vector<double> >  getNormalizedCountsPerBranch(
+    DRTreeLikelihood& drtl,
+    const std::vector<int>& ids,
+    SubstitutionModel* model,
+    SubstitutionModel* nullModel,
+    const SubstitutionRegister& reg,
+    bool verbose = true);
+
+  /**
+   * @brief Returns the counts normalized by a null model set
+   *
+   * @param drtl              A DRTreeLikelihood object.
+   * @param ids               The numbers of the nodes of the tree
+   * @param modelSet          The model set on which the SubstitutionCount is built
+   * @param nullModelSet      The null model set used for normalization.
+   * @param reg               the Substitution Register
+   * @param verbose           Display progress messages.
+   */
+  static std::vector< std::vector<double> > getNormalizedCountsPerBranch(
+    DRTreeLikelihood& drtl,
+    const std::vector<int>& ids,
+    SubstitutionModelSet* modelSet,
+    SubstitutionModelSet* nullModelSet,
+    const SubstitutionRegister& reg,
+    bool verbose = true);
+
+  /**
+   * @brief Returns the counts relative to the frequency of the
+   * states in case of non-stationarity.
+   *
+   * @param drtl              A DRTreeLikelihood object.
+   * @param ids               The numbers of the nodes of the tree
+   * @param model             The model on which the SubstitutionCount is built
+   * @param reg               the Substitution Register
+   * @param stationarity      if false, a correction is made if the SubstitutionRegister
+   *                             is a CategorySubstitutionRegister
+   * @param threshold         value above which counts are considered saturated
+   *                                        (default: -1 means no threshold).
+   *
+   */
+
+  static std::vector< std::vector<double> >  getRelativeCountsPerBranch(
+    DRTreeLikelihood& drtl,
+    const std::vector<int>& ids,
+    SubstitutionModel* model,
+    const SubstitutionRegister& reg,
+    bool stationarity = true,
+    double threshold = -1);
+
+  /**
+   * @brief Output the sum of the counts par branch per site, in a
+   * file.
+   *
+   * @param filename          The name of the output file
+   * @param drtl              A DRTreeLikelihood object.
+   * @param ids               The numbers of the nodes of the tree
+   * @param model             The model on which the SubstitutionCount is built
+   * @param reg               the Substitution Register
+   *
+   */
+  static void outputTotalCountsPerBranchPerSite(
+    std::string& filename,
+    DRTreeLikelihood& drtl,
+    const std::vector<int>& ids,
+    SubstitutionModel* model,
+    const SubstitutionRegister& reg);
+
+
+  /**
+   * @brief Output individual counts par branch per site, in files.
+   *
+   * @param filenamePrefix    The filename prefix
+   * @param drtl              A DRTreeLikelihood object.
+   * @param ids               The numbers of the nodes of the tree
+   * @param model             The model on which the SubstitutionCount is built
+   * @param reg               the Substitution Register
+   * @author Iakov Davydov
+   */
+  static void outputIndividualCountsPerBranchPerSite(
+    const std::string& filenamePrefix,
+    DRTreeLikelihood& drtl,
+    const std::vector<int>& ids,
+    SubstitutionModel* model,
+    const SubstitutionRegister& reg);
+};
+} // end of namespace bpp.
 
+#endif // _SUBSTITUTIONMAPPINGTOOLS_H_
diff --git a/src/Bpp/Phyl/Model/StateMap.cpp b/src/Bpp/Phyl/Mapping/SubstitutionRegister.cpp
similarity index 78%
copy from src/Bpp/Phyl/Model/StateMap.cpp
copy to src/Bpp/Phyl/Mapping/SubstitutionRegister.cpp
index b2c9730..cd8264f 100644
--- a/src/Bpp/Phyl/Model/StateMap.cpp
+++ b/src/Bpp/Phyl/Mapping/SubstitutionRegister.cpp
@@ -1,11 +1,11 @@
 //
-// File: StateMap.cpp
-// Created by: Julien Dutheil
-// Created on: Wed Jun 13 15:03 2012
+// File: SubstitutionRegister.cpp
+// Created by: Laurent Guéguen
+// Created on: lundi 15 avril 2013, à 14h 05
 //
 
 /*
-   Copyright or © or Copr. Bio++ Development Team, (November 16, 2004)
+   Copyright or © or Copr. Bio++ Development Team, (November 16, 2004, 2005, 2006)
 
    This software is a computer program whose purpose is to provide classes
    for phylogenetic data analysis.
@@ -37,17 +37,21 @@
    knowledge of the CeCILL license and that you accept its terms.
  */
 
-#include "StateMap.h"
+#include "SubstitutionRegister.h"
 
 using namespace bpp;
+using namespace std;
 
-CanonicalStateMap::CanonicalStateMap(const Alphabet* alphabet, bool includeGaps):
-  AbstractStateMap(alphabet)
+void GeneralSubstitutionRegister::updateTypes_()
 {
-  for (unsigned int i = 0; i < alphabet->getSize(); ++i) {
-    states_.push_back(i);
+  types_.clear();
+  for (size_t i = 0; i < size_; i++)
+  {
+    for (size_t j = 0; j < size_; j++)
+    {
+      size_t type = matrix_(i, j);
+      map<size_t, vector<size_t> > reg = types_[type];
+      reg[i].push_back(j);
+    }
   }
-  if (includeGaps)
-    states_.push_back(alphabet->getGapCharacterCode());
 }
-
diff --git a/src/Bpp/Phyl/Mapping/SubstitutionRegister.h b/src/Bpp/Phyl/Mapping/SubstitutionRegister.h
index e1f85b0..ce02088 100644
--- a/src/Bpp/Phyl/Mapping/SubstitutionRegister.h
+++ b/src/Bpp/Phyl/Mapping/SubstitutionRegister.h
@@ -40,23 +40,32 @@
 #ifndef _SUBSTITUTIONREGISTER_H_
 #define _SUBSTITUTIONREGISTER_H_
 
+#include "../Model/SubstitutionModel.h"
+#include "../Model/Nucleotide/NucleotideSubstitutionModel.h"
+#include "../Model/Codon/CodonSubstitutionModel.h"
+
 // From bpp-core:
 #include <Bpp/Clonable.h>
+#include <Bpp/Numeric/Matrix/Matrix.h>
+#include <Bpp/Text/StringTokenizer.h>
 
 // From bpp-seq:
-#include <Bpp/Seq/Alphabet/Alphabet.h>
 #include <Bpp/Seq/Alphabet/NucleicAlphabet.h>
+#include <Bpp/Seq/Alphabet/CodonAlphabet.h>
 #include <Bpp/Seq/GeneticCode/GeneticCode.h>
 
 // From the STL:
 #include <vector>
+#include <string>
+#include <algorithm>
 
 namespace bpp
 {
 /**
  * @brief The SubstitutionRegister interface.
  *
- * Substitution registers are simple classes that define categories of substitutions, and assign them an index.
+ * Substitution registers are simple classes that define categories of substitutions, and assign an index to them.
+ * Substitution registers are defined according to a given substitution model.
  *
  * @author Julien Dutheil
  */
@@ -78,19 +87,24 @@ public:
   virtual const Alphabet* getAlphabet() const = 0;
 
   /**
+   * @return The substitution model associated to this instance.
+   */
+  virtual const SubstitutionModel* getSubstitutionModel() const = 0;
+
+  /**
    * @return The number of substitution types supported by this class.
    */
   virtual size_t getNumberOfSubstitutionTypes() const = 0;
 
   /**
-   * @brief Get the substitution type far a given pair of states.
+   * @brief Get the substitution type far a given pair of model states.
    *
    * @param fromState Initial state (should be a state supported by the specified alphabet).
    * @param toState   Final state (should be a state supported by the specified alphabet).
    * @return The index of the corresponding substitution type, ranging from 0 to 'getNumberOfSubstitutionTypes' + 1,
    * as non-substitution (that is when fromState == toState) will always return 0.
    */
-  virtual size_t getType(int fromState, int toState) const = 0;
+  virtual size_t getType(size_t fromState, size_t toState) const = 0;
 
   /**
    * @brief Get the name of a given substitution type.
@@ -108,27 +122,29 @@ class AbstractSubstitutionRegister :
   public virtual SubstitutionRegister
 {
 protected:
-  const Alphabet* alphabet_;
+  const SubstitutionModel* model_;
 
 public:
-  AbstractSubstitutionRegister(const Alphabet* alphabet) :
-    alphabet_(alphabet)
+  AbstractSubstitutionRegister(const SubstitutionModel* model) :
+    model_(model)
   {}
 
   AbstractSubstitutionRegister(const AbstractSubstitutionRegister& asr) :
-    alphabet_(asr.alphabet_)
+    model_(asr.model_)
   {}
 
   AbstractSubstitutionRegister& operator=(const AbstractSubstitutionRegister& asr)
   {
-    alphabet_ = asr.alphabet_;
+    model_ = asr.model_;
     return *this;
   }
 
   virtual ~AbstractSubstitutionRegister() {}
 
 public:
-  const Alphabet* getAlphabet() const { return alphabet_; }
+  const SubstitutionModel* getSubstitutionModel() const { return model_; }
+
+  const Alphabet* getAlphabet() const { return model_->getAlphabet(); }
 };
 
 /**
@@ -149,13 +165,13 @@ protected:
 
 public:
   /**
-   * @brief Build a new substitution register with categories. This class is mean to be inherited.
+   * @brief Build a new substitution register with categories. This class is meant to be inherited.
    *
-   * @param alphabet The input alphabet.
+   * @param model The model defining the states.
    * @param within Specifies if within categories substitutions should be counted as well.
    */
-  CategorySubstitutionRegister(const Alphabet* alphabet, bool within = false) :
-    AbstractSubstitutionRegister(alphabet),
+  CategorySubstitutionRegister(const SubstitutionModel* model, bool within = false) :
+    AbstractSubstitutionRegister(model),
     within_(within),
     nbCategories_(0),
     categories_(),
@@ -183,14 +199,14 @@ protected:
     // Now creates categories:
     categories_.clear();
     categoryNames_.resize(nbCategories_);
-    std::vector<int> types = alphabet_->getSupportedInts();
+    std::vector<int> types = model_->getAlphabetStates();
     for (size_t i = 0; i < types.size(); ++i)
     {
       typename std::map<int, T>::const_iterator it = categories.find(types[i]);
       if (it != categories.end())
       {
         categories_[types[i]] = cats[it->second];
-        categoryNames_[cats[it->second] - 1] += alphabet_->intToChar(types[i]);
+        categoryNames_[cats[it->second] - 1] += model_->getAlphabet()->intToChar(types[i]);
       }
       else
       {
@@ -229,11 +245,10 @@ protected:
   }
 
 public:
-  virtual size_t getCategory(int state) const
+  virtual size_t getCategory(size_t state) const
   {
-    if (!alphabet_->isIntInAlphabet(state))
-      throw Exception("CategorySubstitutionRegister::getCategory(). State is not supported by alphabet.");
-    return categories_[state];
+    int alphabetState = model_->getAlphabetStateAsInt(state);
+    return categories_[alphabetState];
   }
 
   virtual size_t getCategoryFrom(size_t type) const
@@ -277,10 +292,10 @@ public:
 
   size_t getNumberOfSubstitutionTypes() const { return nbCategories_ * (nbCategories_ - 1) + (within_ ? nbCategories_ : 0); }
 
-  virtual size_t getType(int fromState, int toState) const
+  virtual size_t getType(size_t fromState, size_t toState) const
   {
-    size_t fromCat = categories_[fromState];
-    size_t toCat   = categories_[toState];
+    size_t fromCat = categories_[model_->getAlphabetStateAsInt(fromState)];
+    size_t toCat   = categories_[model_->getAlphabetStateAsInt(toState)];
     if (fromCat > 0 && toCat > 0)
       return index_[fromCat - 1][toCat - 1];
     else
@@ -305,8 +320,8 @@ class TotalSubstitutionRegister :
   public AbstractSubstitutionRegister
 {
 public:
-  TotalSubstitutionRegister(const Alphabet* alphabet) :
-    AbstractSubstitutionRegister(alphabet)
+  TotalSubstitutionRegister(const SubstitutionModel* model) :
+    AbstractSubstitutionRegister(model)
   {}
 
   TotalSubstitutionRegister* clone() const { return new TotalSubstitutionRegister(*this); }
@@ -314,7 +329,7 @@ public:
 public:
   size_t getNumberOfSubstitutionTypes() const { return 1; }
 
-  size_t getType(int fromState, int toState) const
+  size_t getType(size_t fromState, size_t toState) const
   {
     return fromState == toState ? 0 : 1;
   }
@@ -337,9 +352,96 @@ public:
 };
 
 /**
+ * @brief Completion of a given substitution register to consider
+ * all substitutions. The new substitutions are considered in an
+ * additional type.
+ */
+class CompleteSubstitutionRegister :
+  public AbstractSubstitutionRegister
+{
+private:
+  const SubstitutionRegister* preg_;
+
+  bool isRegComplete_;
+
+public:
+  CompleteSubstitutionRegister(const SubstitutionRegister& reg) :
+    AbstractSubstitutionRegister(reg.getSubstitutionModel()),
+    preg_(reg.clone()),
+    isRegComplete_(true)
+  {
+    size_t size = reg.getAlphabet()->getSize();
+    for (size_t i = 0; i < size; i++)
+    {
+      for (size_t j = 0; j < size; j++)
+      {
+        if ((i != j) && reg.getType(i, j) == 0)
+        {
+          isRegComplete_ = false;
+          return;
+        }
+      }
+    }
+  }
+
+  CompleteSubstitutionRegister* clone() const { return new CompleteSubstitutionRegister(*this); }
+
+  CompleteSubstitutionRegister(const CompleteSubstitutionRegister& csr) :
+    AbstractSubstitutionRegister(csr),
+    preg_(csr.preg_->clone()),
+    isRegComplete_(csr.isRegComplete_)
+  {}
+
+  CompleteSubstitutionRegister& operator=(const CompleteSubstitutionRegister& csr)
+  {
+    AbstractSubstitutionRegister::operator=(csr);
+    preg_ = csr.preg_->clone();
+    isRegComplete_ = csr.isRegComplete_;
+    return *this;
+  }
+
+  ~CompleteSubstitutionRegister()
+  {
+    if (preg_)
+      delete preg_;
+    preg_ = 0;
+  }
+
+public:
+  size_t getNumberOfSubstitutionTypes() const
+  {
+    return preg_->getNumberOfSubstitutionTypes() + (isRegComplete_ ? 0 : 1);
+  }
+
+  size_t getType(size_t fromState, size_t toState) const
+  {
+    size_t t = preg_->getType(fromState, toState);
+    if (t == 0)
+      return getNumberOfSubstitutionTypes();
+    else
+      return t;
+  }
+
+  std::string getTypeName(size_t type) const
+  {
+    try
+    {
+      return preg_->getTypeName(type);
+    }
+    catch (Exception& e)
+    {
+      if (type == getNumberOfSubstitutionTypes())
+        return "Completion substitution";
+      else
+        throw Exception("CompleteSubstitutionRegister::getTypeName. Bad substitution type.");
+    }
+  }
+};
+
+/**
  * @brief Distinguishes all types of substitutions.
  *
- * This register has only n * (n-1) substitution type, where n is the size of the alphabet, mapped as:
+ * This register has all n * (n-1) substitution type, where n is the size of the alphabet, mapped as:
  * - 0 not a substitution
  * - x in [1, n(n-1)] a substitution
  */
@@ -347,11 +449,11 @@ class ComprehensiveSubstitutionRegister :
   public CategorySubstitutionRegister
 {
 public:
-  ComprehensiveSubstitutionRegister(const Alphabet* alphabet, bool within = false) :
-    CategorySubstitutionRegister(alphabet, within)
+  ComprehensiveSubstitutionRegister(const SubstitutionModel* model, bool within = false) :
+    CategorySubstitutionRegister(model, within)
   {
     std::map<int, int> categories;
-    for (int i = 0; i < static_cast<int>(alphabet->getSize()); ++i)
+    for (int i = 0; i < static_cast<int>(model->getAlphabet()->getSize()); ++i)
     {
       categories[i] = i;
     }
@@ -362,6 +464,312 @@ public:
 };
 
 /**
+ * @brief Sets a Register based on a matrix of integers. If M is the
+ *  matrix, M[i,j] is the number of the substitution type from i to j,
+ *  or 0 if there is no substitution type from i to j.
+ *
+ * @author Laurent Guéguen
+ */
+class GeneralSubstitutionRegister :
+  public AbstractSubstitutionRegister
+{
+protected:
+  /**
+   * @brief The size of the matrix, i.e. the number of states.
+   */
+  size_t size_;
+
+  /**
+   * @brief The matrix of the substitution register.
+   */
+
+  RowMatrix<size_t> matrix_;
+
+  /**
+   * @brief The map from substitution types to the map of from states
+   * to the vector of target states.
+   *
+   * This is the reverse information of matrix_
+   *
+   */
+
+  std::map<size_t, std::map<size_t, std::vector<size_t> > > types_;
+
+public:
+  GeneralSubstitutionRegister(const SubstitutionModel* model) :
+    AbstractSubstitutionRegister(model),
+    size_(model->getNumberOfStates()),
+    matrix_(size_, size_),
+    types_()
+  {}
+
+  GeneralSubstitutionRegister(const SubstitutionModel* model, const RowMatrix<size_t>& matrix) :
+    AbstractSubstitutionRegister(model),
+    size_(model->getNumberOfStates()),
+    matrix_(matrix),
+    types_()
+  {
+    if (matrix_.getNumberOfRows() != size_)
+      throw DimensionException("GeneralSubstitutionRegister", size_, matrix_.getNumberOfRows());
+    if (matrix_.getNumberOfColumns() != size_)
+      throw DimensionException("GeneralSubstitutionRegister", size_, matrix_.getNumberOfColumns());
+    updateTypes_();
+  }
+
+  GeneralSubstitutionRegister(const GeneralSubstitutionRegister& gsr) :
+    AbstractSubstitutionRegister(gsr),
+    size_(gsr.size_),
+    matrix_(gsr.matrix_),
+    types_(gsr.types_)
+  {}
+
+  GeneralSubstitutionRegister& operator=(const GeneralSubstitutionRegister& gsr)
+  {
+    AbstractSubstitutionRegister::operator=(gsr);
+    size_   = gsr.size_;
+    matrix_ = gsr.matrix_;
+    types_  = gsr.types_;
+    return *this;
+  }
+
+  GeneralSubstitutionRegister* clone() const { return new GeneralSubstitutionRegister(*this); }
+
+  virtual ~GeneralSubstitutionRegister() {}
+
+  size_t getType(size_t i, size_t j) const
+  {
+    return matrix_(i, j);
+  }
+
+  size_t getNumberOfSubstitutionTypes() const
+  {
+    return types_.find(0) == types_.end() ? types_.size() : types_.size() - 1;
+  }
+
+  /**
+   * @brief names of the types are their number.
+   */
+  std::string getTypeName(size_t type) const
+  {
+    if (types_.find(type) != types_.end())
+      return TextTools::toString(type);
+
+    throw Exception("Bad type number " + TextTools::toString(type) + " in GeneralSubstitutionRegister::getTypeName.");
+  }
+
+protected:
+  void updateTypes_();
+};
+
+
+/**
+ *  @brief Class inheriting from GeneralSubstitutionRegister, this one
+ *  uses a special constructor which allows it to build a substitution
+ *  matrix from string input specifying a desired substitutions.
+ *
+ *  @author Juraj Michalik
+ */
+
+class SelectedSubstitutionRegister :
+  public GeneralSubstitutionRegister
+{
+  std::map<size_t, std::string> categoryNames_;
+
+public:
+  SelectedSubstitutionRegister (const SubstitutionModel* model, std::string selectedSubstitutions) :
+    GeneralSubstitutionRegister(model),
+    categoryNames_()
+  {
+    selectedSubstitutions.erase(std::remove(selectedSubstitutions.begin(), selectedSubstitutions.end(), ' '), selectedSubstitutions.end());
+    /**
+     *  @brief This constructor creates an empty square matrix (nrow = ncol
+     *  = length of alphabet) and takes a string with specific
+     *  syntax to mark a substitutions with a certain index
+     *  depending on the string entered.
+     *
+     *  The same group of substitution is delimited by parentheses.
+     *  The name, if entered, is entered at the start of a string
+     *  and followed by ";". Substitutions are delimited by ",", and
+     *  each substitution is defined with a "->" symbol.
+     */
+    size_t typeSubs = 0;
+    size_t coord1 = 0;
+    size_t coord2 = 0;
+    std::string codon1 = "";
+    std::string codon2 = "";
+    StringTokenizer subsGroup(selectedSubstitutions, "()");
+    while (subsGroup.hasMoreToken())
+    {
+      typeSubs++;
+      StringTokenizer namesSubs(subsGroup.nextToken(), ":");
+      if (namesSubs.numberOfRemainingTokens() == 2)
+      {
+        categoryNames_[typeSubs] = namesSubs.nextToken();
+      }
+      else if (namesSubs.numberOfRemainingTokens() == 1)
+      {
+        categoryNames_[typeSubs] = TextTools::toString(typeSubs);
+      }
+      StringTokenizer substitutions(namesSubs.nextToken(), ",");
+      while (substitutions.hasMoreToken())
+      {
+        StringTokenizer coordinates(substitutions.nextToken(), "->");
+        codon1 = coordinates.nextToken();
+        codon2 = coordinates.nextToken();
+        coord1 = model_->getAlphabet()->getStateIndex(codon1);
+        coord2 = model_->getAlphabet()->getStateIndex(codon2);
+        this->matrix_(coord1, coord2) = typeSubs;
+      }
+    }
+    updateTypes_();
+  }
+
+  SelectedSubstitutionRegister* clone() const { return new SelectedSubstitutionRegister(*this); }
+
+  ~SelectedSubstitutionRegister() {}
+
+  std::string getTypeName(size_t type) const
+  {
+    if (types_.find(type) != types_.end())
+      return TextTools::toString(categoryNames_.find(type)->second);
+
+    throw Exception("Bad type number " + TextTools::toString(type) + " in GeneralSubstitutionRegister::getTypeName.");
+  }
+};
+
+/**
+ * @brief Indexes only intra amino-acid substitutions. Every group
+ * represents a substitutions for the same amino acid. Met and Trp are
+ * not taken into account due their non-degenerescence.
+ *
+ * @author Juraj Michalik
+ */
+
+class AAInteriorSubstitutionRegister :
+  public GeneralSubstitutionRegister
+{
+  std::map<std::string, size_t> categoryCorrespondance_;
+
+public:
+  AAInteriorSubstitutionRegister(const CodonSubstitutionModel* model) :
+    GeneralSubstitutionRegister(model),
+    categoryCorrespondance_()
+  {
+    size_t categoryIndex = 1;
+    for (size_t i = 0; i < model->getAlphabet()->getSize(); ++i)
+    {
+      int state1 = model->getAlphabet()->getStateAt(i).getNum();
+      for (size_t j = i + 1; j < model->getAlphabet()->getSize(); ++j)
+      {
+        int state2 = model->getAlphabet()->getStateAt(j).getNum();
+        if (!(model->getGeneticCode()->isStop(state1)) && !(model->getGeneticCode()->isStop(state2)))
+        {
+          if (model->getGeneticCode()->translate(state1) == model->getGeneticCode()->translate(state2))
+          {
+            std::string aminoAcid = model->getGeneticCode()->getTargetAlphabet()->intToChar(model->getGeneticCode()->translate(state1));
+            if (categoryCorrespondance_.find(aminoAcid) == categoryCorrespondance_.end())
+            {
+              categoryCorrespondance_[aminoAcid] = categoryIndex;
+              categoryIndex++;
+            }
+            matrix_(i, j) = categoryCorrespondance_[aminoAcid];
+            matrix_(j, i) = categoryCorrespondance_[aminoAcid];
+          }
+        }
+      }
+    }
+    updateTypes_();
+  }
+
+  AAInteriorSubstitutionRegister* clone() const { return new AAInteriorSubstitutionRegister(*this); }
+
+  ~AAInteriorSubstitutionRegister() {}
+
+
+  std::string getTypeName(size_t type) const
+  {
+    if (types_.find(type) != types_.end())
+    {
+      for (std::map<std::string, size_t>::const_iterator it = categoryCorrespondance_.begin(); it != categoryCorrespondance_.end(); it++)
+      {
+        if (it->second == type)
+          return TextTools::toString(it->first);
+      }
+    }
+    throw Exception("Bad type number " + TextTools::toString(type) + " in GeneralSubstitutionRegister::getTypeName.");
+  }
+};
+
+/**
+ * @brief Indexes only substitutions between amino-acids. Groups are
+ * distinguished by their direction.
+ *
+ * @author Juraj Michalik
+ */
+
+class AAExteriorSubstitutionRegister :
+  public GeneralSubstitutionRegister
+{
+  std::map<std::string, size_t> categoryCorrespondance_;
+
+public:
+  AAExteriorSubstitutionRegister (const CodonSubstitutionModel* model) :
+    GeneralSubstitutionRegister(model),
+    categoryCorrespondance_()
+  {
+    size_t categoryIndex = 1;
+    for (size_t i = 0; i < model->getAlphabet()->getSize(); ++i)
+    {
+      int state1 = model->getAlphabet()->getStateAt(i).getNum();
+      for (size_t j = i + 1; j < model->getAlphabet()->getSize(); ++j)
+      {
+        int state2 = model->getAlphabet()->getStateAt(j).getNum();
+        if (!(model->getGeneticCode()->isStop(state1)) && !(model->getGeneticCode()->isStop(state2)))
+        {
+          if (model->getGeneticCode()->translate(state1) != model->getGeneticCode()->translate(state2))
+          {
+            std::string aminoAcid1 = model->getGeneticCode()->getTargetAlphabet()->intToChar(model->getGeneticCode()->translate(state1));
+            std::string aminoAcid2 = model->getGeneticCode()->getTargetAlphabet()->intToChar(model->getGeneticCode()->translate(state2));
+            bool AA1IsNotInGroup = ((categoryCorrespondance_.find(aminoAcid1 + "->" + aminoAcid2) == categoryCorrespondance_.end()));
+            bool AA2IsNotInGroup = ((categoryCorrespondance_.find(aminoAcid2 + "->" + aminoAcid1) == categoryCorrespondance_.end()));
+            if (AA1IsNotInGroup)
+            {
+              categoryCorrespondance_[aminoAcid1 + "->" + aminoAcid2] = categoryIndex;
+              categoryIndex++;
+            }
+            this->matrix_(i, j) = categoryCorrespondance_[aminoAcid1 + "->" + aminoAcid2];
+            if (AA2IsNotInGroup)
+            {
+              categoryCorrespondance_[aminoAcid2 + "->" + aminoAcid1] = categoryIndex;
+              categoryIndex++;
+            }
+            this->matrix_(j, i) = categoryCorrespondance_[aminoAcid2 + "->" + aminoAcid1];
+          }
+        }
+      }
+    }
+    updateTypes_();
+  }
+
+  AAExteriorSubstitutionRegister* clone() const { return new AAExteriorSubstitutionRegister(*this); }
+
+  ~AAExteriorSubstitutionRegister() {}
+
+  std::string getTypeName(size_t type) const
+  {
+    if (types_.find(type) != types_.end())
+    {
+      for (std::map<std::string, size_t>::const_iterator it = categoryCorrespondance_.begin(); it != categoryCorrespondance_.end(); it++)
+      {
+        if (it->second == type)
+          return TextTools::toString(it->first);
+      }
+    }
+    throw Exception("Bad type number " + TextTools::toString(type) + " in GeneralSubstitutionRegister::getTypeName.");
+  }
+};
+
+/**
  * @brief Distinguishes AT<->GC from GC<->AT.
  *
  * This register has two substitution types, mapped as:
@@ -373,8 +781,8 @@ class GCSubstitutionRegister :
   public CategorySubstitutionRegister
 {
 public:
-  GCSubstitutionRegister(const NucleicAlphabet* alphabet, bool within = false) :
-    CategorySubstitutionRegister(alphabet, within)
+  GCSubstitutionRegister(const NucleotideSubstitutionModel* model, bool within = false) :
+    CategorySubstitutionRegister(model, within)
   {
     std::map<int, int> categories;
     categories[0] = 1;
@@ -399,8 +807,8 @@ class TsTvSubstitutionRegister :
   public AbstractSubstitutionRegister
 {
 public:
-  TsTvSubstitutionRegister(const NucleicAlphabet* alphabet) :
-    AbstractSubstitutionRegister(alphabet)
+  TsTvSubstitutionRegister(const NucleotideSubstitutionModel* model) :
+    AbstractSubstitutionRegister(model)
   {}
 
   TsTvSubstitutionRegister* clone() const { return new TsTvSubstitutionRegister(*this); }
@@ -408,15 +816,17 @@ public:
 public:
   size_t getNumberOfSubstitutionTypes() const { return 2; }
 
-  size_t getType(int fromState, int toState) const
+  size_t getType(size_t fromState, size_t toState) const
   {
-    if (fromState == toState)
-      return 0;  // nothing happens
-    if ((fromState == 0 && toState == 2)
-        || (fromState == 2 && toState == 0)
-        || (fromState == 1 && toState == 3)
-        || (fromState == 3 && toState == 1))
-      return 1;  // This is a transition
+    int x = model_->getAlphabetStateAsInt(fromState);
+    int y = model_->getAlphabetStateAsInt(toState);
+    if (x == y)
+      return 0;                     // nothing happens
+    if ((x == 0 && y == 2)
+        || (x == 2 && y == 0)
+        || (x == 1 && y == 3)
+        || (x == 3 && y == 1))
+      return 1;                     // This is a transition
     return 2; // This is a transversion
   }
 
@@ -457,9 +867,9 @@ private:
   bool countMultiple_;
 
 public:
-  DnDsSubstitutionRegister(const GeneticCode* gc, bool countMultiple = false) :
-    AbstractSubstitutionRegister(gc->getSourceAlphabet()),
-    code_(gc),
+  DnDsSubstitutionRegister(const CodonSubstitutionModel* model, bool countMultiple = false) :
+    AbstractSubstitutionRegister(model),
+    code_(model->getGeneticCode()),
     countMultiple_(countMultiple)
   {}
 
@@ -482,26 +892,28 @@ public:
 public:
   size_t getNumberOfSubstitutionTypes() const { return 2; }
 
-  size_t getType(int fromState, int toState) const
+  size_t getType(size_t fromState, size_t toState) const
   {
-    const CodonAlphabet* cAlpha = dynamic_cast<const CodonAlphabet*>(alphabet_);
-    if (cAlpha->isStop(fromState) || cAlpha->isStop(toState))
+    int x = model_->getAlphabetStateAsInt(fromState);
+    int y = model_->getAlphabetStateAsInt(toState);
+    const CodonAlphabet* cAlpha = dynamic_cast<const CodonAlphabet*>(model_->getAlphabet());
+    if (code_->isStop(x) || code_->isStop(y))
       return 0;
-    if (fromState == toState)
-      return 0;  // nothing happens
+    if (x == y)
+      return 0;                     // nothing happens
     if (!countMultiple_)
     {
       size_t countPos = 0;
-      if (cAlpha->getFirstPosition(fromState) != cAlpha->getFirstPosition(toState))
+      if (cAlpha->getFirstPosition(x) != cAlpha->getFirstPosition(y))
         countPos++;
-      if (cAlpha->getSecondPosition(fromState) != cAlpha->getSecondPosition(toState))
+      if (cAlpha->getSecondPosition(x) != cAlpha->getSecondPosition(y))
         countPos++;
-      if (cAlpha->getThirdPosition(fromState) != cAlpha->getThirdPosition(toState))
+      if (cAlpha->getThirdPosition(x) != cAlpha->getThirdPosition(y))
         countPos++;
       if (countPos > 1)
         return 0;
     }
-    return code_->areSynonymous(fromState, toState) ? 1 : 2;
+    return code_->areSynonymous(x, y) ? 1 : 2;
   }
 
   std::string getTypeName (size_t type) const
@@ -545,11 +957,11 @@ private:
   const GeneticCode* code_;
 
 public:
-  GCSynonymousSubstitutionRegister(const GeneticCode* gc, bool within = false) :
-    CategorySubstitutionRegister(gc->getSourceAlphabet(), within),
-    code_(gc)
+  GCSynonymousSubstitutionRegister(const CodonSubstitutionModel* model, bool within = false) :
+    CategorySubstitutionRegister(model, within),
+    code_(model->getGeneticCode())
   {
-    const CodonAlphabet* pCA = dynamic_cast<const CodonAlphabet*>(gc->getSourceAlphabet());
+    const CodonAlphabet* pCA = dynamic_cast<const CodonAlphabet*>(code_->getSourceAlphabet());
 
     std::map<int, int> categories;
     for (int i = 0; i < static_cast<int>(pCA->getSize()); i++)
@@ -587,20 +999,22 @@ public:
 public:
   size_t getNumberOfSubstitutionTypes() const { return 2; }
 
-  size_t getType(int fromState, int toState) const
+  size_t getType(size_t fromState, size_t toState) const
   {
+    int x = model_->getAlphabetStateAsInt(fromState);
+    int y = model_->getAlphabetStateAsInt(toState);
     const CodonAlphabet* pCA = dynamic_cast<const CodonAlphabet*>(code_->getSourceAlphabet());
-    if (pCA->isStop(fromState) || pCA->isStop(toState) || !code_->areSynonymous(fromState, toState))
+    if (code_->isStop(x) || code_->isStop( y) || !code_->areSynonymous(x, y))
       return 0;
 
     // only substitutions between 3rd positions
 
-    if ((pCA->getFirstPosition(fromState) != pCA->getFirstPosition(toState)) ||
-        (pCA->getSecondPosition(fromState) != pCA->getSecondPosition(toState)))
+    if ((pCA->getFirstPosition(x) != pCA->getFirstPosition(y)) ||
+        (pCA->getSecondPosition(x) != pCA->getSecondPosition(y)))
       return 0;
 
-    size_t fromCat = categories_[fromState];
-    size_t toCat   = categories_[toState];
+    size_t fromCat = categories_[x];
+    size_t toCat   = categories_[y];
 
     if (fromCat > 0 && toCat > 0)
       return index_[fromCat - 1][toCat - 1];
@@ -631,4 +1045,3 @@ public:
 } // end of namespace bpp.
 
 #endif // _SUBSTITUTIONREGISTER_H_
-
diff --git a/src/Bpp/Phyl/Mapping/UniformizationSubstitutionCount.cpp b/src/Bpp/Phyl/Mapping/UniformizationSubstitutionCount.cpp
index 95fec35..bf31932 100644
--- a/src/Bpp/Phyl/Mapping/UniformizationSubstitutionCount.cpp
+++ b/src/Bpp/Phyl/Mapping/UniformizationSubstitutionCount.cpp
@@ -74,7 +74,11 @@ UniformizationSubstitutionCount::UniformizationSubstitutionCount(const Substitut
     if (diagQ > miu_)
       miu_ = diagQ;
   }
-}				
+  
+  if (miu_>10000)
+    throw Exception("UniformizationSubstitutionCount::UniformizationSubstitutionCount The maximum diagonal values of generator is above 10000. Abort, chose another mapping method");
+      
+}        
 
 /******************************************************************************/
 
@@ -90,7 +94,7 @@ void UniformizationSubstitutionCount::resetBMatrices_()
 void UniformizationSubstitutionCount::initBMatrices_()
 {
   //Re-initialize all B matrices according to substitution register.
-  for (unsigned int i = 0; i < register_->getNumberOfSubstitutionTypes(); ++i) {
+  for (size_t i = 0; i < register_->getNumberOfSubstitutionTypes(); ++i) {
     bMatrices_[i].resize(nbStates_, nbStates_);
     counts_[i].resize(nbStates_, nbStates_);
   }
@@ -98,12 +102,13 @@ void UniformizationSubstitutionCount::initBMatrices_()
 
 void UniformizationSubstitutionCount::fillBMatrices_()
 {
-  int n = static_cast<int>(nbStates_); //Note jdutheil 20/01/13: shoudl be generalized in case sattes are not 0:n !
-  for (int j = 0; j < n; ++j) {
-    for (int k = 0; k < n; ++k) {
+  for (size_t j = 0; j < nbStates_; ++j) {
+    for (size_t k = 0; k < nbStates_; ++k) {
       size_t i = register_->getType(j, k);
       if (i > 0 && k != j) {
-        bMatrices_[i - 1](j, k) = model_->Qij(j, k) * (weights_ ? weights_->getIndex(j, k) : 1);
+        //jdutheil on 25/07/14: I think this is incorrect, weights should only come at the end.
+        //bMatrices_[i - 1](j, k) = model_->Qij(j, k) * (weights_ ? weights_->getIndex(fromState, toState) : 1);
+        bMatrices_[i - 1](j, k) = model_->Qij(j, k);
       }
     }
   }
@@ -114,35 +119,35 @@ void UniformizationSubstitutionCount::fillBMatrices_()
 
 void UniformizationSubstitutionCount::computeCounts_(double length) const
 {
-	double lam = miu_ * length;
-	RowMatrix<double> I;
+  double lam = miu_ * length;
+  RowMatrix<double> I;
   MatrixTools::getId(nbStates_, I);
   RowMatrix<double> R(model_->getGenerator());
   MatrixTools::scale(R, 1. / miu_);
   MatrixTools::add(R, I);
-	
-	//compute the stopping point
-	//use the tail of Poisson distribution
-	//can be approximated by 4 + 6 * sqrt(lam) + lam
-	size_t nMax = static_cast<size_t>(ceil(4 + 6 * sqrt(lam) + lam));
-
-	//compute the powers of R
-	power_.resize(nMax + 1);
-	power_[0] = I;
-	for (unsigned int i = 1; i < nMax + 1; ++i)
-		MatrixTools::mult(power_[i - 1], R, power_[i]);
-
-  for (unsigned int i = 0; i < register_->getNumberOfSubstitutionTypes(); ++i) {
+  
+  //compute the stopping point
+  //use the tail of Poisson distribution
+  //can be approximated by 4 + 6 * sqrt(lam) + lam
+  size_t nMax = static_cast<size_t>(ceil(4 + 6 * sqrt(lam) + lam));
+
+  //compute the powers of R
+  power_.resize(nMax + 1);
+  power_[0] = I;
+  for (size_t i = 1; i < nMax + 1; ++i)
+    MatrixTools::mult(power_[i - 1], R, power_[i]);
+
+  for (size_t i = 0; i < register_->getNumberOfSubstitutionTypes(); ++i) {
     s_[i].resize(nMax + 1);
     MatrixTools::mult(bMatrices_[i], power_[0], s_[i][0]);
     RowMatrix<double> tmp(nbStates_, nbStates_);
-	  for (unsigned int l = 1; l < nMax + 1; ++l) {
+    for (size_t l = 1; l < nMax + 1; ++l) {
       MatrixTools::mult(R, s_[i][l - 1], s_[i][l]);
       MatrixTools::mult(bMatrices_[i], power_[l], tmp);
       MatrixTools::add(s_[i][l], tmp);
     }
     MatrixTools::fill(counts_[i], 0);
-	  for (unsigned int l = 0; l < nMax + 1; ++l) {
+    for (size_t l = 0; l < nMax + 1; ++l) {
       tmp = s_[i][l];
       //double f = (pow(lam, static_cast<double>(l + 1)) * exp(-lam) / static_cast<double>(NumTools::fact(l + 1))) / miu_;
       double logF = static_cast<double>(l + 1) * log(lam) - lam - log(miu_) - NumTools::logFact(static_cast<double>(l + 1));
@@ -151,14 +156,18 @@ void UniformizationSubstitutionCount::computeCounts_(double length) const
     }
   }
 
-  // Now we must divide by pijt:
+  // Now we must divide by pijt and account for putative weights:
+  vector<int> supportedStates = model_->getAlphabetStates();
   RowMatrix<double> P = model_->getPij_t(length);
-  for (unsigned int i = 0; i < register_->getNumberOfSubstitutionTypes(); i++) {
-    for (unsigned int j = 0; j < nbStates_; j++) {
-      for(unsigned int k = 0; k < nbStates_; k++) {
+  for (size_t i = 0; i < register_->getNumberOfSubstitutionTypes(); i++) {
+    for (size_t j = 0; j < nbStates_; j++) {
+      for(size_t k = 0; k < nbStates_; k++) {
         counts_[i](j, k) /= P(j, k);
         if (isnan(counts_[i](j, k)) || counts_[i](j, k) < 0.)
           counts_[i](j, k) = 0;
+        //Weights:
+        if (weights_)
+          counts_[i](j, k) *= weights_->getIndex(supportedStates[j], supportedStates[k]);
       }
     }
   }
@@ -180,7 +189,7 @@ Matrix<double>* UniformizationSubstitutionCount::getAllNumbersOfSubstitutions(do
 
 /******************************************************************************/
 
-double UniformizationSubstitutionCount::getNumberOfSubstitutions(int initialState, int finalState, double length, size_t type) const
+double UniformizationSubstitutionCount::getNumberOfSubstitutions(size_t initialState, size_t finalState, double length, size_t type) const
 {
   if (length < 0)
     throw Exception("UniformizationSubstitutionCount::getNumbersOfSubstitutions. Negative branch length: " + TextTools::toString(length) + ".");
@@ -194,7 +203,7 @@ double UniformizationSubstitutionCount::getNumberOfSubstitutions(int initialStat
 
 /******************************************************************************/
 
-std::vector<double> UniformizationSubstitutionCount::getNumberOfSubstitutionsForEachType(int initialState, int finalState, double length) const
+std::vector<double> UniformizationSubstitutionCount::getNumberOfSubstitutionsForEachType(size_t initialState, size_t finalState, double length) const
 {
   if (length < 0)
     throw Exception("UniformizationSubstitutionCount::getNumbersOfSubstitutions. Negative branch length: " + TextTools::toString(length) + ".");
@@ -226,7 +235,7 @@ void UniformizationSubstitutionCount::setSubstitutionModel(const SubstitutionMod
     initBMatrices_();
   }
   fillBMatrices_();
-	
+  
   miu_ = 0;
   for (unsigned int i = 0; i < nbStates_; ++i) {
     double diagQ = abs(model_->Qij(i, i));
@@ -234,6 +243,9 @@ void UniformizationSubstitutionCount::setSubstitutionModel(const SubstitutionMod
       miu_ = diagQ;
   }
 
+  if (miu_>10000)
+    throw Exception("UniformizationSubstitutionCount::setSubstitutionModel The maximum diagonal values of generator is above 10000. Abort, chose another mapping method.");
+
   //Recompute counts:
   computeCounts_(currentLength_);
 }
@@ -262,7 +274,8 @@ void UniformizationSubstitutionCount::weightsHaveChanged() throw (Exception)
   if (weights_->getAlphabet()->getAlphabetType() != register_->getAlphabet()->getAlphabetType())
     throw Exception("UniformizationSubstitutionCount::weightsHaveChanged. Incorrect alphabet type.");
 
-  fillBMatrices_();
+  //jdutheil on 25/07/14: not necessary if weights are only accounted for in the end.
+  //fillBMatrices_();
   
   //Recompute counts:
   if (currentLength_ > 0)
diff --git a/src/Bpp/Phyl/Mapping/UniformizationSubstitutionCount.h b/src/Bpp/Phyl/Mapping/UniformizationSubstitutionCount.h
index fb26901..0a6a50e 100644
--- a/src/Bpp/Phyl/Mapping/UniformizationSubstitutionCount.h
+++ b/src/Bpp/Phyl/Mapping/UniformizationSubstitutionCount.h
@@ -103,12 +103,12 @@ class UniformizationSubstitutionCount:
 		
     UniformizationSubstitutionCount* clone() const { return new UniformizationSubstitutionCount(*this); }
 
-	public:
-		double getNumberOfSubstitutions(int initialState, int finalState, double length, size_t type = 1) const;
+public:
+    double getNumberOfSubstitutions(size_t initialState, size_t finalState, double length, size_t type = 1) const;
 
     Matrix<double>* getAllNumbersOfSubstitutions(double length, size_t type = 1) const;
     
-    std::vector<double> getNumberOfSubstitutionsForEachType(int initialState, int finalState, double length) const;
+    std::vector<double> getNumberOfSubstitutionsForEachType(size_t initialState, size_t finalState, double length) const;
    
     void setSubstitutionModel(const SubstitutionModel* model);
 
diff --git a/src/Bpp/Phyl/Mapping/WeightedSubstitutionCount.h b/src/Bpp/Phyl/Mapping/WeightedSubstitutionCount.h
index 8297dbb..5bfb3de 100644
--- a/src/Bpp/Phyl/Mapping/WeightedSubstitutionCount.h
+++ b/src/Bpp/Phyl/Mapping/WeightedSubstitutionCount.h
@@ -42,7 +42,7 @@ knowledge of the CeCILL license and that you accept its terms.
 
 #include "SubstitutionCount.h"
 
-// From SeqLib:
+// From bpp-seq:
 #include <Bpp/Seq/Alphabet/Alphabet.h>
 #include <Bpp/Seq/AlphabetIndex/AlphabetIndex2.h>
 
@@ -67,16 +67,15 @@ class WeightedSubstitutionCount:
 class AbstractWeightedSubstitutionCount:
   public virtual WeightedSubstitutionCount
 {
-	protected:
-		const AlphabetIndex2* weights_;
-		bool ownWeights_;
+  protected:
+    const AlphabetIndex2* weights_;
+    bool ownWeights_;
 	
-	public:
-		AbstractWeightedSubstitutionCount(const AlphabetIndex2* weights, bool ownWeights) :
+  public:
+    AbstractWeightedSubstitutionCount(const AlphabetIndex2* weights, bool ownWeights) :
       weights_(weights),
       ownWeights_(ownWeights)
-    {
-    }
+    {}
 
     AbstractWeightedSubstitutionCount(const AbstractWeightedSubstitutionCount& index) :
       weights_(index.weights_),
@@ -95,11 +94,11 @@ class AbstractWeightedSubstitutionCount:
       return *this;
     }
 		
-		virtual ~AbstractWeightedSubstitutionCount()
+    virtual ~AbstractWeightedSubstitutionCount()
     {
-			if (ownWeights_)
+      if (ownWeights_)
         delete weights_;
-		}
+    }
 		
   public:
     void setWeights(const AlphabetIndex2* weights, bool ownWeights);
diff --git a/src/Bpp/Phyl/Model/AbstractBiblioMixedSubstitutionModel.h b/src/Bpp/Phyl/Model/AbstractBiblioMixedSubstitutionModel.h
index cf12ede..a118063 100644
--- a/src/Bpp/Phyl/Model/AbstractBiblioMixedSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/AbstractBiblioMixedSubstitutionModel.h
@@ -71,9 +71,10 @@ public:
   virtual const MixedSubstitutionModel& getMixedModel() const = 0;
 
   /*
-     *@brief Returns the submodel from the mixture.
+   *@brief Returns the submodel from the mixture.
    *
    */
+  
   const SubstitutionModel* getNModel(size_t i) const
   {
     return getMixedModel().getNModel(i);
diff --git a/src/Bpp/Phyl/Model/AbstractBiblioSubstitutionModel.h b/src/Bpp/Phyl/Model/AbstractBiblioSubstitutionModel.h
index e9cb428..64ca8fd 100644
--- a/src/Bpp/Phyl/Model/AbstractBiblioSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/AbstractBiblioSubstitutionModel.h
@@ -91,11 +91,17 @@ public:
    * @{
    */
 
-  const std::vector<int>& getAlphabetChars() const { return getModel().getAlphabetChars(); }
+  const std::vector<int>& getAlphabetStates() const { return getModel().getAlphabetStates(); }
 
-  int getAlphabetChar(size_t i) const { return getModel().getAlphabetChar(i); }
+  const StateMap& getStateMap() const { return getModel().getStateMap(); }
 
-  std::vector<size_t> getModelStates(int i) const { return getModel().getModelStates(i); }
+  int getAlphabetStateAsInt(size_t i) const { return getModel().getAlphabetStateAsInt(i); }
+  
+  std::string getAlphabetStateAsChar(size_t i) const { return getModel().getAlphabetStateAsChar(i); }
+
+  std::vector<size_t> getModelStates(int code) const { return getModel().getModelStates(code); }
+  
+  std::vector<size_t> getModelStates(const std::string& code) const { return getModel().getModelStates(code); }
 
   virtual double freq(size_t i) const { return getModel().freq(i); }
 
diff --git a/src/Bpp/Phyl/Model/AbstractMixedSubstitutionModel.cpp b/src/Bpp/Phyl/Model/AbstractMixedSubstitutionModel.cpp
index 2bcc2dd..b64576f 100644
--- a/src/Bpp/Phyl/Model/AbstractMixedSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/AbstractMixedSubstitutionModel.cpp
@@ -5,37 +5,37 @@
 //
 
 /*
-  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.
-*/
+   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 "AbstractMixedSubstitutionModel.h"
 
@@ -45,23 +45,26 @@ using namespace bpp;
 using namespace std;
 
 
-AbstractMixedSubstitutionModel::AbstractMixedSubstitutionModel(const Alphabet* alpha,
-                                                               const std::string& prefix): AbstractParameterAliasable(prefix),
-AbstractSubstitutionModel(alpha, prefix),
-                                                                                           modelsContainer_(),
-                                                                                           vProbas_(),
-                                                                                           vRates_()
+AbstractMixedSubstitutionModel::AbstractMixedSubstitutionModel(
+  const Alphabet* alpha, StateMap* stateMap, const std::string& prefix) :
+  AbstractParameterAliasable(prefix),
+  AbstractSubstitutionModel(alpha, stateMap, prefix),
+  modelsContainer_(),
+  vProbas_(),
+  vRates_()
 {
-  for (unsigned int i=0;i<size_;i++){
-    for (unsigned int j=0; j<size_;j++){
-      generator_(i,j)=0;
-      exchangeability_(i,j)=0;
-      leftEigenVectors_(i,j)=0;
-      rightEigenVectors_(i,j)=0;
+  for (unsigned int i = 0; i < size_; i++)
+  {
+    for (unsigned int j = 0; j < size_; j++)
+    {
+      generator_(i, j) = 0;
+      exchangeability_(i, j) = 0;
+      leftEigenVectors_(i, j) = 0;
+      rightEigenVectors_(i, j) = 0;
     }
-    eigenValues_[i]=0;
+    eigenValues_[i] = 0;
   }
-  eigenDecompose_=false;
+  eigenDecompose_ = false;
 }
 
 AbstractMixedSubstitutionModel::AbstractMixedSubstitutionModel(const AbstractMixedSubstitutionModel& msm) :
@@ -72,37 +75,39 @@ AbstractMixedSubstitutionModel::AbstractMixedSubstitutionModel(const AbstractMix
   vRates_()
 {
   for (unsigned int i = 0; i < msm.modelsContainer_.size(); i++)
-    {
-      modelsContainer_.push_back(msm.modelsContainer_[i]->clone());
-      vProbas_.push_back(msm.vProbas_[i]);
-      vRates_.push_back(msm.vRates_[i]);
-    }
+  {
+    modelsContainer_.push_back(msm.modelsContainer_[i]->clone());
+    vProbas_.push_back(msm.vProbas_[i]);
+    vRates_.push_back(msm.vRates_[i]);
+  }
 }
 
 AbstractMixedSubstitutionModel& AbstractMixedSubstitutionModel::operator=(const AbstractMixedSubstitutionModel& model)
 {
   AbstractParameterAliasable::operator=(model);
   AbstractSubstitutionModel::operator=(model);
-  
-  //Clear existing containers:
+
+  // Clear existing containers:
   modelsContainer_.clear();
   vProbas_.clear();
   vRates_.clear();
-  
+
   for (unsigned int i = 0; i < model.modelsContainer_.size(); i++)
-    {
-      modelsContainer_.push_back(model.modelsContainer_[i]->clone());
-      vProbas_.push_back(model.vProbas_[i]);
-      vRates_.push_back(model.vRates_[i]);
-    }
-  
+  {
+    modelsContainer_.push_back(model.modelsContainer_[i]->clone());
+    vProbas_.push_back(model.vProbas_[i]);
+    vRates_.push_back(model.vRates_[i]);
+  }
+
   return *this;
 }
 
 AbstractMixedSubstitutionModel::~AbstractMixedSubstitutionModel()
 {
   for (unsigned int i = 0; i < modelsContainer_.size(); i++)
-      delete modelsContainer_[i];
+  {
+    delete modelsContainer_[i];
+  }
 }
 
 size_t AbstractMixedSubstitutionModel::getNumberOfStates() const
@@ -113,19 +118,25 @@ size_t AbstractMixedSubstitutionModel::getNumberOfStates() const
 const Matrix<double>& AbstractMixedSubstitutionModel::getPij_t(double t) const
 {
   vector<const Matrix<double>* > vM;
-  double sP=0;
-  for (unsigned int n = 0; n < modelsContainer_.size(); n++){
+  double sP = 0;
+  for (unsigned int n = 0; n < modelsContainer_.size(); n++)
+  {
     vM.push_back(&modelsContainer_[n]->getPij_t(t));
-    sP+=vProbas_[n];
+    sP += vProbas_[n];
   }
-  
-  for (unsigned int i=0; i< getNumberOfStates(); i++)
-    for (unsigned int j=0; j< getNumberOfStates(); j++){
-      double x=0;
+
+  for (unsigned int i = 0; i < getNumberOfStates(); i++)
+  {
+    for (unsigned int j = 0; j < getNumberOfStates(); j++)
+    {
+      double x = 0;
       for (unsigned int n = 0; n < modelsContainer_.size(); n++)
-        x+= (*vM[n])(i,j)*vProbas_[n];
-      pijt_(i,j)=x/sP;
+      {
+        x += (*vM[n])(i, j) * vProbas_[n];
+      }
+      pijt_(i, j) = x / sP;
     }
+  }
   return pijt_;
 }
 
@@ -133,19 +144,25 @@ const Matrix<double>& AbstractMixedSubstitutionModel::getPij_t(double t) const
 const Matrix<double>& AbstractMixedSubstitutionModel::getdPij_dt(double t) const
 {
   vector<const Matrix<double>* > vM;
-  double sP=0;
-  for (unsigned int n = 0; n < modelsContainer_.size(); n++){
+  double sP = 0;
+  for (unsigned int n = 0; n < modelsContainer_.size(); n++)
+  {
     vM.push_back(&modelsContainer_[n]->getdPij_dt(t));
-    sP+=vProbas_[n];
+    sP += vProbas_[n];
   }
-  
-  for (unsigned int i=0; i< getNumberOfStates(); i++)
-    for (unsigned int j=0; j< getNumberOfStates(); j++){
-      double x=0;
+
+  for (unsigned int i = 0; i < getNumberOfStates(); i++)
+  {
+    for (unsigned int j = 0; j < getNumberOfStates(); j++)
+    {
+      double x = 0;
       for (unsigned int n = 0; n < modelsContainer_.size(); n++)
-        x+= (*vM[n])(i,j)*vProbas_[n];
-      dpijt_(i,j)=x/sP;
+      {
+        x += (*vM[n])(i, j) * vProbas_[n];
+      }
+      dpijt_(i, j) = x / sP;
     }
+  }
   return dpijt_;
 }
 
@@ -153,19 +170,25 @@ const Matrix<double>& AbstractMixedSubstitutionModel::getdPij_dt(double t) const
 const Matrix<double>& AbstractMixedSubstitutionModel::getd2Pij_dt2(double t) const
 {
   vector<const Matrix<double>* > vM;
-  double sP=0;
-  for (unsigned int n = 0; n < modelsContainer_.size(); n++){
+  double sP = 0;
+  for (unsigned int n = 0; n < modelsContainer_.size(); n++)
+  {
     vM.push_back(&modelsContainer_[n]->getd2Pij_dt2(t));
-    sP+=vProbas_[n];
+    sP += vProbas_[n];
   }
-  
-  for (unsigned int i=0; i< getNumberOfStates(); i++)
-    for (unsigned int j=0; j< getNumberOfStates(); j++){
-      double x=0;
+
+  for (unsigned int i = 0; i < getNumberOfStates(); i++)
+  {
+    for (unsigned int j = 0; j < getNumberOfStates(); j++)
+    {
+      double x = 0;
       for (unsigned int n = 0; n < modelsContainer_.size(); n++)
-        x+= (*vM[n])(i,j)*vProbas_[n];
-      d2pijt_(i,j)=x/sP;
+      {
+        x += (*vM[n])(i, j) * vProbas_[n];
+      }
+      d2pijt_(i, j) = x / sP;
     }
+  }
   return d2pijt_;
 }
 
@@ -174,43 +197,49 @@ void AbstractMixedSubstitutionModel::setRate(double rate)
 {
   AbstractSubstitutionModel::setRate(rate);
 
-  double sum=0;
-  double sP=0;
-  for (unsigned int n = 0; n < modelsContainer_.size(); n++){
-    sum+=vRates_[n]*vProbas_[n];
-    sP+=vProbas_[n];
+  double sum = 0;
+  double sP = 0;
+  for (unsigned int n = 0; n < modelsContainer_.size(); n++)
+  {
+    sum += vRates_[n] * vProbas_[n];
+    sP += vProbas_[n];
   }
-  sum/=sP;
-  
-  for (unsigned int n = 0; n < modelsContainer_.size(); n++){
-    vRates_[n]*=rate_/sum;
+  sum /= sP;
+
+  for (unsigned int n = 0; n < modelsContainer_.size(); n++)
+  {
+    vRates_[n] *= rate_ / sum;
     modelsContainer_[n]->setRate(vRates_[n]);
   }
 }
 
 void AbstractMixedSubstitutionModel::setVRates(const Vdouble& vd)
 {
-  if (vd.size()!=modelsContainer_.size())
+  if (vd.size() != modelsContainer_.size())
     throw Exception("AbstractMixedSubstitutionModel::setVRates  bad size of Vdouble argument.");
 
-  for (unsigned int i=0;i<vd.size();i++)
-    vRates_[i]=vd[i];
- 
+  for (unsigned int i = 0; i < vd.size(); i++)
+  {
+    vRates_[i] = vd[i];
+  }
+
   normalizeVRates();
 }
 
 void AbstractMixedSubstitutionModel::normalizeVRates()
 {
-  double sum=0;
-  double sP=0;
-  for (unsigned int i=0;i<vRates_.size();i++){
-    sum+=vRates_[i]*vProbas_[i];
-    sP+=vProbas_[i];
+  double sum = 0;
+  double sP = 0;
+  for (unsigned int i = 0; i < vRates_.size(); i++)
+  {
+    sum += vRates_[i] * vProbas_[i];
+    sP += vProbas_[i];
   }
-  sum/=sP;
-  
-  for (unsigned int i=0;i<vRates_.size();i++){
-    vRates_[i]*=rate_/sum;
+  sum /= sP;
+
+  for (unsigned int i = 0; i < vRates_.size(); i++)
+  {
+    vRates_[i] *= rate_ / sum;
     modelsContainer_[i]->setRate(vRates_[i]);
   }
 }
diff --git a/src/Bpp/Phyl/Model/AbstractMixedSubstitutionModel.h b/src/Bpp/Phyl/Model/AbstractMixedSubstitutionModel.h
index 0ab8867..591d273 100644
--- a/src/Bpp/Phyl/Model/AbstractMixedSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/AbstractMixedSubstitutionModel.h
@@ -5,37 +5,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.
-*/
+   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 _ABSTRACTMIXEDSUBSTITUTIONMODEL_H_
 #define _ABSTRACTMIXEDSUBSTITUTIONMODEL_H_
@@ -51,186 +51,172 @@
 
 namespace bpp
 {
+/**
+ * @brief Partial implementation for Mixed Substitution models,
+ * defined as a mixture of "simple" substitution models. Each model
+ * has a specific probability and rate, with the constraint that the
+ * expectation (on the distribution of the models) of the rate of
+ * all the models equals one.
+ *
+ * In this kind of model, there is no generator.
+ *
+ * @author Laurent Guéguen
+ *
+ */
+
+class AbstractMixedSubstitutionModel :
+  public virtual MixedSubstitutionModel,
+  public AbstractSubstitutionModel
+{
+protected:
   /**
-   * @brief Partial implementation for Mixed Substitution models,
-   * defined as a mixture of "simple" substitution models. Each model
-   * has a specific probability and rate, with the constraint that the
-   * expectation (on the distribution of the models) of the rate of
-   * all the models equals one.
+   * @brief vector of pointers to SubstitutionModels.
    *
-   * In this kind of model, there is no generator.
+   * Beware: these SubstitutionModels are owned by the object, so
+   * will be deleted at destruction
+   */
+  std::vector<SubstitutionModel*> modelsContainer_;
+
+  /**
+   * @brief vector of the probabilities of the models
+   */
+  std::vector<double> vProbas_;
+
+  /**
+   * @brief vector of the rates of the models.
    *
-   * @author Laurent Guéguen
+   * For the computation of the transition probabilities, the rates
+   * are included in the submodels while updating the mixture, so
+   * there is no need to multiply here the transition times with the
+   * rates.
    *
+   * The mean (on the distribution of the models) of the elements of
+   * this vector equals the overall rate of the mixture model, that
+   * is rate_;
    */
+  std::vector<double> vRates_;
+
+public:
+  AbstractMixedSubstitutionModel(const Alphabet*, StateMap* stateMap, const std::string& prefix);
+
+  AbstractMixedSubstitutionModel(const AbstractMixedSubstitutionModel&);
 
-  class AbstractMixedSubstitutionModel :
-    public virtual MixedSubstitutionModel,
-    public AbstractSubstitutionModel
+  AbstractMixedSubstitutionModel& operator=(const AbstractMixedSubstitutionModel&);
+
+  virtual ~AbstractMixedSubstitutionModel();
+
+  virtual AbstractMixedSubstitutionModel* clone() const = 0;
+
+public:
+  /**
+   * @brief returns the number of models in the mixture
+   */
+  virtual size_t getNumberOfModels() const
   {
-  protected:
-
-    /*
-     * @brief vector of pointers to SubstitutionModels.
-     *
-     * Beware: these SubstitutionModels are owned by the object, so
-     * will be deleted at destruction
-     *
-     */
-    
-    std::vector<SubstitutionModel*> modelsContainer_;
-
-    /*
-     *@brief vector of the probabilities of the models
-     *
-     */
-    
-    std::vector<double> vProbas_;
-
-    /*
-     *@brief vector of the rates of the models.
-     *
-     * For the computation of the transition probabilities, the rates
-     * are included in the submodels while updating the mixture, so
-     * there is no need to multiply here the transition times with the
-     * rates.
-     *
-     * The mean (on the distribution of the models) of the elements of
-     * this vector equals the overall rate of the mixture model, that
-     * is rate_;
-     */
-    
-    std::vector<double> vRates_;
-
-  public:
-
-    AbstractMixedSubstitutionModel(const Alphabet*, const std::string& prefix);
-    
-    AbstractMixedSubstitutionModel(const AbstractMixedSubstitutionModel&);
-  
-    AbstractMixedSubstitutionModel& operator=(const AbstractMixedSubstitutionModel&);
-
-    virtual ~AbstractMixedSubstitutionModel();
-
-    virtual AbstractMixedSubstitutionModel* clone() const = 0;
-
-  public:
-
-    /**
-     * @brief returns the number of models in the mixture
-     */
-    
-    virtual size_t getNumberOfModels() const
-    {
-      return modelsContainer_.size();
-    }
- 
-    /**
-     * @brief Returns a specific model from the mixture
-     */
-    virtual const SubstitutionModel* getNModel(size_t i) const
-    {
-      return modelsContainer_[i];
-    }
-    
-    virtual SubstitutionModel* getNModel(size_t i)
-    {
-      return modelsContainer_[i];
-    }
-
-    /**
-     * @brief Returns the rate of a specific model from the mixture
-     */
-  
-    double getNRate(size_t i) const
-    {
-      return vRates_[i];
-    }
-  
-    /**
-     * @brief Set the rate of the model and the submodels.
-     * @param rate must be positive.
-     */
-  
-    virtual void setRate(double rate);
-
-    /**
-     * @brief Sets the rates of the submodels to be proportional to a
-     * given vector, with the constraint that the mean rate of the
-     * mixture equals rate_.
-     
-     * @param vd a vector of positive values such that the rates of
-     * the respective submodels are in the same proportions (ie this
-     * vector does not need to be normalized).
-     */
-
-    virtual void setVRates(const Vdouble& vd);
-
-    /**
-     * @brief Normalizes the rates of the submodels so that the mean
-     * rate of the mixture equals rate_.
-     */
-
-    virtual void normalizeVRates();
-
-    /**
-     * @brief Returns the vector of all the rates of the mixture
-     */
-
-    const std::vector<double>& getVRates() const
-    {
-      return vRates_;
-    }
-  
-    /**
-     * @brief Returns the probability of a specific model from the
-     * mixture
-     */
-  
-    virtual double getNProbability(size_t i) const
-    {
-      return vProbas_[i];
-    }
-
-    /**
-     * @brief Returns the vector of probabilities
-     *
-     */
-  
-    virtual const std::vector<double>& getProbabilities() const
-    {
-      return vProbas_;
-    }
-
-    /**
-     * @brief Sets the  probability of a specific model from the mixture
-     */
-  
-    virtual void setNProbability(size_t i, double prob)
-    {
-      if ((prob>=0) && (prob<=1))
-        vProbas_[i]=prob;
-    }
-
-    /**
-     * @brief This function can not be applied here, so it is defined
-     * to prevent wrong usage.
-     */
-    
-    double Qij(size_t i, size_t j) const {return 0;}
-
-    /**
-     * @brief From SubstitutionModel interface
-     *
-     */
-
-    virtual size_t getNumberOfStates() const;
-    
-    virtual const Matrix<double>& getPij_t(double t) const;
-    virtual const Matrix<double>& getdPij_dt(double t) const;
-    virtual const Matrix<double>& getd2Pij_dt2(double t) const;
-
-  };
+    return modelsContainer_.size();
+  }
+
+  /**
+   * @brief Returns a specific model from the mixture
+   */
+  virtual const SubstitutionModel* getNModel(size_t i) const
+  {
+    return modelsContainer_[i];
+  }
+
+  virtual SubstitutionModel* getNModel(size_t i)
+  {
+    return modelsContainer_[i];
+  }
+
+  /**
+   * @brief Returns the rate of a specific model from the mixture
+   */
+  double getNRate(size_t i) const
+  {
+    return vRates_[i];
+  }
+
+  /**
+   * @brief Set the rate of the model and the submodels.
+   * @param rate must be positive.
+   */
+
+  virtual void setRate(double rate);
+
+  /**
+   * @brief Sets the rates of the submodels to be proportional to a
+   * given vector, with the constraint that the mean rate of the
+   * mixture equals rate_.
+
+   * @param vd a vector of positive values such that the rates of
+   * the respective submodels are in the same proportions (ie this
+   * vector does not need to be normalized).
+   */
+
+  virtual void setVRates(const Vdouble& vd);
+
+  /**
+   * @brief Normalizes the rates of the submodels so that the mean
+   * rate of the mixture equals rate_.
+   */
+
+  virtual void normalizeVRates();
+
+  /**
+   * @brief Returns the vector of all the rates of the mixture
+   */
+
+  const std::vector<double>& getVRates() const
+  {
+    return vRates_;
+  }
+
+  /**
+   * @brief Returns the probability of a specific model from the
+   * mixture
+   */
+  virtual double getNProbability(size_t i) const
+  {
+    return vProbas_[i];
+  }
+
+  /**
+   * @brief Returns the vector of probabilities
+   *
+   */
+
+  virtual const std::vector<double>& getProbabilities() const
+  {
+    return vProbas_;
+  }
+
+  /**
+   * @brief Sets the  probability of a specific model from the mixture
+   */
+  virtual void setNProbability(size_t i, double prob)
+  {
+    if ((prob >= 0) && (prob <= 1))
+      vProbas_[i] = prob;
+  }
+
+  /**
+   * @brief This function can not be applied here, so it is defined
+   * to prevent wrong usage.
+   */
+  double Qij(size_t i, size_t j) const {return 0; }
+
+  /**
+   * @brief From SubstitutionModel interface
+   *
+   */
+
+  virtual size_t getNumberOfStates() const;
+
+  virtual const Matrix<double>& getPij_t(double t) const;
+  virtual const Matrix<double>& getdPij_dt(double t) const;
+  virtual const Matrix<double>& getd2Pij_dt2(double t) const;
+};
 } // end of namespace bpp.
 
 #endif  // _ABSTRACTMIXEDSUBSTITUTIONMODEL_H_
diff --git a/src/Bpp/Phyl/Model/AbstractSubstitutionModel.cpp b/src/Bpp/Phyl/Model/AbstractSubstitutionModel.cpp
index d1c89bd..dcbf755 100644
--- a/src/Bpp/Phyl/Model/AbstractSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/AbstractSubstitutionModel.cpp
@@ -53,12 +53,12 @@ using namespace std;
 
 /******************************************************************************/
 
-AbstractSubstitutionModel::AbstractSubstitutionModel(const Alphabet* alpha, const std::string& prefix) :
+AbstractSubstitutionModel::AbstractSubstitutionModel(const Alphabet* alpha, StateMap* stateMap, const std::string& prefix) :
   AbstractParameterAliasable(prefix),
   alphabet_(alpha),
+  stateMap_(stateMap),
   size_(alpha->getSize()),
   rate_(1),
-  chars_(size_),
   generator_(size_, size_),
   freq_(size_),
   exchangeability_(size_, size_),
@@ -78,7 +78,6 @@ AbstractSubstitutionModel::AbstractSubstitutionModel(const Alphabet* alpha, cons
   for (size_t i = 0; i < size_; i++)
   {
     freq_[i] = 1.0 / static_cast<double>(size_);
-    chars_[i] = static_cast<int>(i);
   }
 }
 
@@ -158,9 +157,9 @@ const Matrix<double>& AbstractSubstitutionModel::getPij_t(double t) const
         {
           s = std::sin(iEigenValues_[i] * l);
           c = std::cos(iEigenValues_[i] * l);
-          vdia[i] *= c;
           vup[i] = vdia[i] * s;
           vlo[i] = -vup[i];
+          vdia[i] *= c;
           vdia[i + 1] = vdia[i]; // trick to avoid computation
           i++;
         }
@@ -199,7 +198,7 @@ const Matrix<double>& AbstractSubstitutionModel::getPij_t(double t) const
       m--;
     }
   }
-  //MatrixTools::print(pijt_);
+//  MatrixTools::print(pijt_);
   return pijt_;
 }
 
@@ -278,7 +277,7 @@ const Matrix<double>& AbstractSubstitutionModel::getd2Pij_dt2(double t) const
   {
     if (isDiagonalizable_)
     {
-      MatrixTools::mult(rightEigenVectors_, NumTools::sqr(rate_ * eigenValues_) * VectorTools::exp(eigenValues_ * (rate_ * t)), leftEigenVectors_, d2pijt_);
+      MatrixTools::mult(rightEigenVectors_, VectorTools::sqr(rate_ * eigenValues_) * VectorTools::exp(eigenValues_ * (rate_ * t)), leftEigenVectors_, d2pijt_);
     }
     else
     {
@@ -356,7 +355,7 @@ double AbstractSubstitutionModel::getInitValue(size_t i, int state) const throw
   vector<int> states = alphabet_->getAlias(state);
   for (size_t j = 0; j < states.size(); j++)
   {
-    if (getAlphabetChar(i) == states[j])
+    if (getAlphabetStateAsInt(i) == states[j])
       return 1.;
   }
   return 0.;
@@ -373,7 +372,7 @@ void AbstractSubstitutionModel::setFreqFromData(const SequenceContainer& data, d
 
   for (int i = 0; i < static_cast<int>(size_); i++)
   {
-    t += counts[i] + pseudoCount;
+    t += (counts[i] + pseudoCount);
   }
   for (int i = 0; i < static_cast<int>(size_); i++)
   {
@@ -388,9 +387,9 @@ void AbstractSubstitutionModel::setFreqFromData(const SequenceContainer& data, d
 
 void AbstractSubstitutionModel::setFreq(map<int, double>& freqs)
 {
-  for (int i = 0; i < static_cast<int>(size_); i++)
+  for (size_t i = 0; i < size_; ++i)
   {
-    freq_[i] = freqs[i];
+    freq_[i] = freqs[static_cast<int>(i)];
   }
   // Re-compute generator and eigen values:
   updateMatrices();
diff --git a/src/Bpp/Phyl/Model/AbstractSubstitutionModel.h b/src/Bpp/Phyl/Model/AbstractSubstitutionModel.h
index a684e74..40e6d5b 100755
--- a/src/Bpp/Phyl/Model/AbstractSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/AbstractSubstitutionModel.h
@@ -45,6 +45,8 @@
 #include <Bpp/Numeric/AbstractParameterAliasable.h>
 #include <Bpp/Numeric/VectorTools.h>
 
+#include <memory>
+
 namespace bpp
 {
 /**
@@ -84,6 +86,11 @@ protected:
   const Alphabet* alphabet_;
 
   /**
+   * @brief The map of model states with alphabet states.
+   */
+  std::auto_ptr<StateMap> stateMap_;
+
+  /**
    * @brief The size of the generator, i.e. the number of states.
    */
   size_t size_;
@@ -92,16 +99,10 @@ protected:
    * @brief The rate of the model (default: 1). The generator (and all
    * its vectorial components) is independent of the rate, since it
    * should be normalized.
-   */
-  
+   */ 
   double rate_;
 
   /**
-   * @brief The list of supported chars.
-   */
-  std::vector<int> chars_;
-
-  /**
    * @brief The generator matrix \f$Q\f$ of the model.
    */
   RowMatrix<double> generator_;
@@ -109,7 +110,6 @@ protected:
   /**
    * @brief The vector \f$\pi_e\f$ of equilibrium frequencies.
    */
-
   Vdouble freq_;
 
   /**
@@ -157,39 +157,34 @@ protected:
   /**
    * @brief boolean value for non-singularity of rightEigenVectors_
    */
-  
   bool isNonSingular_;
 
   /**
    * @brief The \f$U\f$ matrix made of left eigen vectors (by row) if
    * rightEigenVectors_ is non-singular.
    */
-  
   RowMatrix<double> leftEigenVectors_;
 
   /**
    * @brief vector of the powers of generator_ for Taylor development (if
    * rightEigenVectors_ is singular).
    */
-
   std::vector< RowMatrix<double> > vPowGen_;
 
   /**
    * @brief For computational issues
-   *
    */
-
   mutable RowMatrix<double> tmpMat_;
   
 public:
-  AbstractSubstitutionModel(const Alphabet* alpha, const std::string& prefix);
+  AbstractSubstitutionModel(const Alphabet* alpha, StateMap* stateMap, const std::string& prefix);
 
   AbstractSubstitutionModel(const AbstractSubstitutionModel& model) :
     AbstractParameterAliasable(model),
     alphabet_(model.alphabet_),
+    stateMap_(model.stateMap_->clone()),
     size_(model.size_),
     rate_(model.rate_),
-    chars_(model.chars_),
     generator_(model.generator_),
     freq_(model.freq_),
     exchangeability_(model.exchangeability_),
@@ -211,9 +206,9 @@ public:
   {
     AbstractParameterAliasable::operator=(model);
     alphabet_          = model.alphabet_;
+    stateMap_.reset(model.stateMap_->clone());
     size_              = model.size_;
     rate_              = model.rate_;
-    chars_             = model.chars_;
     generator_         = model.generator_;
     freq_              = model.freq_;
     exchangeability_   = model.exchangeability_;
@@ -241,11 +236,17 @@ public:
 public:
   const Alphabet* getAlphabet() const { return alphabet_; }
 
-  const std::vector<int>& getAlphabetChars() const { return chars_; }
+  const StateMap& getStateMap() const { return *stateMap_; }
+
+  const std::vector<int>& getAlphabetStates() const { return stateMap_->getAlphabetStates(); }
 
-  int getAlphabetChar(size_t i) const { return chars_[i]; }
+  std::string getAlphabetStateAsChar(size_t index) const { return stateMap_->getAlphabetStateAsChar(index); }
 
-  std::vector<size_t> getModelStates(int i) const { return VectorTools::whichAll(chars_, i); }
+  int getAlphabetStateAsInt(size_t index) const { return stateMap_->getAlphabetStateAsInt(index); }
+
+  std::vector<size_t> getModelStates(int code) const { return stateMap_->getModelStates(code); }
+  
+  std::vector<size_t> getModelStates(const std::string& code) const { return stateMap_->getModelStates(code); }
 
   virtual const Vdouble& getFrequencies() const { return freq_; }
 
@@ -325,6 +326,13 @@ protected:
 public:
   double getScale() const;
 
+  /*
+   * @brief Multiplies the current generator by the given scale.
+   *
+   * @param scale the scale by which the generator is multiplied.
+   *
+   */
+  
   void setScale(double scale);
 
   virtual double getRate() const;
@@ -362,13 +370,13 @@ public:
  */
   
 class AbstractReversibleSubstitutionModel :
-  public virtual AbstractSubstitutionModel,
+  public AbstractSubstitutionModel,
   public virtual ReversibleSubstitutionModel
 {
 public:
-  AbstractReversibleSubstitutionModel(const Alphabet* alpha, const std::string& prefix) :
+  AbstractReversibleSubstitutionModel(const Alphabet* alpha, StateMap* stateMap, const std::string& prefix) :
     AbstractParameterAliasable(prefix),
-    AbstractSubstitutionModel(alpha, prefix)
+    AbstractSubstitutionModel(alpha, stateMap, prefix)
   {
     isDiagonalizable_ = true;
     isNonSingular_    = true;
diff --git a/src/Bpp/Phyl/Model/AbstractWordSubstitutionModel.cpp b/src/Bpp/Phyl/Model/AbstractWordSubstitutionModel.cpp
index 8de2a8d..15b1dfd 100644
--- a/src/Bpp/Phyl/Model/AbstractWordSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/AbstractWordSubstitutionModel.cpp
@@ -59,15 +59,17 @@ using namespace std;
 
 /******************************************************************************/
 
+//TODO: jdutheil on 24/09/14: we should define a class "vector of models", insuring they share the same alphabet and StateMap for instance.
+//This is the only way to avoid a segfault in case the user provides a vector of models of length 0.
 AbstractWordSubstitutionModel::AbstractWordSubstitutionModel(
   const std::vector<SubstitutionModel*>& modelVector,
-  const std::string& st) :
-  AbstractParameterAliasable(st),
-  AbstractSubstitutionModel(AbstractWordSubstitutionModel::extractAlph(modelVector), st),
+  const std::string& prefix) :
+  AbstractParameterAliasable(prefix),
+  AbstractSubstitutionModel(AbstractWordSubstitutionModel::extractAlph(modelVector), modelVector[0]->getStateMap().clone(), prefix),
   new_alphabet_ (true),
   VSubMod_      (),
   VnestedPrefix_(),
-  Vrate_         (modelVector.size())
+  Vrate_        (modelVector.size())
 {
   enableEigenDecomposition(false);
   size_t i, j;
@@ -99,7 +101,7 @@ AbstractWordSubstitutionModel::AbstractWordSubstitutionModel(
     {
       VSubMod_.push_back(modelVector[i]);
       VnestedPrefix_.push_back(modelVector[i]->getNamespace());
-      VSubMod_[i]->setNamespace(st + TextTools::toString(i + 1) + "_" + VnestedPrefix_[i]);
+      VSubMod_[i]->setNamespace(prefix + TextTools::toString(i + 1) + "_" + VnestedPrefix_[i]);
       addParameters_(VSubMod_[i]->getParameters());
     }
   }
@@ -112,7 +114,7 @@ AbstractWordSubstitutionModel::AbstractWordSubstitutionModel(
       VnestedPrefix_.push_back(modelVector[0]->getNamespace());
       t += TextTools::toString(i + 1);
     }
-    VSubMod_[0]->setNamespace(st + t + "_" + VnestedPrefix_[0]);
+    VSubMod_[0]->setNamespace(prefix + t + "_" + VnestedPrefix_[0]);
     addParameters_(VSubMod_[0]->getParameters());
   }
 
@@ -124,9 +126,10 @@ AbstractWordSubstitutionModel::AbstractWordSubstitutionModel(
 
 AbstractWordSubstitutionModel::AbstractWordSubstitutionModel(
   const Alphabet* alph,
-  const std::string& st) :
-  AbstractParameterAliasable(st),
-  AbstractSubstitutionModel(alph, st),
+  StateMap* stateMap,
+  const std::string& prefix) :
+  AbstractParameterAliasable(prefix),
+  AbstractSubstitutionModel(alph, stateMap, prefix),
   new_alphabet_ (false),
   VSubMod_      (),
   VnestedPrefix_(),
@@ -138,9 +141,9 @@ AbstractWordSubstitutionModel::AbstractWordSubstitutionModel(
 AbstractWordSubstitutionModel::AbstractWordSubstitutionModel(
   SubstitutionModel* pmodel,
   unsigned int num,
-  const std::string& st) :
-  AbstractParameterAliasable(st),
-  AbstractSubstitutionModel(new WordAlphabet(pmodel->getAlphabet(), num), st),
+  const std::string& prefix) :
+  AbstractParameterAliasable(prefix),
+  AbstractSubstitutionModel(new WordAlphabet(pmodel->getAlphabet(), num), pmodel->getStateMap().clone(), prefix),
   new_alphabet_ (true),
   VSubMod_      (),
   VnestedPrefix_(),
@@ -158,7 +161,7 @@ AbstractWordSubstitutionModel::AbstractWordSubstitutionModel(
     t += TextTools::toString(i + 1);
   }
 
-  pmodel->setNamespace(st + t + "_" + VnestedPrefix_[0]);
+  pmodel->setNamespace(prefix + t + "_" + VnestedPrefix_[0]);
   addParameters_(pmodel->getParameters());
 }
 
@@ -377,7 +380,7 @@ void AbstractWordSubstitutionModel::updateMatrices()
 
     if (nbStop != 0)
     {
-      int gi = 0, gj = 0;
+      size_t gi = 0, gj = 0;
 
       RowMatrix<double> gk;
 
@@ -462,23 +465,18 @@ void AbstractWordSubstitutionModel::updateMatrices()
           isDiagonalizable_ = false;
       }
 
-
       // is it singular?
 
       // looking for the 0 eigenvector for which the non-stop right
       // eigen vector elements are equal.
       //
-      // there is a tolerance for numerical problems
-      //
-
-      size_t nulleigen = 0;
-      double val;
-      double seuil = 1;
 
-      isNonSingular_ = false;
-      while (!isNonSingular_)
+      if (isDiagonalizable_)
       {
-        nulleigen = 0;
+        size_t nulleigen = 0;
+        double val;
+
+        isNonSingular_ = false;
         while (nulleigen < salph - nbStop)
         {
           if ((abs(eigenValues_[nulleigen]) < NumConstants::SMALL()) && (abs(iEigenValues_[nulleigen]) < NumConstants::SMALL()))
@@ -486,19 +484,19 @@ void AbstractWordSubstitutionModel::updateMatrices()
             i = 0;
             while (vnull[i])
               i++;
-
+            
             val = rightEigenVectors_(i, nulleigen);
             i++;
             while (i < salph)
             {
               if (!vnull[i])
               {
-                if (abs(rightEigenVectors_(i, nulleigen) - val) > seuil * NumConstants::SMALL())
+                if (abs(rightEigenVectors_(i, nulleigen) - val) > NumConstants::SMALL())
                   break;
               }
               i++;
             }
-
+            
             if (i < salph)
               nulleigen++;
             else
@@ -510,44 +508,31 @@ void AbstractWordSubstitutionModel::updateMatrices()
           else
             nulleigen++;
         }
-        if (seuil > 100)
+        
+        if (isNonSingular_)
         {
-          ApplicationTools::displayWarning("!!! Equilibrium frequency of the model " + getName() + " has a precision less than " ""  + TextTools::toString(seuil * NumConstants::SMALL()) + ". There may be some computing issues.");
-          ApplicationTools::displayWarning("!!! Taylor series used instead");
-          break;
+          eigenValues_[nulleigen] = 0; // to avoid approximation errors on long long branches
+          iEigenValues_[nulleigen] = 0; // to avoid approximation errors on long long branches
+          
+          for (i = 0; i < salph; i++)
+            freq_[i] = leftEigenVectors_(nulleigen, i);
+          
+          x = 0;
+          for (i = 0; i < salph; i++)
+            x += freq_[i];
+          
+          for (i = 0; i < salph; i++)
+          freq_[i] /= x;
         }
+      
         else
-          seuil *= 10;
-      }
-
-      if (isNonSingular_)
-      {
-        eigenValues_[nulleigen] = 0; // to avoid approximation errors on long long branches
-        iEigenValues_[nulleigen] = 0; // to avoid approximation errors on long long branches
-
-        for (i = 0; i < salph; i++)
         {
-          freq_[i] = leftEigenVectors_(nulleigen, i);
-        }
-
-        x = 0;
-        for (i = 0; i < salph; i++)
-        {
-          x += freq_[i];
-        }
-
-        for (i = 0; i < salph; i++)
-        {
-          freq_[i] /= x;
+          ApplicationTools::displayMessage("Unable to find eigenvector for eigenvalue 1. Taylor series used instead.");
+          isDiagonalizable_ = false;
         }
       }
-      else
-      {
-        ApplicationTools::displayMessage("Unable to find eigenvector for eigenvalue 1. Taylor series used instead.");
-        isDiagonalizable_ = false;
-      }
     }
-
+    
     // if rightEigenVectors_ is singular
     catch (ZeroDivisionException& e)
     {
@@ -586,9 +571,7 @@ void AbstractWordSubstitutionModel::updateMatrices()
 
     x = 0;
     for (i = 0; i < salph; i++)
-    {
       x += freq_[i] * generator_(i, i);
-    }
 
     MatrixTools::scale(generator_, -1. / x);
     for (i = 0; i < salph; i++)
@@ -604,12 +587,9 @@ void AbstractWordSubstitutionModel::updateMatrices()
   // compute the exchangeability_
 
   for (i = 0; i < size_; i++)
-  {
     for (j = 0; j < size_; j++)
-    {
       exchangeability_(i, j) = generator_(i, j) / freq_[j];
-    }
-  }
+
 }
 
 void AbstractWordSubstitutionModel::setFreq(std::map<int, double>& freqs)
diff --git a/src/Bpp/Phyl/Model/AbstractWordSubstitutionModel.h b/src/Bpp/Phyl/Model/AbstractWordSubstitutionModel.h
index 3c736e5..7df2f9d 100644
--- a/src/Bpp/Phyl/Model/AbstractWordSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/AbstractWordSubstitutionModel.h
@@ -73,11 +73,11 @@ namespace bpp
  *
  */
 class AbstractWordSubstitutionModel :
-    public virtual AbstractSubstitutionModel
+    public AbstractSubstitutionModel
 {
 private:
   /**
-   * @ brief boolean flag to check if a specific WordAlphabet has been built
+   * @brief boolean flag to check if a specific WordAlphabet has been built
    */
   bool new_alphabet_;
 
@@ -109,11 +109,11 @@ public:
    *   the models must be different objects to avoid parameters
    *   redundancy, otherwise only the first model is used. The used models
    *   are owned by the instance.
-   * @param st the Namespace.
+   * @param prefix the Namespace.
    */
   AbstractWordSubstitutionModel(
     const std::vector<SubstitutionModel*>& modelVector,
-    const std::string& st);
+    const std::string& prefix);
 
   /**
    * @brief Build a new AbstractWordSubstitutionModel object from a
@@ -123,12 +123,12 @@ public:
    * @param pmodel A pointer to the substitution model to use in all
    * the positions. It will be owned by the instance.
    * @param num The number of models involved.
-   * @param st the Namespace.
+   * @param prefix the Namespace.
    */
   AbstractWordSubstitutionModel(
     SubstitutionModel* pmodel,
     unsigned int num,
-    const std::string& st);
+    const std::string& prefix);
 
   AbstractWordSubstitutionModel(const AbstractWordSubstitutionModel&);
 
@@ -140,9 +140,9 @@ public:
 
 protected:
   /**
-   *@brief Constructor for the derived classes only
+   * @brief Constructor for the derived classes only
    */
-  AbstractWordSubstitutionModel(const Alphabet* alph, const std::string&);
+  AbstractWordSubstitutionModel(const Alphabet* alph, StateMap* stateMap, const std::string& prefix);
 
 public:
   virtual size_t getNumberOfStates() const;
@@ -153,8 +153,8 @@ public:
    */
   
   const SubstitutionModel* getNModel(size_t i) const {
-    if (i< VSubMod_.size())
-        return dynamic_cast<const SubstitutionModel*>(VSubMod_[i]);
+    if (i < VSubMod_.size())
+      return dynamic_cast<const SubstitutionModel*>(VSubMod_[i]);
     else
       return 0;
   }
diff --git a/src/Bpp/Phyl/Model/BinarySubstitutionModel.cpp b/src/Bpp/Phyl/Model/BinarySubstitutionModel.cpp
index 3cac715..d43c8f5 100644
--- a/src/Bpp/Phyl/Model/BinarySubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/BinarySubstitutionModel.cpp
@@ -52,8 +52,8 @@ using namespace std;
 
 BinarySubstitutionModel::BinarySubstitutionModel(const BinaryAlphabet* alpha, double kappa) :
   AbstractParameterAliasable("Binary."),
-  AbstractSubstitutionModel(alpha, "Binary."),
-  AbstractReversibleSubstitutionModel(alpha, "Binary."),
+  //AbstractSubstitutionModel(alpha, new CanonicalStateMap(alpha, false), "Binary."),
+  AbstractReversibleSubstitutionModel(alpha, new CanonicalStateMap(alpha, false), "Binary."),
   kappa_(kappa),
   lambda_(0),
   exp_(0),
diff --git a/src/Bpp/Phyl/Model/Codon/AbstractCodonDistanceSubstitutionModel.cpp b/src/Bpp/Phyl/Model/Codon/AbstractCodonDistanceSubstitutionModel.cpp
index e7eef94..4dbdb5e 100644
--- a/src/Bpp/Phyl/Model/Codon/AbstractCodonDistanceSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/Codon/AbstractCodonDistanceSubstitutionModel.cpp
@@ -46,13 +46,11 @@ using namespace std;
 /******************************************************************************/
 
 AbstractCodonDistanceSubstitutionModel::AbstractCodonDistanceSubstitutionModel(
-  const GeneticCode* palph,
   const AlphabetIndex2* pdist,
   const std::string& prefix,
   bool paramSynRate) :
   CodonSubstitutionModel(),
   AbstractParameterAliasable(prefix),
-  geneticCode_(palph),
   pdistance_(pdist),
   alpha_(10000),
   beta_(1),
@@ -79,9 +77,9 @@ void AbstractCodonDistanceSubstitutionModel::fireParameterChanged(const Paramete
 
 double AbstractCodonDistanceSubstitutionModel::getCodonsMulRate(size_t i, size_t j) const
 {
-  return geneticCode_->areSynonymous(static_cast<int>(i), static_cast<int>(j)) ? gamma_ :
+  return getGeneticCode()->areSynonymous(static_cast<int>(i), static_cast<int>(j)) ? gamma_ :
          beta_ * (pdistance_ ? exp(-pdistance_->getIndex(
-                 geneticCode_->translate(static_cast<int>(i)),
-                 geneticCode_->translate(static_cast<int>(j))) / alpha_) : 1);
+                 getGeneticCode()->translate(static_cast<int>(i)),
+                 getGeneticCode()->translate(static_cast<int>(j))) / alpha_) : 1);
 }
 
diff --git a/src/Bpp/Phyl/Model/Codon/AbstractCodonDistanceSubstitutionModel.h b/src/Bpp/Phyl/Model/Codon/AbstractCodonDistanceSubstitutionModel.h
index 0b5a702..e5a9f87 100644
--- a/src/Bpp/Phyl/Model/Codon/AbstractCodonDistanceSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/Codon/AbstractCodonDistanceSubstitutionModel.h
@@ -70,14 +70,12 @@ namespace bpp
  *  multiplied with @f$\gamma at f$ (with optional positive parameter \c
  *  "gamma"), else it is multiplied with 1.
  *
- * 
  * References:
  * - Goldman N. and Yang Z. (1994), _Molecular Biology And Evolution_ 11(5) 725--736. 
- * _ Kosakovsky Pond, S. and Muse, S.V. (2005), _Molecular Biology And Evolution_,
+ * - Kosakovsky Pond, S. and Muse, S.V. (2005), _Molecular Biology And Evolution_,
  *   22(12), 2375--2385.
  * - Mayrose, I. and Doron-Faigenboim, A. and Bacharach, E. and Pupko T.
  *   (2007), Bioinformatics, 23, i319--i327.
- *
  */
 
 class AbstractCodonDistanceSubstitutionModel :
@@ -85,7 +83,6 @@ class AbstractCodonDistanceSubstitutionModel :
   public virtual AbstractParameterAliasable
 {
 private:
-  const GeneticCode* geneticCode_;
   const AlphabetIndex2* pdistance_;
 
   double alpha_, beta_;
@@ -93,27 +90,21 @@ private:
   double gamma_;
 public:
   /**
-   *@brief Build a new AbstractCodonDistanceSubstitutionModel object from
-   * a pointer to NucleotideSubstitutionModel.
+   * @brief Build a new AbstractCodonDistanceSubstitutionModel object from
+   *  a pointer to NucleotideSubstitutionModel.
    *
-   *@param palph pointer to a GeneticCode
-   *@param pdist optional pointer to a distance between amino-acids
-   *@param prefix the Namespace
-   *@param paramSynRate is true iff synonymous rate is parametrised
+   * @param pdist optional pointer to a distance between amino-acids
+   * @param prefix the Namespace
+   * @param paramSynRate is true iff synonymous rate is parametrised
    *       (default=false).
    */
-
   AbstractCodonDistanceSubstitutionModel(
-    const GeneticCode* palph,
     const AlphabetIndex2* pdist,
     const std::string& prefix,
     bool paramSynRate = false);
 
-
-  AbstractCodonDistanceSubstitutionModel(
-    const AbstractCodonDistanceSubstitutionModel& model) :
+  AbstractCodonDistanceSubstitutionModel(const AbstractCodonDistanceSubstitutionModel& model) :
     AbstractParameterAliasable(model),
-    geneticCode_(model.geneticCode_),
     pdistance_(model.pdistance_),
     alpha_(model.alpha_),
     beta_(model.beta_),
@@ -124,7 +115,6 @@ public:
     const AbstractCodonDistanceSubstitutionModel& model)
   {
     AbstractParameterAliasable::operator=(model);
-    geneticCode_ = model.geneticCode_;
     pdistance_ = model.pdistance_;
     alpha_ = model.alpha_;
     beta_ = model.beta_;
@@ -132,16 +122,15 @@ public:
     return *this;
   }
 
-  ~AbstractCodonDistanceSubstitutionModel() {}
+  virtual ~AbstractCodonDistanceSubstitutionModel() {}
 
 public:
   void fireParameterChanged(const ParameterList& parameters);
 
-  const GeneticCode* getGeneticCode() const { return geneticCode_; }
-
 public:
   double getCodonsMulRate(size_t i, size_t j) const;
 };
+
 } // end of namespace bpp.
 
 #endif
diff --git a/src/Bpp/Phyl/Model/Codon/AbstractCodonFitnessSubstitutionModel.cpp b/src/Bpp/Phyl/Model/Codon/AbstractCodonFitnessSubstitutionModel.cpp
index b15ab86..4c49591 100644
--- a/src/Bpp/Phyl/Model/Codon/AbstractCodonFitnessSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/Codon/AbstractCodonFitnessSubstitutionModel.cpp
@@ -5,7 +5,7 @@
 //
 
 /*
-  Copyright or © or Copr. CNRS, (November 16, 2004)
+  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.
  
@@ -62,7 +62,7 @@ void AbstractCodonFitnessSubstitutionModel::fireParameterChanged (const Paramete
 
 void AbstractCodonFitnessSubstitutionModel::setFreq(map<int, double>& frequencies)
 {
-  pfitset_->setFrequenciesFromMap(frequencies);
+  pfitset_->setFrequenciesFromAlphabetStatesFrequencies(frequencies);
   matchParametersValues(pfitset_->getParameters() );
 }
 
diff --git a/src/Bpp/Phyl/Model/Codon/AbstractCodonFitnessSubstitutionModel.h b/src/Bpp/Phyl/Model/Codon/AbstractCodonFitnessSubstitutionModel.h
index 0eb4707..49aa385 100644
--- a/src/Bpp/Phyl/Model/Codon/AbstractCodonFitnessSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/Codon/AbstractCodonFitnessSubstitutionModel.h
@@ -87,6 +87,7 @@ namespace bpp
 
     virtual ~AbstractCodonFitnessSubstitutionModel();
 
+  public:
     void fireParameterChanged (const ParameterList& parameters);
     void setFreq(std::map<int, double>& frequencies);
     const FrequenciesSet& getFreq() const { return *pfitset_; }
@@ -94,7 +95,6 @@ namespace bpp
       pfitset_->setNamespace(prefix + fitName_);
     }
 
-  public:
     double getCodonsMulRate(size_t i, size_t j) const;
 
     const FrequenciesSet* getFitness() const { return pfitset_;}
diff --git a/src/Bpp/Phyl/Model/Codon/AbstractCodonFrequenciesSubstitutionModel.cpp b/src/Bpp/Phyl/Model/Codon/AbstractCodonFrequenciesSubstitutionModel.cpp
index 491c37b..e93f50a 100644
--- a/src/Bpp/Phyl/Model/Codon/AbstractCodonFrequenciesSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/Codon/AbstractCodonFrequenciesSubstitutionModel.cpp
@@ -76,7 +76,7 @@ void AbstractCodonFrequenciesSubstitutionModel::fireParameterChanged(const Param
 
 void AbstractCodonFrequenciesSubstitutionModel::setFreq(map<int, double>& frequencies)
 {
-  pfreqset_->setFrequenciesFromMap(frequencies);
+  pfreqset_->setFrequenciesFromAlphabetStatesFrequencies(frequencies);
   matchParametersValues(pfreqset_->getParameters());
 }
 
diff --git a/src/Bpp/Phyl/Model/Codon/AbstractCodonPhaseFrequenciesSubstitutionModel.cpp b/src/Bpp/Phyl/Model/Codon/AbstractCodonPhaseFrequenciesSubstitutionModel.cpp
index 15f48ca..90fc857 100644
--- a/src/Bpp/Phyl/Model/Codon/AbstractCodonPhaseFrequenciesSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/Codon/AbstractCodonPhaseFrequenciesSubstitutionModel.cpp
@@ -5,7 +5,7 @@
 //
 
 /*
-   Copyright or © or Copr. CNRS, (November 16, 2004)
+   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.
 
@@ -37,8 +37,7 @@
  */
 
 #include "AbstractCodonPhaseFrequenciesSubstitutionModel.h"
-
-// #include <Bpp/Seq/Alphabet/AlphabetTools.h>
+#include "../FrequenciesSet/NucleotideFrequenciesSet.h"
 
 using namespace bpp;
 
@@ -55,30 +54,29 @@ AbstractCodonPhaseFrequenciesSubstitutionModel::AbstractCodonPhaseFrequenciesSub
   freqName_("")
 {
   CodonFrequenciesSet* pCFS = dynamic_cast<CodonFrequenciesSet*>(pfreq);
-  if (pCFS == NULL)
+  if (!pCFS)
     throw Exception("Bad type for equilibrium frequencies " + pfreq->getName());
 
-  if ((dynamic_cast<CodonFromUniqueFrequenciesSet*>(pCFS))
-      || (dynamic_cast<CodonFromIndependentFrequenciesSet*>(pCFS) != NULL))
+  if (dynamic_cast<CodonFromUniqueFrequenciesSet*>(pCFS)
+   || dynamic_cast<CodonFromIndependentFrequenciesSet*>(pCFS))
     posfreqset_ = dynamic_cast<WordFrequenciesSet*>(pfreq)->clone();
   else
   {
     vector<FrequenciesSet*> vFS;
-    if (dynamic_cast<FixedCodonFrequenciesSet*>(pCFS))
+    if (dynamic_cast<FixedCodonFrequenciesSet*>(pCFS)) {
       for (unsigned int i = 0; i < 3; i++)
       {
-        vFS.push_back(new FixedFrequenciesSet(
-              pCFS->getAlphabet()->getNucleicAlphabet(),
-              pCFS->getAlphabet()->getNucleicAlphabet()->getSize()));
+        vFS.push_back(new FixedNucleotideFrequenciesSet(pCFS->getAlphabet()->getNucleicAlphabet()));
       }
-    else
+    } else {
       for (unsigned int i = 0; i < 3; i++)
       {
-        vFS.push_back(new FullFrequenciesSet(pCFS->getAlphabet()->getNucleicAlphabet()));
+        vFS.push_back(new FullNucleotideFrequenciesSet(pCFS->getAlphabet()->getNucleicAlphabet()));
       }
-
-    posfreqset_ = new CodonFromIndependentFrequenciesSet(pCFS->getAlphabet(),
-                                                         vFS, "");
+    }
+    posfreqset_ = new CodonFromIndependentFrequenciesSet(
+        pCFS->getGeneticCode(),
+        vFS, "");
 
     posfreqset_->setFrequencies(pfreq->getFrequencies());
   }
@@ -103,7 +101,7 @@ void AbstractCodonPhaseFrequenciesSubstitutionModel::fireParameterChanged(const
 
 void AbstractCodonPhaseFrequenciesSubstitutionModel::setFreq(map<int, double>& frequencies)
 {
-  posfreqset_->setFrequenciesFromMap(frequencies);
+  posfreqset_->setFrequenciesFromAlphabetStatesFrequencies(frequencies);
   matchParametersValues(posfreqset_->getParameters());
 }
 
diff --git a/src/Bpp/Phyl/Model/Codon/AbstractCodonPhaseFrequenciesSubstitutionModel.h b/src/Bpp/Phyl/Model/Codon/AbstractCodonPhaseFrequenciesSubstitutionModel.h
index 698ab62..69e3cdc 100644
--- a/src/Bpp/Phyl/Model/Codon/AbstractCodonPhaseFrequenciesSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/Codon/AbstractCodonPhaseFrequenciesSubstitutionModel.h
@@ -71,25 +71,23 @@ class AbstractCodonPhaseFrequenciesSubstitutionModel :
   public virtual AbstractParameterAliasable
 {
 private:
-  /*
-   *@brief Position dependent version of Codon Frequencies Set
-   *
+  /**
+   * @brief Position dependent version of Codon Frequencies Set
    */
-
   WordFrequenciesSet* posfreqset_;
   std::string freqName_;
 
 public:
   /**
-   *@brief Build a AbstractCodonPhaseFrequenciesSubstitutionModel instance
+   * @brief Build a AbstractCodonPhaseFrequenciesSubstitutionModel instance
    *
-   *@param pfreq pointer to the AbstractFrequenciesSet equilibrium frequencies.
+   * @param pfreq pointer to the AbstractFrequenciesSet equilibrium frequencies.
    *        It is owned by the instance.
-   *@param prefix the Namespace
+   * @param prefix the Namespace
    */
-
-  AbstractCodonPhaseFrequenciesSubstitutionModel(FrequenciesSet* pfreq,
-                                                 const std::string& prefix);
+  AbstractCodonPhaseFrequenciesSubstitutionModel(
+      FrequenciesSet* pfreq,
+      const std::string& prefix);
 
   AbstractCodonPhaseFrequenciesSubstitutionModel(const AbstractCodonPhaseFrequenciesSubstitutionModel& model) :
     AbstractParameterAliasable(model),
diff --git a/src/Bpp/Phyl/Model/Codon/AbstractCodonSubstitutionModel.cpp b/src/Bpp/Phyl/Model/Codon/AbstractCodonSubstitutionModel.cpp
index fa5941e..f6eb83f 100644
--- a/src/Bpp/Phyl/Model/Codon/AbstractCodonSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/Codon/AbstractCodonSubstitutionModel.cpp
@@ -45,25 +45,25 @@ using namespace std;
 /******************************************************************************/
 
 AbstractCodonSubstitutionModel::AbstractCodonSubstitutionModel(
-  const CodonAlphabet* palph,
+  const GeneticCode* gCode,
   NucleotideSubstitutionModel* pmod,
-  const std::string& st,
+  const std::string& prefix,
   bool paramRates) :
-  AbstractParameterAliasable(st),
-  AbstractSubstitutionModel(palph, st),
-  AbstractWordSubstitutionModel(palph, st),
-  hasParametrizedRates_(paramRates)
+  AbstractParameterAliasable(prefix),
+  AbstractWordSubstitutionModel(gCode->getSourceAlphabet(), new CanonicalStateMap(gCode->getSourceAlphabet(), false), prefix),
+  hasParametrizedRates_(paramRates),
+  gCode_(gCode)
 {
-  enableEigenDecomposition(1);
+  enableEigenDecomposition(true);
 
-  unsigned int i;
+  size_t i;
   for (i = 0; i < 3; i++)
   {
     VSubMod_.push_back(pmod);
     VnestedPrefix_.push_back(pmod->getNamespace());
   }
 
-  pmod->setNamespace(st + "123_" + VnestedPrefix_[0]);
+  pmod->setNamespace(prefix + "123_" + VnestedPrefix_[0]);
   pmod->enableEigenDecomposition(0);
   addParameters_(pmod->getParameters());
 
@@ -79,35 +79,34 @@ AbstractCodonSubstitutionModel::AbstractCodonSubstitutionModel(
     // relative rates
     for (i = 0; i < 2; i++)
     {
-      addParameter_(new Parameter(st + "relrate" + TextTools::toString(i + 1), 1.0 / static_cast<double>(3 - i), &Parameter::PROP_CONSTRAINT_EX));
+      addParameter_(new Parameter(prefix + "relrate" + TextTools::toString(i + 1), 1.0 / static_cast<double>(3 - i), &Parameter::PROP_CONSTRAINT_EX));
     }
   }
 }
 
 AbstractCodonSubstitutionModel::AbstractCodonSubstitutionModel(
-  const CodonAlphabet* palph,
+  const GeneticCode* gCode,
   NucleotideSubstitutionModel* pmod1,
   NucleotideSubstitutionModel* pmod2,
   NucleotideSubstitutionModel* pmod3,
-  const std::string& st,
+  const std::string& prefix,
   bool paramRates) :
-  AbstractParameterAliasable(st),
-  AbstractSubstitutionModel(palph, st),
-  AbstractWordSubstitutionModel(palph, st),
-  hasParametrizedRates_(paramRates)
+  AbstractParameterAliasable(prefix),
+  AbstractWordSubstitutionModel(gCode->getSourceAlphabet(), new CanonicalStateMap(gCode->getSourceAlphabet(), false), prefix),
+  hasParametrizedRates_(paramRates),
+  gCode_(gCode)
 {
-  unsigned int i;
   enableEigenDecomposition(1);
 
   if ((pmod1 == pmod2) || (pmod2 == pmod3) || (pmod1 == pmod3))
   {
-    for (i = 0; i < 3; i++)
+    for (size_t i = 0; i < 3; ++i)
     {
       VSubMod_.push_back(pmod1);
       VnestedPrefix_.push_back(pmod1->getNamespace());
     }
 
-    pmod1->setNamespace(st + "123_" + VnestedPrefix_[0]);
+    pmod1->setNamespace(prefix + "123_" + VnestedPrefix_[0]);
     pmod1->enableEigenDecomposition(0);
     addParameters_(pmod1->getParameters());
   }
@@ -115,25 +114,25 @@ AbstractCodonSubstitutionModel::AbstractCodonSubstitutionModel(
   {
     VSubMod_.push_back(pmod1);
     VnestedPrefix_.push_back(pmod1->getNamespace());
-    VSubMod_[0]->setNamespace(st + "1_" + VnestedPrefix_[0]);
+    VSubMod_[0]->setNamespace(prefix + "1_" + VnestedPrefix_[0]);
     VSubMod_[0]->enableEigenDecomposition(0);
     addParameters_(pmod1->getParameters());
 
     VSubMod_.push_back(pmod2);
     VnestedPrefix_.push_back(pmod2->getNamespace());
-    VSubMod_[1]->setNamespace(st + "2_" + VnestedPrefix_[1]);
+    VSubMod_[1]->setNamespace(prefix + "2_" + VnestedPrefix_[1]);
     VSubMod_[1]->enableEigenDecomposition(0);
     addParameters_(pmod2->getParameters());
 
     VSubMod_.push_back(pmod3);
     VnestedPrefix_.push_back(pmod3->getNamespace());
-    VSubMod_[2]->setNamespace(st + "3_" + VnestedPrefix_[2]);
+    VSubMod_[2]->setNamespace(prefix + "3_" + VnestedPrefix_[2]);
     VSubMod_[2]->enableEigenDecomposition(0);
     addParameters_(pmod3->getParameters());
   }
 
   Vrate_.resize(3);
-  for (i = 0; i < 3; i++)
+  for (size_t i = 0; i < 3; ++i)
   {
     Vrate_[i] = 1.0 / 3;
   }
@@ -141,9 +140,9 @@ AbstractCodonSubstitutionModel::AbstractCodonSubstitutionModel(
   if (hasParametrizedRates_)
   {
     // relative rates
-    for (i = 0; i < 2; i++)
+    for (int i = 0; i < 2; ++i)
     {
-      addParameter_(new Parameter(st + "relrate" + TextTools::toString(i + 1), 1.0 / (3 - i), &Parameter::PROP_CONSTRAINT_EX));
+      addParameter_(new Parameter(prefix + "relrate" + TextTools::toString(i + 1), 1.0 / (3.0 - i), &Parameter::PROP_CONSTRAINT_EX));
     }
   }
 }
@@ -176,13 +175,11 @@ void AbstractCodonSubstitutionModel::completeMatrices()
   size_t i, j;
   size_t salph = getNumberOfStates();
 
-  const CodonAlphabet* ca = dynamic_cast<const CodonAlphabet*>(alphabet_);
-
   for (i = 0; i < salph; i++)
   {
     for (j = 0; j < salph; j++)
     {
-      if (ca->isStop(static_cast<int>(i)) || ca->isStop(static_cast<int>(j)))
+      if (gCode_->isStop(static_cast<int>(i)) || gCode_->isStop(static_cast<int>(j)))
       {
         generator_(i, j) = 0;
       }
diff --git a/src/Bpp/Phyl/Model/Codon/AbstractCodonSubstitutionModel.h b/src/Bpp/Phyl/Model/Codon/AbstractCodonSubstitutionModel.h
index f87cdae..006fefe 100644
--- a/src/Bpp/Phyl/Model/Codon/AbstractCodonSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/Codon/AbstractCodonSubstitutionModel.h
@@ -44,8 +44,11 @@
 #include "../Nucleotide/NucleotideSubstitutionModel.h"
 #include "CodonSubstitutionModel.h"
 
-// From SeqLib:
-#include <Bpp/Seq/Alphabet/CodonAlphabet.h>
+// From bpp-seq:
+#include <Bpp/Seq/GeneticCode/GeneticCode.h>
+
+// From the STL:
+#include <memory>
 
 namespace bpp
 {
@@ -66,42 +69,44 @@ namespace bpp
  * used. Their names have a new prefix, "i_" where i stands for the
  * the phase (1,2 or 3) in the codon.
  */
-
 class AbstractCodonSubstitutionModel :
   public virtual CodonSubstitutionModel,
-  public virtual AbstractWordSubstitutionModel
+  public AbstractWordSubstitutionModel
 {
 private:
   /**
    * @brief boolean for the parametrization of the position relative
    * rates. Default : false.
-   *
    */
   bool hasParametrizedRates_;
+  const GeneticCode* gCode_;
 
 public:
+  const GeneticCode* getGeneticCode() const { return gCode_; }
+  
   /**
    * @brief Build a new AbstractCodonSubstitutionModel object from
    * a pointer to a NucleotideSubstitutionModel.
    *
-   * @param palph pointer to a CodonAlphabet
+   * @param gCode a pointer toward a genetic code. The codon alphabet from the genetic code will be used by the model class.
    * @param pmod pointer to the NucleotideSubstitutionModel to use in
    *        the three positions. It is owned by the instance.
    * @param st string of the Namespace
    * @param paramRates boolean concerning the presence of position
    * relative rates (default: false)
    */
-
-  AbstractCodonSubstitutionModel(const CodonAlphabet* palph,
-                                 NucleotideSubstitutionModel* pmod,
-                                 const std::string& st,
-                                 bool paramRates = false);
+  AbstractCodonSubstitutionModel(
+      const GeneticCode* gCode,
+      NucleotideSubstitutionModel* pmod,
+      const std::string& st,
+      bool paramRates = false);
 
   /**
    * @brief Build a new AbstractCodonSubstitutionModel object
    * from three pointers to NucleotideSubstitutionModels.
    *
-   * @param palph pointer to a CodonAlphabet
+   * @param gCode a pointer toward a genetic code. This model instance will own the underlying GeneticCode object and delete it when required.
+   *   The codon alphabet from the genetic code will be used by the model class.
    * @param pmod1, pmod2, pmod3 are pointers to the
    *   NucleotideSubstitutionModel to use in the three positions.
    *   All the models must be different objects to avoid redundant
@@ -110,22 +115,21 @@ public:
    * @param paramRates boolean concerning the presence of position
    * relative rates (default: false)
    */
-
-  AbstractCodonSubstitutionModel(const CodonAlphabet*,
-                                 NucleotideSubstitutionModel* pmod1,
-                                 NucleotideSubstitutionModel* pmod2,
-                                 NucleotideSubstitutionModel* pmod3,
-                                 const std::string& st,
-                                 bool paramRates = false);
-
+  AbstractCodonSubstitutionModel(
+      const GeneticCode* gCode,
+      NucleotideSubstitutionModel* pmod1,
+      NucleotideSubstitutionModel* pmod2,
+      NucleotideSubstitutionModel* pmod3,
+      const std::string& st,
+      bool paramRates = false);
 
   virtual ~AbstractCodonSubstitutionModel() {}
 
   AbstractCodonSubstitutionModel(const AbstractCodonSubstitutionModel& model) :
     AbstractParameterAliasable(model),
-    AbstractSubstitutionModel(model),
     AbstractWordSubstitutionModel(model),
-    hasParametrizedRates_(model.hasParametrizedRates_)
+    hasParametrizedRates_(model.hasParametrizedRates_),
+    gCode_(model.gCode_)
   {}
 
   AbstractCodonSubstitutionModel& operator=(const AbstractCodonSubstitutionModel& model)
@@ -134,6 +138,7 @@ public:
     AbstractSubstitutionModel::operator=(model);
     AbstractWordSubstitutionModel::operator=(model);
     hasParametrizedRates_ = model.hasParametrizedRates_;
+    gCode_ = model.gCode_;
     return *this;
   }
 
@@ -150,9 +155,7 @@ protected:
    *
    * This method sets the rates to/from stop codons to zero and
    * performs the multiplication by the specific codon-codon rate.
-   *
-   **/
-
+   */
   void completeMatrices();
 
 public:
diff --git a/src/Bpp/Phyl/Model/Codon/CodonDistanceFitnessPhaseFrequenciesSubstitutionModel.cpp b/src/Bpp/Phyl/Model/Codon/CodonDistanceFitnessPhaseFrequenciesSubstitutionModel.cpp
index 6e5d28b..3e4170b 100644
--- a/src/Bpp/Phyl/Model/Codon/CodonDistanceFitnessPhaseFrequenciesSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/Codon/CodonDistanceFitnessPhaseFrequenciesSubstitutionModel.cpp
@@ -42,34 +42,32 @@
 using namespace bpp;
 using namespace std;
 
-CodonDistanceFitnessPhaseFrequenciesSubstitutionModel::CodonDistanceFitnessPhaseFrequenciesSubstitutionModel(const GeneticCode* palph,
-                                                             NucleotideSubstitutionModel* pmod,
-                                                             FrequenciesSet* pfit,
-                                                             FrequenciesSet* pfreq,
-                                                             const AlphabetIndex2* pdist) :
+CodonDistanceFitnessPhaseFrequenciesSubstitutionModel::CodonDistanceFitnessPhaseFrequenciesSubstitutionModel(
+    const GeneticCode* gCode,
+    NucleotideSubstitutionModel* pmod,
+    FrequenciesSet* pfit,
+    FrequenciesSet* pfreq,
+    const AlphabetIndex2* pdist) :
   AbstractParameterAliasable("CodonDistFitPhasFreq."),
-  AbstractSubstitutionModel(dynamic_cast<const CodonAlphabet*>(palph->getSourceAlphabet()), "CodonDistFitPhasFreq."),
-  AbstractWordSubstitutionModel(dynamic_cast<const CodonAlphabet*>(palph->getSourceAlphabet()), "CodonDistFitPhasFreq."),
-  AbstractCodonSubstitutionModel(dynamic_cast<const CodonAlphabet*>(palph->getSourceAlphabet()), pmod, "CodonDistFitPhasFreq."),
-  AbstractCodonDistanceSubstitutionModel(palph, pdist, "CodonDistFitPhasFreq."),
+  AbstractCodonSubstitutionModel(gCode, pmod, "CodonDistFitPhasFreq."),
+  AbstractCodonDistanceSubstitutionModel(pdist, "CodonDistFitPhasFreq."),
   AbstractCodonPhaseFrequenciesSubstitutionModel(pfreq, "CodonDistFitPhasFreq."),
   AbstractCodonFitnessSubstitutionModel(pfit, "CodonDistFitPhasFreq.")
 {
   updateMatrices();
 }
 
-CodonDistanceFitnessPhaseFrequenciesSubstitutionModel::CodonDistanceFitnessPhaseFrequenciesSubstitutionModel(const GeneticCode* palph,
-                                                             NucleotideSubstitutionModel* pmod1,
-                                                             NucleotideSubstitutionModel* pmod2,
-                                                             NucleotideSubstitutionModel* pmod3,
-                                                             FrequenciesSet* pfit,
-                                                             FrequenciesSet* pfreq,
-                                                             const AlphabetIndex2* pdist) :
+CodonDistanceFitnessPhaseFrequenciesSubstitutionModel::CodonDistanceFitnessPhaseFrequenciesSubstitutionModel(
+    const GeneticCode* gCode,
+    NucleotideSubstitutionModel* pmod1,
+    NucleotideSubstitutionModel* pmod2,
+    NucleotideSubstitutionModel* pmod3,
+    FrequenciesSet* pfit,
+    FrequenciesSet* pfreq,
+    const AlphabetIndex2* pdist) :
   AbstractParameterAliasable("CodonDistFitPhasFreq."),
-  AbstractSubstitutionModel(dynamic_cast<const CodonAlphabet*>(palph->getSourceAlphabet()), "CodonDistFitPhasFreq."),
-  AbstractWordSubstitutionModel(dynamic_cast<const CodonAlphabet*>(palph->getSourceAlphabet()), "CodonDistFitPhasFreq."),
-  AbstractCodonSubstitutionModel(dynamic_cast<const CodonAlphabet*>(palph->getSourceAlphabet()), pmod1, pmod2, pmod3, "CodonDistFitPhasFreq."),
-  AbstractCodonDistanceSubstitutionModel(palph, pdist, "CodonDistFitPhasFreq."),
+  AbstractCodonSubstitutionModel(gCode, pmod1, pmod2, pmod3, "CodonDistFitPhasFreq."),
+  AbstractCodonDistanceSubstitutionModel(pdist, "CodonDistFitPhasFreq."),
   AbstractCodonPhaseFrequenciesSubstitutionModel(pfreq, "CodonDistFitPhasFreq."),
   AbstractCodonFitnessSubstitutionModel(pfit,"CodonDistFitPhasFreq.")
 {
@@ -110,6 +108,24 @@ void CodonDistanceFitnessPhaseFrequenciesSubstitutionModel::setNamespace(const s
 void CodonDistanceFitnessPhaseFrequenciesSubstitutionModel::setFreq(map<int,double>& frequencies)
 {
   AbstractCodonPhaseFrequenciesSubstitutionModel::setFreq(frequencies);
+  map<int, double> freq1 = AbstractCodonPhaseFrequenciesSubstitutionModel::getFrequenciesSet()->getAlphabetStatesFrequencies();
+
+  map<int, double> freq2;
+  double s=0;
+  map<int, double>::iterator it;
+
+  for (it=frequencies.begin();it!=frequencies.end();it++)
+  {
+    freq2[it->first]=(freq1[it->first] != 0 ? it->second/freq1[it->first] : 0);
+    s += freq2[it->first];
+  }
+  
+  for (it = freq2.begin(); it != freq2.end(); it++)
+    freq2[it->first] /= s;
+
+  AbstractCodonFitnessSubstitutionModel::setFreq(freq2);
+
+  updateMatrices();
 }
 
 
diff --git a/src/Bpp/Phyl/Model/Codon/CodonDistanceFitnessPhaseFrequenciesSubstitutionModel.h b/src/Bpp/Phyl/Model/Codon/CodonDistanceFitnessPhaseFrequenciesSubstitutionModel.h
index f044327..8aceb00 100644
--- a/src/Bpp/Phyl/Model/Codon/CodonDistanceFitnessPhaseFrequenciesSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/Codon/CodonDistanceFitnessPhaseFrequenciesSubstitutionModel.h
@@ -90,52 +90,30 @@ namespace bpp
    * Reference:
    * -  Yang Z. and Nielsen R. (2008), _Molecular Biology and Evolution_ 25(3):568--579.
    */
-
-
   class CodonDistanceFitnessPhaseFrequenciesSubstitutionModel :
+    public virtual ReversibleSubstitutionModel,
     public AbstractCodonSubstitutionModel,
     public AbstractCodonDistanceSubstitutionModel,
     public AbstractCodonPhaseFrequenciesSubstitutionModel,
     public AbstractCodonFitnessSubstitutionModel
   {
   public:
-    CodonDistanceFitnessPhaseFrequenciesSubstitutionModel(const GeneticCode* palph,
-                                  NucleotideSubstitutionModel* pmod,
-                                  FrequenciesSet* pfit,
-                                  FrequenciesSet* pfreq,
-                                  const AlphabetIndex2* pdist = 0);
-    CodonDistanceFitnessPhaseFrequenciesSubstitutionModel(const GeneticCode* palph,
-                                  NucleotideSubstitutionModel* pmod1,
-                                  NucleotideSubstitutionModel* pmod2,
-                                  NucleotideSubstitutionModel* pmod3,
-                                  FrequenciesSet* pfit,
-                                  FrequenciesSet* pfreq,
-                                  const AlphabetIndex2* pdist = 0);
-
-    CodonDistanceFitnessPhaseFrequenciesSubstitutionModel(const CodonDistanceFitnessPhaseFrequenciesSubstitutionModel& model) :
-      AbstractParameterAliasable(model),
-      AbstractSubstitutionModel(model),
-      AbstractWordSubstitutionModel(model),
-      AbstractCodonSubstitutionModel(model),
-      AbstractCodonDistanceSubstitutionModel(model),
-      AbstractCodonPhaseFrequenciesSubstitutionModel(model),
-      AbstractCodonFitnessSubstitutionModel(model)
-    {}
-
-    CodonDistanceFitnessPhaseFrequenciesSubstitutionModel& operator=(
-                                                                     const CodonDistanceFitnessPhaseFrequenciesSubstitutionModel& model)
-    {
-      AbstractParameterAliasable::operator=(model);
-      AbstractSubstitutionModel::operator=(model);
-      AbstractWordSubstitutionModel::operator=(model);
-      AbstractCodonSubstitutionModel::operator=(model);
-      AbstractCodonDistanceSubstitutionModel::operator=(model);
-      AbstractCodonPhaseFrequenciesSubstitutionModel::operator=(model);
-      AbstractCodonFitnessSubstitutionModel::operator=(model);
-      return *this;
-    }
-
-    ~CodonDistanceFitnessPhaseFrequenciesSubstitutionModel() {}
+    CodonDistanceFitnessPhaseFrequenciesSubstitutionModel(
+        const GeneticCode* gCode,
+        NucleotideSubstitutionModel* pmod,
+        FrequenciesSet* pfit,
+        FrequenciesSet* pfreq,
+        const AlphabetIndex2* pdist = 0);
+    CodonDistanceFitnessPhaseFrequenciesSubstitutionModel(
+        const GeneticCode* gCode,
+        NucleotideSubstitutionModel* pmod1,
+        NucleotideSubstitutionModel* pmod2,
+        NucleotideSubstitutionModel* pmod3,
+        FrequenciesSet* pfit,
+        FrequenciesSet* pfreq,
+        const AlphabetIndex2* pdist = 0);
+
+    virtual ~CodonDistanceFitnessPhaseFrequenciesSubstitutionModel() {}
 
     CodonDistanceFitnessPhaseFrequenciesSubstitutionModel* clone() const
     {
@@ -151,6 +129,18 @@ namespace bpp
 
     void setNamespace(const std::string&);
 
+    /*
+     * @brief set the phasefrequencies and fitness of the model from
+     * given frequencies, such that the equilibrium frequencies of the
+     * model matches at best the given ones.
+     * 
+     * Matching is done in two steps : first, phase frequencies are
+     * matched at best, then the resulting discrepancy (in terms of
+     * ratios between the given one and the one computed by the pahse
+     * frequencies) is given for matching to the fitness.
+     *
+     * @ param frequencies  the frequencies to match on.
+     */
     void setFreq(std::map<int,double>& frequencies);
 
   };
diff --git a/src/Bpp/Phyl/Model/Codon/CodonDistanceFrequenciesSubstitutionModel.cpp b/src/Bpp/Phyl/Model/Codon/CodonDistanceFrequenciesSubstitutionModel.cpp
index 58fe922..fc86530 100644
--- a/src/Bpp/Phyl/Model/Codon/CodonDistanceFrequenciesSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/Codon/CodonDistanceFrequenciesSubstitutionModel.cpp
@@ -5,7 +5,7 @@
 //
 
 /*
-  Copyright or © or Copr. CNRS, (November 16, 2004)
+  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.
 
@@ -44,33 +44,31 @@ using namespace std;
 
 /******************************************************************************/
 
-CodonDistanceFrequenciesSubstitutionModel::CodonDistanceFrequenciesSubstitutionModel(const GeneticCode* palph,
-                                                                                     NucleotideSubstitutionModel* pmod,
-                                                                                     FrequenciesSet* pfreq,
-                                                                                     const AlphabetIndex2* pdist,
-                                                                                     bool paramSynRate) :
+CodonDistanceFrequenciesSubstitutionModel::CodonDistanceFrequenciesSubstitutionModel(
+    const GeneticCode* gCode,
+    NucleotideSubstitutionModel* pmod,
+    FrequenciesSet* pfreq,
+    const AlphabetIndex2* pdist,
+    bool paramSynRate) :
   AbstractParameterAliasable("CodonDistFreq."),
-  AbstractSubstitutionModel(dynamic_cast<const CodonAlphabet*>(palph->getSourceAlphabet()), "CodonDistFreq."),
-  AbstractWordSubstitutionModel(dynamic_cast<const CodonAlphabet*>(palph->getSourceAlphabet()), "CodonDistFreq."),
-  AbstractCodonSubstitutionModel(dynamic_cast<const CodonAlphabet*>(palph->getSourceAlphabet()), pmod, "CodonDistFreq."),
-  AbstractCodonDistanceSubstitutionModel(palph, pdist, "CodonDistFreq.", paramSynRate),
+  AbstractCodonSubstitutionModel(gCode, pmod, "CodonDistFreq."),
+  AbstractCodonDistanceSubstitutionModel(pdist, "CodonDistFreq.", paramSynRate),
   AbstractCodonFrequenciesSubstitutionModel(pfreq, "CodonDistFreq.")
 {
   updateMatrices();
 }
 
-CodonDistanceFrequenciesSubstitutionModel::CodonDistanceFrequenciesSubstitutionModel(const GeneticCode* palph,
-                                                                                     NucleotideSubstitutionModel* pmod1,
-                                                                                     NucleotideSubstitutionModel* pmod2,
-                                                                                     NucleotideSubstitutionModel* pmod3,
-                                                                                     FrequenciesSet* pfreq,
-                                                                                     const AlphabetIndex2* pdist,
-                                                                                     bool paramSynRate) :
+CodonDistanceFrequenciesSubstitutionModel::CodonDistanceFrequenciesSubstitutionModel(
+    const GeneticCode* gCode,
+    NucleotideSubstitutionModel* pmod1,
+    NucleotideSubstitutionModel* pmod2,
+    NucleotideSubstitutionModel* pmod3,
+    FrequenciesSet* pfreq,
+    const AlphabetIndex2* pdist,
+    bool paramSynRate) :
   AbstractParameterAliasable("CodonDistFreq."),
-  AbstractSubstitutionModel(dynamic_cast<const CodonAlphabet*>(palph->getSourceAlphabet()), "CodonDistFreq."),
-  AbstractWordSubstitutionModel(dynamic_cast<const CodonAlphabet*>(palph->getSourceAlphabet()), "CodonDistFreq."),
-  AbstractCodonSubstitutionModel(dynamic_cast<const CodonAlphabet*>(palph->getSourceAlphabet()), pmod1, pmod2, pmod3, "CodonDistFreq."),
-  AbstractCodonDistanceSubstitutionModel(palph, pdist, "CodonDistFreq.", paramSynRate),
+  AbstractCodonSubstitutionModel(gCode, pmod1, pmod2, pmod3, "CodonDistFreq."),
+  AbstractCodonDistanceSubstitutionModel(pdist, "CodonDistFreq.", paramSynRate),
   AbstractCodonFrequenciesSubstitutionModel(pfreq, "CodonDistFreq.")
 {
   updateMatrices();
diff --git a/src/Bpp/Phyl/Model/Codon/CodonDistanceFrequenciesSubstitutionModel.h b/src/Bpp/Phyl/Model/Codon/CodonDistanceFrequenciesSubstitutionModel.h
index 05bb7fa..2d2e999 100644
--- a/src/Bpp/Phyl/Model/Codon/CodonDistanceFrequenciesSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/Codon/CodonDistanceFrequenciesSubstitutionModel.h
@@ -82,7 +82,6 @@ namespace bpp
  * and synonymous substitutions rates is @f$\beta at f$ with positive
  * parameter \c "beta".
  */
-
 class CodonDistanceFrequenciesSubstitutionModel :
     public AbstractCodonSubstitutionModel,
     public AbstractCodonDistanceSubstitutionModel,
@@ -94,7 +93,7 @@ public:
    * from three pointers to AbstractSubstitutionModels. NEW
    * AbstractSubstitutionModels are copied from the given ones.
    *
-   * @param palph pointer to a GeneticCode
+   * @param gCode pointer to a GeneticCode
    * @param pmod pointer to the NucleotideSubstitutionModel to use in
    *        the three positions. It is owned by the instance.
    * @param pfreq pointer to the FrequenciesSet* equilibrium frequencies
@@ -103,18 +102,19 @@ public:
    * @param paramSynRate is true iff synonymous rate is parametrised
    *        (default=false).
    */
-  CodonDistanceFrequenciesSubstitutionModel(const GeneticCode* palph,
-                                            NucleotideSubstitutionModel* pmod,
-                                            FrequenciesSet* pfreq,
-                                            const AlphabetIndex2* pdist = 0,
-                                            bool paramSynRate = false);
+  CodonDistanceFrequenciesSubstitutionModel(
+      const GeneticCode* gCode,
+      NucleotideSubstitutionModel* pmod,
+      FrequenciesSet* pfreq,
+      const AlphabetIndex2* pdist = 0,
+      bool paramSynRate = false);
 
   /**
    * @brief Build a new CodonDistanceFrequenciesSubstitutionModel object
    * from three pointers to AbstractSubstitutionModels. NEW
    * AbstractSubstitutionModels are copied from the given ones.
    *
-   * @param palph pointer to a GeneticCode
+   * @param gCode pointer to a GeneticCode
    * @param pmod1, pmod2, pmod3 are pointers to the
    *   NucleotideSubstitutionModel to use in the three positions.
    *   All the models must be different objects to avoid redundant
@@ -125,39 +125,16 @@ public:
    * @param paramSynRate is true iff synonymous rate is parametrised
    *   (default=false).
    */
-  CodonDistanceFrequenciesSubstitutionModel(const GeneticCode* palph,
-                                            NucleotideSubstitutionModel* pmod1,
-                                            NucleotideSubstitutionModel* pmod2,
-                                            NucleotideSubstitutionModel* pmod3,
-                                            FrequenciesSet* pfreq,
-                                            const AlphabetIndex2* pdist = 0,
-                                            bool paramSynRate = false);
-
-
   CodonDistanceFrequenciesSubstitutionModel(
-    const CodonDistanceFrequenciesSubstitutionModel& model) :
-    AbstractParameterAliasable(model),
-    AbstractSubstitutionModel(model),
-    AbstractWordSubstitutionModel(model),
-    AbstractCodonSubstitutionModel(model),
-    AbstractCodonDistanceSubstitutionModel(model),
-    AbstractCodonFrequenciesSubstitutionModel(model)
-  {
-  }
-
-  CodonDistanceFrequenciesSubstitutionModel& operator=(
-    const CodonDistanceFrequenciesSubstitutionModel& model)
-  {
-    AbstractParameterAliasable::operator=(model);
-    AbstractSubstitutionModel::operator=(model);
-    AbstractWordSubstitutionModel::operator=(model);
-    AbstractCodonSubstitutionModel::operator=(model);
-    AbstractCodonDistanceSubstitutionModel::operator=(model);
-    AbstractCodonFrequenciesSubstitutionModel::operator=(model);
-    return *this;
-  }
-
-  ~CodonDistanceFrequenciesSubstitutionModel() {}
+      const GeneticCode* gCode,
+      NucleotideSubstitutionModel* pmod1,
+      NucleotideSubstitutionModel* pmod2,
+      NucleotideSubstitutionModel* pmod3,
+      FrequenciesSet* pfreq,
+      const AlphabetIndex2* pdist = 0,
+      bool paramSynRate = false);
+
+  virtual ~CodonDistanceFrequenciesSubstitutionModel() {}
 
   CodonDistanceFrequenciesSubstitutionModel* clone() const
   {
diff --git a/src/Bpp/Phyl/Model/Codon/CodonDistancePhaseFrequenciesSubstitutionModel.cpp b/src/Bpp/Phyl/Model/Codon/CodonDistancePhaseFrequenciesSubstitutionModel.cpp
index e5d82c3..b40273d 100644
--- a/src/Bpp/Phyl/Model/Codon/CodonDistancePhaseFrequenciesSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/Codon/CodonDistancePhaseFrequenciesSubstitutionModel.cpp
@@ -5,7 +5,7 @@
 //
 
 /*
-  Copyright or © or Copr. CNRS, (November 16, 2004)
+  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.
 
@@ -44,31 +44,29 @@ using namespace std;
 
 /******************************************************************************/
 
-CodonDistancePhaseFrequenciesSubstitutionModel::CodonDistancePhaseFrequenciesSubstitutionModel(const GeneticCode* palph,
-                                                                                     NucleotideSubstitutionModel* pmod,
-                                                                                     FrequenciesSet* pfreq,
-                                                                                     const AlphabetIndex2* pdist) :
+CodonDistancePhaseFrequenciesSubstitutionModel::CodonDistancePhaseFrequenciesSubstitutionModel(
+    const GeneticCode* gCode,
+    NucleotideSubstitutionModel* pmod,
+    FrequenciesSet* pfreq,
+    const AlphabetIndex2* pdist) :
   AbstractParameterAliasable("CodonDistPhasFreq."),
-  AbstractSubstitutionModel(dynamic_cast<const CodonAlphabet*>(palph->getSourceAlphabet()), "CodonDistPhasFreq."),
-  AbstractWordSubstitutionModel(dynamic_cast<const CodonAlphabet*>(palph->getSourceAlphabet()), "CodonDistPhasFreq."),
-  AbstractCodonSubstitutionModel(dynamic_cast<const CodonAlphabet*>(palph->getSourceAlphabet()), pmod, "CodonDistPhasFreq."),
-  AbstractCodonDistanceSubstitutionModel(palph, pdist, "CodonDistPhasFreq."),
+  AbstractCodonSubstitutionModel(gCode, pmod, "CodonDistPhasFreq."),
+  AbstractCodonDistanceSubstitutionModel(pdist, "CodonDistPhasFreq."),
   AbstractCodonPhaseFrequenciesSubstitutionModel(pfreq, "CodonDistPhasFreq.")
 {
   updateMatrices();
 }
 
-CodonDistancePhaseFrequenciesSubstitutionModel::CodonDistancePhaseFrequenciesSubstitutionModel(const GeneticCode* palph,
-                                                                                     NucleotideSubstitutionModel* pmod1,
-                                                                                     NucleotideSubstitutionModel* pmod2,
-                                                                                     NucleotideSubstitutionModel* pmod3,
-                                                                                     FrequenciesSet* pfreq,
-                                                                                     const AlphabetIndex2* pdist) :
+CodonDistancePhaseFrequenciesSubstitutionModel::CodonDistancePhaseFrequenciesSubstitutionModel(
+    const GeneticCode* gCode,
+    NucleotideSubstitutionModel* pmod1,
+    NucleotideSubstitutionModel* pmod2,
+    NucleotideSubstitutionModel* pmod3,
+    FrequenciesSet* pfreq,
+    const AlphabetIndex2* pdist) :
   AbstractParameterAliasable("CodonDistPhasFreq."),
-  AbstractSubstitutionModel(dynamic_cast<const CodonAlphabet*>(palph->getSourceAlphabet()), "CodonDistPhasFreq."),
-  AbstractWordSubstitutionModel(dynamic_cast<const CodonAlphabet*>(palph->getSourceAlphabet()), "CodonDistPhasFreq."),
-  AbstractCodonSubstitutionModel(dynamic_cast<const CodonAlphabet*>(palph->getSourceAlphabet()), pmod1, pmod2, pmod3, "CodonDistPhasFreq."),
-  AbstractCodonDistanceSubstitutionModel(palph, pdist, "CodonDistPhasFreq."),
+  AbstractCodonSubstitutionModel(gCode, pmod1, pmod2, pmod3, "CodonDistPhasFreq."),
+  AbstractCodonDistanceSubstitutionModel(pdist, "CodonDistPhasFreq."),
   AbstractCodonPhaseFrequenciesSubstitutionModel(pfreq, "CodonDistPhasFreq.")
 {
   updateMatrices();
diff --git a/src/Bpp/Phyl/Model/Codon/CodonDistancePhaseFrequenciesSubstitutionModel.h b/src/Bpp/Phyl/Model/Codon/CodonDistancePhaseFrequenciesSubstitutionModel.h
index 7a7c192..d154f2e 100644
--- a/src/Bpp/Phyl/Model/Codon/CodonDistancePhaseFrequenciesSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/Codon/CodonDistancePhaseFrequenciesSubstitutionModel.h
@@ -74,7 +74,6 @@ namespace bpp
  * and synonymous substitutions rates is @f$\beta at f$ with positive
  * parameter \c "beta".
  */
-
 class CodonDistancePhaseFrequenciesSubstitutionModel :
     public AbstractCodonSubstitutionModel,
     public AbstractCodonDistanceSubstitutionModel,
@@ -86,23 +85,24 @@ public:
    * from three pointers to AbstractSubstitutionModels. NEW
    * AbstractSubstitutionModels are copied from the given ones.
    *
-   * @param palph pointer to a GeneticCode
+   * @param gCode pointer to a GeneticCode
    * @param pmod pointer to the NucleotideSubstitutionModel to use in
    *        the three positions. It is owned by the instance.
    * @param pfreq pointer to the FrequenciesSet* equilibrium frequencies
    * @param pdist optional pointer to the AlphabetIndex2 amino-acids distance object.
    */
-  CodonDistancePhaseFrequenciesSubstitutionModel(const GeneticCode* palph,
-                                            NucleotideSubstitutionModel* pmod,
-                                            FrequenciesSet* pfreq,
-                                            const AlphabetIndex2* pdist = 0);
+  CodonDistancePhaseFrequenciesSubstitutionModel(
+      const GeneticCode* gCode,
+      NucleotideSubstitutionModel* pmod,
+      FrequenciesSet* pfreq,
+      const AlphabetIndex2* pdist = 0);
 
   /**
    * @brief Build a new CodonDistancePhaseFrequenciesSubstitutionModel object
    * from three pointers to AbstractSubstitutionModels. NEW
    * AbstractSubstitutionModels are copied from the given ones.
    *
-   * @param palph pointer to a GeneticCode
+   * @param gCode pointer to a GeneticCode
    * @param pmod1, pmod2, pmod3 are pointers to the
    *   NucleotideSubstitutionModel to use in the three positions.
    *   All the models must be different objects to avoid redundant
@@ -110,36 +110,15 @@ public:
    * @param pfreq pointer to the FrequenciesSet* equilibrium frequencies
    * @param pdist optional pointer to the AlphabetIndex2 amino-acids distance object.
    */
-  CodonDistancePhaseFrequenciesSubstitutionModel(const GeneticCode* palph,
-                                            NucleotideSubstitutionModel* pmod1,
-                                            NucleotideSubstitutionModel* pmod2,
-                                            NucleotideSubstitutionModel* pmod3,
-                                            FrequenciesSet* pfreq,
-                                            const AlphabetIndex2* pdist = 0);
-
   CodonDistancePhaseFrequenciesSubstitutionModel(
-    const CodonDistancePhaseFrequenciesSubstitutionModel& model) :
-    AbstractParameterAliasable(model),
-    AbstractSubstitutionModel(model),
-    AbstractWordSubstitutionModel(model),
-    AbstractCodonSubstitutionModel(model),
-    AbstractCodonDistanceSubstitutionModel(model),
-    AbstractCodonPhaseFrequenciesSubstitutionModel(model)
-  {}
-
-  CodonDistancePhaseFrequenciesSubstitutionModel& operator=(
-    const CodonDistancePhaseFrequenciesSubstitutionModel& model)
-  {
-    AbstractParameterAliasable::operator=(model);
-    AbstractSubstitutionModel::operator=(model);
-    AbstractWordSubstitutionModel::operator=(model);
-    AbstractCodonSubstitutionModel::operator=(model);
-    AbstractCodonDistanceSubstitutionModel::operator=(model);
-    AbstractCodonPhaseFrequenciesSubstitutionModel::operator=(model);
-    return *this;
-  }
-
-  ~CodonDistancePhaseFrequenciesSubstitutionModel() {}
+      const GeneticCode* gCode,
+      NucleotideSubstitutionModel* pmod1,
+      NucleotideSubstitutionModel* pmod2,
+      NucleotideSubstitutionModel* pmod3,
+      FrequenciesSet* pfreq,
+      const AlphabetIndex2* pdist = 0);
+
+  virtual ~CodonDistancePhaseFrequenciesSubstitutionModel() {}
 
   CodonDistancePhaseFrequenciesSubstitutionModel* clone() const
   {
diff --git a/src/Bpp/Phyl/Model/Codon/CodonDistanceSubstitutionModel.cpp b/src/Bpp/Phyl/Model/Codon/CodonDistanceSubstitutionModel.cpp
index fbe750e..daf14a1 100644
--- a/src/Bpp/Phyl/Model/Codon/CodonDistanceSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/Codon/CodonDistanceSubstitutionModel.cpp
@@ -44,41 +44,33 @@ using namespace std;
 
 /******************************************************************************/
 
-CodonDistanceSubstitutionModel::CodonDistanceSubstitutionModel(const GeneticCode* palph,
-                                                               NucleotideSubstitutionModel* pmod,
-                                                               const AlphabetIndex2* pdist) :
+CodonDistanceSubstitutionModel::CodonDistanceSubstitutionModel(
+    const GeneticCode* gCode,
+    NucleotideSubstitutionModel* pmod,
+    const AlphabetIndex2* pdist) :
   AbstractParameterAliasable("CodonDist."),
-  AbstractSubstitutionModel(dynamic_cast<const CodonAlphabet*>(palph->getSourceAlphabet()),
-      "CodonDist."),
-  AbstractWordSubstitutionModel(dynamic_cast<const CodonAlphabet*>(palph->getSourceAlphabet()),
-      "CodonDist."),
-  AbstractCodonSubstitutionModel(dynamic_cast<const CodonAlphabet*>(palph->getSourceAlphabet()),
-      pmod, "CodonDist."),
-  AbstractCodonDistanceSubstitutionModel(palph, pdist, "CodonDist.")
+  AbstractCodonSubstitutionModel(gCode, pmod, "CodonDist."),
+  AbstractCodonDistanceSubstitutionModel(pdist, "CodonDist.")
 {
   updateMatrices();
 }
 
-CodonDistanceSubstitutionModel::CodonDistanceSubstitutionModel(const GeneticCode* palph,
-                                                               NucleotideSubstitutionModel* pmod1,
-                                                               NucleotideSubstitutionModel* pmod2,
-                                                               NucleotideSubstitutionModel* pmod3,
-                                                               const AlphabetIndex2* pdist) :
+CodonDistanceSubstitutionModel::CodonDistanceSubstitutionModel(
+    const GeneticCode* gCode,
+    NucleotideSubstitutionModel* pmod1,
+    NucleotideSubstitutionModel* pmod2,
+    NucleotideSubstitutionModel* pmod3,
+    const AlphabetIndex2* pdist) :
   AbstractParameterAliasable("CodonDist."),
-  AbstractSubstitutionModel(dynamic_cast<const CodonAlphabet*>(palph->getSourceAlphabet()),
-      "CodonDist."),
-  AbstractWordSubstitutionModel(dynamic_cast<const CodonAlphabet*>(palph->getSourceAlphabet()),
-      "CodonDist."),
-  AbstractCodonSubstitutionModel(dynamic_cast<const CodonAlphabet*>(palph->getSourceAlphabet()),
-      pmod1, pmod2, pmod3, "CodonDist."),
-  AbstractCodonDistanceSubstitutionModel(palph, pdist, "CodonDist.")
+  AbstractCodonSubstitutionModel(gCode, pmod1, pmod2, pmod3, "CodonDist."),
+  AbstractCodonDistanceSubstitutionModel(pdist, "CodonDist.")
 {
   updateMatrices();
 }
 
 std::string CodonDistanceSubstitutionModel::getName() const
 {
-  return ("CodonDist");
+  return "CodonDist";
 }
 
 void CodonDistanceSubstitutionModel::fireParameterChanged(const ParameterList& parameters)
diff --git a/src/Bpp/Phyl/Model/Codon/CodonDistanceSubstitutionModel.h b/src/Bpp/Phyl/Model/Codon/CodonDistanceSubstitutionModel.h
index be939ca..014d20b 100644
--- a/src/Bpp/Phyl/Model/Codon/CodonDistanceSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/Codon/CodonDistanceSubstitutionModel.h
@@ -77,20 +77,21 @@ namespace bpp
      * @brief Build a new CodonDistanceSubstitutionModel object from
      * a pointer to NucleotideSubstitutionModel.
      *
-     * @param palph pointer to a GeneticCode
+     * @param gCode pointer to a GeneticCode
      * @param pmod  pointer to the NucleotideSubstitutionModel to use in the three positions.
      * The instance will then own this substitution model.
      * @param pdist optional pointer to a distance between amino-acids
      */
-    CodonDistanceSubstitutionModel(const GeneticCode* palph,
-                                   NucleotideSubstitutionModel* pmod,
-                                   const AlphabetIndex2* pdist);
+    CodonDistanceSubstitutionModel(
+        const GeneticCode* gCode,
+        NucleotideSubstitutionModel* pmod,
+        const AlphabetIndex2* pdist);
 
     /**
      * @brief Build a new CodonDistanceSubstitutionModel object
      * from three pointers to NucleotideSubstitutionModels.
      *
-     * @param palph pointer to a GeneticCode
+     * @param gCode pointer to a GeneticCode
      * @param pmod1, pmod2, pmod3 pointers to the
      *   NucleotideSubstitutionModels to use in the three positions.
      *   Either all the models are different objects to avoid parameters
@@ -98,32 +99,14 @@ namespace bpp
      *   The used models are owned by the instance.
      * @param pdist optional pointer to the AlphabetIndex2 amino-acids distance object.
      */
-  
-    CodonDistanceSubstitutionModel(const GeneticCode* palph,
-                                   NucleotideSubstitutionModel* pmod1,
-                                   NucleotideSubstitutionModel* pmod2,
-                                   NucleotideSubstitutionModel* pmod3,
-                                   const AlphabetIndex2* pdist);
-
-    CodonDistanceSubstitutionModel(const CodonDistanceSubstitutionModel& model) :
-      AbstractParameterAliasable(model),
-      AbstractSubstitutionModel(model),
-      AbstractWordSubstitutionModel(model),
-      AbstractCodonSubstitutionModel(model),
-      AbstractCodonDistanceSubstitutionModel(model)
-    {}
-
-    CodonDistanceSubstitutionModel & operator=(const CodonDistanceSubstitutionModel& model)
-    {
-      AbstractParameterAliasable::operator=(model);
-      AbstractSubstitutionModel::operator=(model);
-      AbstractWordSubstitutionModel::operator=(model);
-      AbstractCodonSubstitutionModel::operator=(model);
-      AbstractCodonDistanceSubstitutionModel::operator=(model);
-      return *this;
-    }
+    CodonDistanceSubstitutionModel(
+        const GeneticCode* gCode,
+        NucleotideSubstitutionModel* pmod1,
+        NucleotideSubstitutionModel* pmod2,
+        NucleotideSubstitutionModel* pmod3,
+        const AlphabetIndex2* pdist);
 
-    ~CodonDistanceSubstitutionModel() {}
+    virtual ~CodonDistanceSubstitutionModel() {}
 
     CodonDistanceSubstitutionModel* clone() const
     {
@@ -139,5 +122,5 @@ namespace bpp
   };
 } // end of namespace bpp.
 
-#endif
+#endif //_CODONDISTANCESUBSTITUTIONMODEL_H_
 
diff --git a/src/Bpp/Phyl/Model/Codon/CodonRateFrequenciesSubstitutionModel.cpp b/src/Bpp/Phyl/Model/Codon/CodonRateFrequenciesSubstitutionModel.cpp
index 907598a..b26bf4b 100644
--- a/src/Bpp/Phyl/Model/Codon/CodonRateFrequenciesSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/Codon/CodonRateFrequenciesSubstitutionModel.cpp
@@ -44,27 +44,25 @@ using namespace std;
 
 /******************************************************************************/
 
-CodonRateFrequenciesSubstitutionModel::CodonRateFrequenciesSubstitutionModel(const CodonAlphabet* palph,
-                                                                             NucleotideSubstitutionModel* pmod,
-                                                                             FrequenciesSet* pfreq) :
+CodonRateFrequenciesSubstitutionModel::CodonRateFrequenciesSubstitutionModel(
+    const GeneticCode* gCode,
+    NucleotideSubstitutionModel* pmod,
+    FrequenciesSet* pfreq) :
   AbstractParameterAliasable("CodonRateFreq."),
-  AbstractSubstitutionModel(palph, "CodonRateFreq."),
-  AbstractWordSubstitutionModel(palph, "CodonRateFreq."),
-  AbstractCodonSubstitutionModel(palph, pmod, "CodonRateFreq.", true),
+  AbstractCodonSubstitutionModel(gCode, pmod, "CodonRateFreq.", true),
   AbstractCodonFrequenciesSubstitutionModel(pfreq, "CodonRateFreq.")
 {
   updateMatrices();
 }
 
-CodonRateFrequenciesSubstitutionModel::CodonRateFrequenciesSubstitutionModel(const CodonAlphabet* palph,
-                                                                             NucleotideSubstitutionModel* pmod1,
-                                                                             NucleotideSubstitutionModel* pmod2,
-                                                                             NucleotideSubstitutionModel* pmod3,
-                                                                             FrequenciesSet* pfreq) :
+CodonRateFrequenciesSubstitutionModel::CodonRateFrequenciesSubstitutionModel(
+    const GeneticCode* gCode,
+    NucleotideSubstitutionModel* pmod1,
+    NucleotideSubstitutionModel* pmod2,
+    NucleotideSubstitutionModel* pmod3,
+    FrequenciesSet* pfreq) :
   AbstractParameterAliasable("CodonRateFreq."),
-  AbstractSubstitutionModel(palph, "CodonRateFreq."),
-  AbstractWordSubstitutionModel(palph, "CodonRateFreq."),
-  AbstractCodonSubstitutionModel(palph, pmod1, pmod2, pmod3, "CodonRateFreq.", true),
+  AbstractCodonSubstitutionModel(gCode, pmod1, pmod2, pmod3, "CodonRateFreq.", true),
   AbstractCodonFrequenciesSubstitutionModel(pfreq, "CodonRateFreq.")
 {
   updateMatrices();
@@ -72,7 +70,7 @@ CodonRateFrequenciesSubstitutionModel::CodonRateFrequenciesSubstitutionModel(con
 
 std::string CodonRateFrequenciesSubstitutionModel::getName() const
 {
-  return ("CodonRateFreq");
+  return "CodonRateFreq";
 }
 
 void CodonRateFrequenciesSubstitutionModel::fireParameterChanged(const ParameterList& parameters)
diff --git a/src/Bpp/Phyl/Model/Codon/CodonRateFrequenciesSubstitutionModel.h b/src/Bpp/Phyl/Model/Codon/CodonRateFrequenciesSubstitutionModel.h
index 88617c3..9e0612e 100644
--- a/src/Bpp/Phyl/Model/Codon/CodonRateFrequenciesSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/Codon/CodonRateFrequenciesSubstitutionModel.h
@@ -61,47 +61,48 @@ namespace bpp
  * AbstractCodonFrequenciesSubstitutionModel class.
  *
  */
-
 class CodonRateFrequenciesSubstitutionModel :
     public AbstractCodonSubstitutionModel,
     public AbstractCodonFrequenciesSubstitutionModel
 {
 public:
+  
   /**
-   *@brief Build a new CodonRateSubstitutionModel object from
-   *a pointer to NucleotideSubstitutionModels.
+   * @brief Build a new CodonRateSubstitutionModel object from
+   *  a pointer to NucleotideSubstitutionModels.
    * @author Laurent Guéguen
    *
-   *@param palph pointer to a CodonAlphabet
-   *@param pmod pointer to the NucleotideSubstitutionModel to use in the
+   * @param gCode pointer to a genetic code, which will be owned by this instance.
+   * @param pmod pointer to the NucleotideSubstitutionModel to use in the
    *       three positions. It is owned by the instabce.
-   *@param pfreq pointer to the FrequenciesSet* equilibrium frequencies
+   * @param pfreq pointer to the FrequenciesSet* equilibrium frequencies
    */
-
-  CodonRateFrequenciesSubstitutionModel(const CodonAlphabet* palph,
-                                        NucleotideSubstitutionModel* pmod,
-                                        FrequenciesSet* pfreq);
+  CodonRateFrequenciesSubstitutionModel(
+      const GeneticCode* gCode,
+      NucleotideSubstitutionModel* pmod,
+      FrequenciesSet* pfreq);
 
   /**
-   *@brief Build a new CodonRateSubstitutionModel object
-   *from three pointers to NucleotideSubstitutionModels.
+   * @brief Build a new CodonRateSubstitutionModel object
+   *  from three pointers to NucleotideSubstitutionModels.
    *
-   *@param palph pointer to a CodonAlphabet
-   *@param pmod1, pmod2, pmod3 pointers to the
+   * @param gCode pointer to a genetic code, which will be owned by this instance.
+   * @param pmod1, pmod2, pmod3 pointers to the
    *   NucleotideSubstitutionModel to use in the three positions.
    *   All the models must be different objects to avoid parameters
    *   redondancy, otherwise only the first model is used. The used models
    *   are owned by the instance.
-   *@param pfreq pointer to the FrequenciesSet* equilibrium frequencies
+   * @param pfreq pointer to the FrequenciesSet* equilibrium frequencies
    */
 
-  CodonRateFrequenciesSubstitutionModel(const CodonAlphabet* palph,
-                                        NucleotideSubstitutionModel* pmod1,
-                                        NucleotideSubstitutionModel* pmod2,
-                                        NucleotideSubstitutionModel* pmod3,
-                                        FrequenciesSet* pfreq);
+  CodonRateFrequenciesSubstitutionModel(
+      const GeneticCode* gCode,
+      NucleotideSubstitutionModel* pmod1,
+      NucleotideSubstitutionModel* pmod2,
+      NucleotideSubstitutionModel* pmod3,
+      FrequenciesSet* pfreq);
 
-  ~CodonRateFrequenciesSubstitutionModel(){}
+  virtual ~CodonRateFrequenciesSubstitutionModel(){}
 
 #ifndef NO_VIRTUAL_COV
   CodonRateFrequenciesSubstitutionModel*
@@ -121,6 +122,7 @@ public:
 
   void setFreq(std::map<int,double>& frequencies);
 };
+
 } // end of namespace bpp.
 
 #endif
diff --git a/src/Bpp/Phyl/Model/Codon/CodonRateSubstitutionModel.cpp b/src/Bpp/Phyl/Model/Codon/CodonRateSubstitutionModel.cpp
index fd8b566..13dba94 100644
--- a/src/Bpp/Phyl/Model/Codon/CodonRateSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/Codon/CodonRateSubstitutionModel.cpp
@@ -45,31 +45,29 @@ using namespace std;
 
 /******************************************************************************/
 
-CodonRateSubstitutionModel::CodonRateSubstitutionModel(const CodonAlphabet* palph,
-                                                       NucleotideSubstitutionModel* pmod) :
+CodonRateSubstitutionModel::CodonRateSubstitutionModel(
+    const GeneticCode* gCode,
+    NucleotideSubstitutionModel* pmod) :
   AbstractParameterAliasable("CodonRate."),
-  AbstractSubstitutionModel(palph, "CodonRate."),
-  AbstractWordSubstitutionModel(palph, "CodonRate."),
-  AbstractCodonSubstitutionModel(palph, pmod, "CodonRate.", true)
+  AbstractCodonSubstitutionModel(gCode, pmod, "CodonRate.", true)
 {
   updateMatrices();
 }
 
-CodonRateSubstitutionModel::CodonRateSubstitutionModel(const CodonAlphabet* palph,
-                                                       NucleotideSubstitutionModel* pmod1,
-                                                       NucleotideSubstitutionModel* pmod2,
-                                                       NucleotideSubstitutionModel* pmod3) :
+CodonRateSubstitutionModel::CodonRateSubstitutionModel(
+    const GeneticCode* gCode,
+    NucleotideSubstitutionModel* pmod1,
+    NucleotideSubstitutionModel* pmod2,
+    NucleotideSubstitutionModel* pmod3) :
   AbstractParameterAliasable("CodonRate."),
-  AbstractSubstitutionModel(palph, "CodonRate."),
-  AbstractWordSubstitutionModel(palph, "CodonRate."),
-  AbstractCodonSubstitutionModel(palph, pmod1, pmod2, pmod3, "CodonRate.", true)
+  AbstractCodonSubstitutionModel(gCode, pmod1, pmod2, pmod3, "CodonRate.", true)
 {
   updateMatrices();
 }
 
 std::string CodonRateSubstitutionModel::getName() const
 {
-  return ("CodonRate");
+  return "CodonRate";
 }
 
 void CodonRateSubstitutionModel::fireParameterChanged(const ParameterList& parameters)
diff --git a/src/Bpp/Phyl/Model/Codon/CodonRateSubstitutionModel.h b/src/Bpp/Phyl/Model/Codon/CodonRateSubstitutionModel.h
index 6f84d06..40d85a7 100644
--- a/src/Bpp/Phyl/Model/Codon/CodonRateSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/Codon/CodonRateSubstitutionModel.h
@@ -52,44 +52,42 @@ namespace bpp
  * @author Laurent Guéguen
  *
  * See description in AbstractCodonRateSubstitutionModel class.
- *
  */
-
 class CodonRateSubstitutionModel :
   public AbstractCodonSubstitutionModel
 {
 public:
   /**
-   *@brief Build a new CodonRateSubstitutionModel object from
-   *a pointer to NucleotideSubstitutionModels.
+   * @brief Build a new CodonRateSubstitutionModel object from
+   * a pointer to NucleotideSubstitutionModels.
    * @author Laurent Guéguen
    *
-   *@param palph pointer to a CodonAlphabet
-   *@param pmod pointer to the NucleotideSubstitutionModel to use in the
+   * @param gCode pointer to a genetic code, which will be owned by this instance.
+   * @param pmod pointer to the NucleotideSubstitutionModel to use in the
    *       three positions. It is owned by the instabce.
    */
-
-  CodonRateSubstitutionModel(const CodonAlphabet* palph,
-                             NucleotideSubstitutionModel* pmod);
+  CodonRateSubstitutionModel(
+      const GeneticCode* gCode,
+      NucleotideSubstitutionModel* pmod);
 
   /**
-   *@brief Build a new CodonRateSubstitutionModel object
-   *from three pointers to NucleotideSubstitutionModels.
+   * @brief Build a new CodonRateSubstitutionModel object
+   * from three pointers to NucleotideSubstitutionModels.
    *
-   *@param palph pointer to a CodonAlphabet
-   *@param pmod1, pmod2, pmod3 pointers to the
+   * @param gCode pointer to a genetic code, which will be owned by this instance.
+   * @param pmod1, pmod2, pmod3 pointers to the
    *   NucleotideSubstitutionModel to use in the three positions.
    *   All the models must be different objects to avoid parameters
    *   redondancy, otherwise only the first model is used. The used models
    *   are owned by the instance.
    */
+  CodonRateSubstitutionModel(
+      const GeneticCode* gCode,
+      NucleotideSubstitutionModel* pmod1,
+      NucleotideSubstitutionModel* pmod2,
+      NucleotideSubstitutionModel* pmod3);
 
-  CodonRateSubstitutionModel(const CodonAlphabet* palph,
-                             NucleotideSubstitutionModel* pmod1,
-                             NucleotideSubstitutionModel* pmod2,
-                             NucleotideSubstitutionModel* pmod3);
-
-  ~CodonRateSubstitutionModel(){}
+  virtual ~CodonRateSubstitutionModel() {}
 
 #ifndef NO_VIRTUAL_COV
   CodonRateSubstitutionModel*
@@ -105,6 +103,7 @@ public:
 
   double getCodonsMulRate(size_t i, size_t j) const;
 };
+
 } // end of namespace bpp.
 
 #endif
diff --git a/src/Bpp/Phyl/Model/Codon/CodonSubstitutionModel.h b/src/Bpp/Phyl/Model/Codon/CodonSubstitutionModel.h
index de1fbaa..b72deb4 100644
--- a/src/Bpp/Phyl/Model/Codon/CodonSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/Codon/CodonSubstitutionModel.h
@@ -42,6 +42,9 @@
 
 #include <Bpp/Numeric/ParameterAliasable.h>
 
+//From bpp-seq:
+#include <Bpp/Seq/GeneticCode/GeneticCode.h>
+
 #include "../WordSubstitutionModel.h"
 
 namespace bpp
@@ -53,7 +56,6 @@ namespace bpp
    * This class aims at defining methods needed for inheriting codon.
    *
    */
-  
   class CodonSubstitutionModel:
     public virtual SubstitutionModel
   {
@@ -67,14 +69,14 @@ namespace bpp
 
   public:
 
+    virtual const GeneticCode* getGeneticCode() const = 0;
+
     /**
      * @brief Returns the multiplicative rate specific to two codons
      * specified by their number. The respective generator rate is this
      * rate multiplied by the rate defined by the model defined on
      * nucleotides.
-     *
-     **/
-  
+     */
     virtual double getCodonsMulRate(size_t, size_t) const = 0;
   };
   
diff --git a/src/Bpp/Phyl/Model/Codon/TripletSubstitutionModel.cpp b/src/Bpp/Phyl/Model/Codon/TripletSubstitutionModel.cpp
index e9c1a81..9852447 100644
--- a/src/Bpp/Phyl/Model/Codon/TripletSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/Codon/TripletSubstitutionModel.cpp
@@ -59,8 +59,7 @@ TripletSubstitutionModel::TripletSubstitutionModel(
     const CodonAlphabet* palph,
     NucleotideSubstitutionModel* pmod) :
   AbstractParameterAliasable("Triplet."),
-  AbstractSubstitutionModel(palph, "Triplet."),
-  WordSubstitutionModel(palph, "Triplet.")
+  WordSubstitutionModel(palph, new CanonicalStateMap(palph, false), "Triplet.")
 {
   unsigned int i;
   addParameters_(pmod->getParameters());
@@ -88,8 +87,7 @@ TripletSubstitutionModel::TripletSubstitutionModel(
     NucleotideSubstitutionModel* pmod2,
     NucleotideSubstitutionModel* pmod3) :
   AbstractParameterAliasable("Triplet."),
-  AbstractSubstitutionModel(palph, "Triplet."),
-  WordSubstitutionModel(palph, "Triplet.")
+  WordSubstitutionModel(palph, new CanonicalStateMap(palph, false), "Triplet.")
 {
   string st = "Triplet.";
 
diff --git a/src/Bpp/Phyl/Model/Codon/YN98.cpp b/src/Bpp/Phyl/Model/Codon/YN98.cpp
index 15aca0a..dce5ea5 100644
--- a/src/Bpp/Phyl/Model/Codon/YN98.cpp
+++ b/src/Bpp/Phyl/Model/Codon/YN98.cpp
@@ -38,6 +38,7 @@
 
 #include "YN98.h"
 #include "../Nucleotide/K80.h"
+
 #include "../FrequenciesSet/CodonFrequenciesSet.h"
 #include <Bpp/Numeric/NumConstants.h>
 
@@ -83,4 +84,3 @@ YN98& YN98::operator=(const YN98& yn98)
   return *this;
 }
 
-YN98::~YN98() {}
diff --git a/src/Bpp/Phyl/Model/Codon/YN98.h b/src/Bpp/Phyl/Model/Codon/YN98.h
index c01dd80..4fdc6fb 100644
--- a/src/Bpp/Phyl/Model/Codon/YN98.h
+++ b/src/Bpp/Phyl/Model/Codon/YN98.h
@@ -87,6 +87,7 @@ namespace bpp
  */
 class YN98 :
     public AbstractBiblioSubstitutionModel,
+    public virtual CodonSubstitutionModel,
     public virtual ReversibleSubstitutionModel
 {
 private:
@@ -99,7 +100,7 @@ public:
 
   YN98& operator=(const YN98&);
 
-  ~YN98();
+  virtual ~YN98() {}
 
   YN98* clone() const { return new YN98(*this); }
 
@@ -108,6 +109,10 @@ public:
 
   const SubstitutionModel& getModel() const { return *pmodel_.get(); }
 
+  const GeneticCode* getGeneticCode() const { return pmodel_->getGeneticCode(); }
+  
+  double getCodonsMulRate(size_t i, size_t j) const { return pmodel_->getCodonsMulRate(i, j); }
+
 private:
   SubstitutionModel& getModel() { return *pmodel_.get(); }
 
diff --git a/src/Bpp/Phyl/Model/Codon/YNGKP_M1.cpp b/src/Bpp/Phyl/Model/Codon/YNGKP_M1.cpp
index fdcb4e4..045bc8c 100644
--- a/src/Bpp/Phyl/Model/Codon/YNGKP_M1.cpp
+++ b/src/Bpp/Phyl/Model/Codon/YNGKP_M1.cpp
@@ -51,8 +51,8 @@ using namespace std;
 YNGKP_M1::YNGKP_M1(const GeneticCode* gc, FrequenciesSet* codonFreqs) :
   AbstractBiblioMixedSubstitutionModel("YNGKP_M1."),
   pmixmodel_(0),
-  synfrom_(-1),
-  synto_(-1)
+  synfrom_(),
+  synto_()
 {
   // build the submodel
 
@@ -65,8 +65,10 @@ YNGKP_M1::YNGKP_M1(const GeneticCode* gc, FrequenciesSet* codonFreqs) :
   map<string, DiscreteDistribution*> mpdd;
   mpdd["omega"] = psdd;
 
-  pmixmodel_.reset(new MixtureOfASubstitutionModel(gc->getSourceAlphabet(), new YN98(gc, codonFreqs), mpdd));
+  YN98* yn98 = new YN98(gc, codonFreqs);
+  pmixmodel_.reset(new MixtureOfASubstitutionModel(gc->getSourceAlphabet(), yn98, mpdd));
   delete psdd;
+  vector<int> supportedChars = yn98->getAlphabetStates();
 
   // map the parameters
 
@@ -99,20 +101,20 @@ YNGKP_M1::YNGKP_M1(const GeneticCode* gc, FrequenciesSet* codonFreqs) :
   addParameter_(new Parameter("YNGKP_M1.omega", 0.5, new IntervalConstraint(NumConstants::MILLI(), 1, true, false, NumConstants::MILLI()), true));
 
   // look for synonymous codons
-  for (synfrom_ = 1; synfrom_ < static_cast<int>(gc->getSourceAlphabet()->getSize()); synfrom_++)
+  for (synfrom_ = 1; synfrom_ < supportedChars.size(); ++synfrom_)
   {
-    for (synto_ = 0; synto_ < synfrom_; synto_++)
+    for (synto_ = 0; synto_ < synfrom_; ++synto_)
     {
-      if ((gc->areSynonymous(synfrom_, synto_))
-          && (pmixmodel_->getNModel(0)->Qij(synfrom_, synto_) != 0)
-          && (pmixmodel_->getNModel(1)->Qij(synfrom_, synto_) != 0))
+      if (gc->areSynonymous(supportedChars[synfrom_], supportedChars[synto_])
+        && (pmixmodel_->getNModel(0)->Qij(synfrom_, synto_) != 0)
+        && (pmixmodel_->getNModel(1)->Qij(synfrom_, synto_) != 0))
         break;
     }
     if (synto_ < synfrom_)
       break;
   }
 
-  if (synto_ == static_cast<int>(gc->getSourceAlphabet()->getSize()))
+  if (synto_ == supportedChars.size())
     throw Exception("Impossible to find synonymous codons");
 
   // update matrice
diff --git a/src/Bpp/Phyl/Model/Codon/YNGKP_M1.h b/src/Bpp/Phyl/Model/Codon/YNGKP_M1.h
index 707edfd..df27549 100644
--- a/src/Bpp/Phyl/Model/Codon/YNGKP_M1.h
+++ b/src/Bpp/Phyl/Model/Codon/YNGKP_M1.h
@@ -84,13 +84,12 @@ private:
   std::auto_ptr<MixtureOfASubstitutionModel> pmixmodel_;
 
 
-  /*
-   *@brief indexes of 2 codons between which the substitution is
+  /**
+   * @brief indexes of 2 codons states between which the substitution is
    * synonymous, to set a basis to the homogeneization of the rates.
    *
    */
-
-  int synfrom_, synto_;
+  size_t synfrom_, synto_;
   
 public:
   YNGKP_M1(const GeneticCode* gc, FrequenciesSet* codonFreqs);
@@ -117,6 +116,8 @@ private:
   SubstitutionModel& getModel() { return *pmixmodel_.get(); }
   
   MixedSubstitutionModel& getMixedModel() { return *pmixmodel_.get(); }
+
+  const FrequenciesSet* getFrequenciesSet() const {return pmixmodel_->getNModel(1)->getFrequenciesSet();}
 };
 
 } //end of namespace bpp.
diff --git a/src/Bpp/Phyl/Model/Codon/YNGKP_M2.cpp b/src/Bpp/Phyl/Model/Codon/YNGKP_M2.cpp
index 319f146..f1fea59 100644
--- a/src/Bpp/Phyl/Model/Codon/YNGKP_M2.cpp
+++ b/src/Bpp/Phyl/Model/Codon/YNGKP_M2.cpp
@@ -51,8 +51,8 @@ using namespace std;
 YNGKP_M2::YNGKP_M2(const GeneticCode* gc, FrequenciesSet* codonFreqs) :
   AbstractBiblioMixedSubstitutionModel("YNGKP_M2."),
   pmixmodel_(0),
-  synfrom_(-1),
-  synto_(-1)
+  synfrom_(),
+  synto_()
 {
   // build the submodel
 
@@ -65,13 +65,15 @@ YNGKP_M2::YNGKP_M2(const GeneticCode* gc, FrequenciesSet* codonFreqs) :
   map<string, DiscreteDistribution*> mpdd;
   mpdd["omega"] = psdd;
 
-  pmixmodel_.reset(new MixtureOfASubstitutionModel(gc->getSourceAlphabet(), new YN98(gc, codonFreqs), mpdd));
+  YN98* yn98 = new YN98(gc, codonFreqs);
+  pmixmodel_.reset(new MixtureOfASubstitutionModel(gc->getSourceAlphabet(), yn98, mpdd));
   delete psdd;
+  vector<int> supportedChars = yn98->getAlphabetStates();
 
   // mapping the parameters
 
   ParameterList pl = pmixmodel_->getParameters();
-  for (unsigned int i = 0; i < pl.size(); i++)
+  for (size_t i = 0; i < pl.size(); i++)
   {
     lParPmodel_.addParameter(Parameter(pl[i]));
   }
@@ -105,11 +107,11 @@ YNGKP_M2::YNGKP_M2(const GeneticCode* gc, FrequenciesSet* codonFreqs) :
   addParameter_(new Parameter("YNGKP_M2.omega2", 2, new IntervalConstraint(1, 999, false, false, NumConstants::MILLI()), true));
 
   // look for synonymous codons
-  for (synfrom_ = 1; synfrom_ < (int)gc->getSourceAlphabet()->getSize(); synfrom_++)
+  for (synfrom_ = 1; synfrom_ < supportedChars.size(); ++synfrom_)
   {
-    for (synto_ = 0; synto_ < synfrom_; synto_++)
+    for (synto_ = 0; synto_ < synfrom_; ++synto_)
     {
-      if ((gc->areSynonymous(synfrom_, synto_))
+      if (gc->areSynonymous(supportedChars[synfrom_], supportedChars[synto_])
           && (pmixmodel_->getNModel(0)->Qij(synfrom_, synto_) != 0)
           && (pmixmodel_->getNModel(1)->Qij(synfrom_, synto_) != 0))
         break;
@@ -118,7 +120,7 @@ YNGKP_M2::YNGKP_M2(const GeneticCode* gc, FrequenciesSet* codonFreqs) :
       break;
   }
 
-  if (synto_ == (int)gc->getSourceAlphabet()->getSize())
+  if (synto_ == supportedChars.size())
     throw Exception("Impossible to find synonymous codons");
 
   // update Matrices
diff --git a/src/Bpp/Phyl/Model/Codon/YNGKP_M2.h b/src/Bpp/Phyl/Model/Codon/YNGKP_M2.h
index 0f945ed..359e1f0 100644
--- a/src/Bpp/Phyl/Model/Codon/YNGKP_M2.h
+++ b/src/Bpp/Phyl/Model/Codon/YNGKP_M2.h
@@ -79,18 +79,16 @@ class YNGKP_M2:
 private:
   std::auto_ptr<MixtureOfASubstitutionModel> pmixmodel_;
 
-  /*
-   *@brief indexes of 2 codons between which the substitution is
+  /**
+   * @brief indexes of 2 codons between which the substitution is
    * synonymous, to set a basis to the homogeneization of the rates.
-   *
    */
-
-  int synfrom_, synto_;
+  size_t synfrom_, synto_;
   
 public:
   YNGKP_M2(const GeneticCode* gc, FrequenciesSet* codonFreqs);
 
-  ~YNGKP_M2();
+  virtual ~YNGKP_M2();
   
   YNGKP_M2* clone() const { return new YNGKP_M2(*this); }
 
@@ -113,6 +111,7 @@ private:
 
   MixedSubstitutionModel& getMixedModel() { return *pmixmodel_.get(); }
 
+  const FrequenciesSet* getFrequenciesSet() const {return pmixmodel_->getNModel(1)->getFrequenciesSet();}
 };
 
 } //end of namespace bpp.
diff --git a/src/Bpp/Phyl/Model/Codon/YNGKP_M3.cpp b/src/Bpp/Phyl/Model/Codon/YNGKP_M3.cpp
index 3b53fb3..9d61027 100644
--- a/src/Bpp/Phyl/Model/Codon/YNGKP_M3.cpp
+++ b/src/Bpp/Phyl/Model/Codon/YNGKP_M3.cpp
@@ -51,8 +51,8 @@ using namespace std;
 YNGKP_M3::YNGKP_M3(const GeneticCode* gc, FrequenciesSet* codonFreqs, unsigned int nbOmega) :
   AbstractBiblioMixedSubstitutionModel("YNGKP_M3."),
   pmixmodel_(0),
-  synfrom_(-1),
-  synto_(-1)
+  synfrom_(),
+  synto_()
 {
   if (nbOmega < 1)
     throw Exception("At least one omega is necessary in the YNGKP_M3 model");
@@ -76,33 +76,35 @@ YNGKP_M3::YNGKP_M3(const GeneticCode* gc, FrequenciesSet* codonFreqs, unsigned i
   map<string, DiscreteDistribution*> mpdd;
   mpdd["omega"] = psdd;
 
-  pmixmodel_.reset(new MixtureOfASubstitutionModel(gc->getSourceAlphabet(), new YN98(gc, codonFreqs), mpdd));
+  YN98* yn98 = new YN98(gc, codonFreqs);
+  pmixmodel_.reset(new MixtureOfASubstitutionModel(gc->getSourceAlphabet(), yn98, mpdd));
   delete psdd;
+  vector<int> supportedChars = yn98->getAlphabetStates();
 
   // mapping the parameters
 
   ParameterList pl = pmixmodel_->getParameters();
-  for (size_t i = 0; i < pl.size(); i++)
+  for (size_t i = 0; i < pl.size(); ++i)
   {
     lParPmodel_.addParameter(Parameter(pl[i]));
   }
 
   vector<std::string> v = dynamic_cast<YN98*>(pmixmodel_->getNModel(0))->getFrequenciesSet()->getParameters().getParameterNames();
-  for (size_t i = 0; i < v.size(); i++)
+  for (size_t i = 0; i < v.size(); ++i)
   {
     mapParNamesFromPmodel_[v[i]] = getParameterNameWithoutNamespace("YNGKP_M3." + v[i].substr(5));
   }
 
   mapParNamesFromPmodel_["YN98.kappa"] = "kappa";
 
-  for (unsigned int i = 1; i < nbOmega; i++)
+  for (size_t i = 1; i < nbOmega; ++i)
   {
     mapParNamesFromPmodel_["YN98.omega_Simple.theta" + TextTools::toString(i)] = "theta" + TextTools::toString(i);
   }
 
 
   mapParNamesFromPmodel_["YN98.omega_Simple.V1"] = "omega0";
-  for (unsigned int i = 1; i < nbOmega; i++)
+  for (size_t i = 1; i < nbOmega; ++i)
   {
     mapParNamesFromPmodel_["YN98.omega_Simple.V" + TextTools::toString(i + 1)] = "delta" + TextTools::toString(i);
   }
@@ -118,17 +120,17 @@ YNGKP_M3::YNGKP_M3(const GeneticCode* gc, FrequenciesSet* codonFreqs, unsigned i
                               pmixmodel_->getParameter(st).hasConstraint() ? pmixmodel_->getParameter(st).getConstraint()->clone() : 0, true));
   }
 
-  for (unsigned int i = 1; i < nbOmega; i++)
+  for (size_t i = 1; i < nbOmega; ++i)
   {
     addParameter_(new Parameter("YNGKP_M3.delta" + TextTools::toString(i), 0.5, new IntervalConstraint(NumConstants::MILLI(), 999, true, true, NumConstants::MILLI()), true));
   }
 
   // look for synonymous codons
-  for (synfrom_ = 1; synfrom_ < (int)gc->getSourceAlphabet()->getSize(); synfrom_++)
+  for (synfrom_ = 1; synfrom_ < supportedChars.size(); synfrom_++)
   {
     for (synto_ = 0; synto_ < synfrom_; synto_++)
     {
-      if ((gc->areSynonymous(synfrom_, synto_))
+      if (gc->areSynonymous(supportedChars[synfrom_], supportedChars[synto_])
           && (pmixmodel_->getNModel(0)->Qij(synfrom_, synto_) != 0)
           && (pmixmodel_->getNModel(1)->Qij(synfrom_, synto_) != 0))
         break;
@@ -137,7 +139,7 @@ YNGKP_M3::YNGKP_M3(const GeneticCode* gc, FrequenciesSet* codonFreqs, unsigned i
       break;
   }
 
-  if (synto_ == (int)gc->getSourceAlphabet()->getSize())
+  if (synto_ == supportedChars.size())
     throw Exception("Impossible to find synonymous codons");
 
   // update Matrices
@@ -171,7 +173,7 @@ void YNGKP_M3::updateMatrices()
     {
       if (lParPmodel_[i].getName()[18] == 'V')
       {
-        unsigned int ind = TextTools::toInt(lParPmodel_[i].getName().substr(19));
+        size_t ind = TextTools::to<size_t>(lParPmodel_[i].getName().substr(19));
         double x = getParameterValue("omega0");
         for (unsigned j = 1; j < ind; j++)
         {
diff --git a/src/Bpp/Phyl/Model/Codon/YNGKP_M3.h b/src/Bpp/Phyl/Model/Codon/YNGKP_M3.h
index 94f82cf..caacfba 100644
--- a/src/Bpp/Phyl/Model/Codon/YNGKP_M3.h
+++ b/src/Bpp/Phyl/Model/Codon/YNGKP_M3.h
@@ -79,13 +79,12 @@ class YNGKP_M3:
 private:
   std::auto_ptr<MixtureOfASubstitutionModel> pmixmodel_;
 
-  /*
-   *@brief indexes of 2 codons between which the substitution is
+  /**
+   * @brief indexes of 2 codons between which the substitution is
    * synonymous, to set a basis to the homogeneization of the rates.
    *
    */
-
-  int synfrom_, synto_;
+  size_t synfrom_, synto_;
   
 public:
   YNGKP_M3(const GeneticCode* gc, FrequenciesSet* codonFreqs, unsigned int nclass = 3);
@@ -112,6 +111,9 @@ private:
   SubstitutionModel& getModel() { return *pmixmodel_.get(); }
   
   MixedSubstitutionModel& getMixedModel() { return *pmixmodel_.get(); }
+  
+  const FrequenciesSet* getFrequenciesSet() const {return pmixmodel_->getNModel(1)->getFrequenciesSet();}
+
 };
 
 } //end of namespace bpp.
diff --git a/src/Bpp/Phyl/Model/Codon/YNGKP_M7.cpp b/src/Bpp/Phyl/Model/Codon/YNGKP_M7.cpp
index 2a2c9e5..7658f2b 100644
--- a/src/Bpp/Phyl/Model/Codon/YNGKP_M7.cpp
+++ b/src/Bpp/Phyl/Model/Codon/YNGKP_M7.cpp
@@ -53,8 +53,8 @@ using namespace std;
 YNGKP_M7::YNGKP_M7(const GeneticCode* gc, FrequenciesSet* codonFreqs, unsigned int nclass) :
   AbstractBiblioMixedSubstitutionModel("YNGKP_M7."),
   pmixmodel_(0),
-  synfrom_(-1),
-  synto_(-1)
+  synfrom_(),
+  synto_()
 {
   if (nclass <= 0)
     throw Exception("Bad number of classes for model YNGKP_M7: " + TextTools::toString(nclass));
@@ -66,8 +66,10 @@ YNGKP_M7::YNGKP_M7(const GeneticCode* gc, FrequenciesSet* codonFreqs, unsigned i
   map<string, DiscreteDistribution*> mpdd;
   mpdd["omega"] = pbdd;
 
-  pmixmodel_.reset(new MixtureOfASubstitutionModel(gc->getSourceAlphabet(), new YN98(gc, codonFreqs), mpdd));
+  YN98* yn98 = new YN98(gc, codonFreqs);
+  pmixmodel_.reset(new MixtureOfASubstitutionModel(gc->getSourceAlphabet(), yn98, mpdd));
   delete pbdd;
+  vector<int> supportedChars = yn98->getAlphabetStates();
 
   // mapping the parameters
 
@@ -99,11 +101,11 @@ YNGKP_M7::YNGKP_M7(const GeneticCode* gc, FrequenciesSet* codonFreqs, unsigned i
   }
 
   // look for synonymous codons
-  for (synfrom_ = 1; synfrom_ < (int)gc->getSourceAlphabet()->getSize(); synfrom_++)
+  for (synfrom_ = 1; synfrom_ < supportedChars.size(); ++synfrom_)
   {
-    for (synto_ = 0; synto_ < synfrom_; synto_++)
+    for (synto_ = 0; synto_ < synfrom_; ++synto_)
     {
-      if ((gc->areSynonymous(synfrom_, synto_))
+      if (gc->areSynonymous(supportedChars[synfrom_], supportedChars[synto_])
           && (pmixmodel_->getNModel(0)->Qij(synfrom_, synto_) != 0)
           && (pmixmodel_->getNModel(1)->Qij(synfrom_, synto_) != 0))
         break;
@@ -112,7 +114,7 @@ YNGKP_M7::YNGKP_M7(const GeneticCode* gc, FrequenciesSet* codonFreqs, unsigned i
       break;
   }
 
-  if (synto_ == (int)gc->getSourceAlphabet()->getSize())
+  if (synto_ == supportedChars.size())
     throw Exception("Impossible to find synonymous codons");
 
   // update Matrices
diff --git a/src/Bpp/Phyl/Model/Codon/YNGKP_M7.h b/src/Bpp/Phyl/Model/Codon/YNGKP_M7.h
index 03e61dd..715dd8f 100644
--- a/src/Bpp/Phyl/Model/Codon/YNGKP_M7.h
+++ b/src/Bpp/Phyl/Model/Codon/YNGKP_M7.h
@@ -74,13 +74,12 @@ class YNGKP_M7:
 private:
   std::auto_ptr<MixtureOfASubstitutionModel> pmixmodel_;
 
-  /*
-   *@brief indexes of 2 codons between which the substitution is
+  /**
+   * @brief indexes of 2 codons between which the substitution is
    * synonymous, to set a basis to the homogeneization of the rates.
    *
    */
-
-  int synfrom_, synto_;
+  size_t synfrom_, synto_;
   
 public:
   /*
@@ -114,6 +113,8 @@ private:
 
   MixedSubstitutionModel& getMixedModel() { return *pmixmodel_.get(); }
 
+  const FrequenciesSet* getFrequenciesSet() const {return pmixmodel_->getNModel(1)->getFrequenciesSet();}
+
 };
 
 } //end of namespace bpp.
diff --git a/src/Bpp/Phyl/Model/Codon/YNGKP_M8.cpp b/src/Bpp/Phyl/Model/Codon/YNGKP_M8.cpp
index 2fb5891..869d7ab 100644
--- a/src/Bpp/Phyl/Model/Codon/YNGKP_M8.cpp
+++ b/src/Bpp/Phyl/Model/Codon/YNGKP_M8.cpp
@@ -53,8 +53,8 @@ using namespace std;
 YNGKP_M8::YNGKP_M8(const GeneticCode* gc, FrequenciesSet* codonFreqs, unsigned int nclass) :
   AbstractBiblioMixedSubstitutionModel("YNGKP_M8."),
   pmixmodel_(0),
-  synfrom_(-1),
-  synto_(-1)
+  synfrom_(),
+  synto_()
 {
   if (nclass <= 0)
     throw Exception("Bad number of classes for model YNGKP_M8: " + TextTools::toString(nclass));
@@ -76,8 +76,10 @@ YNGKP_M8::YNGKP_M8(const GeneticCode* gc, FrequenciesSet* codonFreqs, unsigned i
   map<string, DiscreteDistribution*> mpdd;
   mpdd["omega"] = pmodd;
 
-  pmixmodel_.reset(new MixtureOfASubstitutionModel(gc->getSourceAlphabet(), new YN98(gc, codonFreqs), mpdd));
+  YN98* yn98 = new YN98(gc, codonFreqs);
+  pmixmodel_.reset(new MixtureOfASubstitutionModel(gc->getSourceAlphabet(), yn98, mpdd));
   delete pbdd;
+  vector<int> supportedChars = yn98->getAlphabetStates();
 
   // mapping the parameters
 
@@ -114,11 +116,11 @@ YNGKP_M8::YNGKP_M8(const GeneticCode* gc, FrequenciesSet* codonFreqs, unsigned i
   addParameter_(new Parameter("YNGKP_M8.omegas", 2., new IntervalConstraint(1, 1, false), true));
 
   // look for synonymous codons
-  for (synfrom_ = 1; synfrom_ < (int)gc->getSourceAlphabet()->getSize(); synfrom_++)
+  for (synfrom_ = 1; synfrom_ < supportedChars.size(); synfrom_++)
   {
     for (synto_ = 0; synto_ < synfrom_; synto_++)
     {
-      if ((gc->areSynonymous(synfrom_, synto_))
+      if ((gc->areSynonymous(supportedChars[synfrom_], supportedChars[synto_]))
           && (pmixmodel_->getNModel(0)->Qij(synfrom_, synto_) != 0)
           && (pmixmodel_->getNModel(1)->Qij(synfrom_, synto_) != 0))
         break;
@@ -127,7 +129,7 @@ YNGKP_M8::YNGKP_M8(const GeneticCode* gc, FrequenciesSet* codonFreqs, unsigned i
       break;
   }
 
-  if (synto_ == (int)gc->getSourceAlphabet()->getSize())
+  if (synto_ == gc->getSourceAlphabet()->getSize())
     throw Exception("Impossible to find synonymous codons");
 
   // update Matrices
diff --git a/src/Bpp/Phyl/Model/Codon/YNGKP_M8.h b/src/Bpp/Phyl/Model/Codon/YNGKP_M8.h
index 849f101..d9caf9d 100644
--- a/src/Bpp/Phyl/Model/Codon/YNGKP_M8.h
+++ b/src/Bpp/Phyl/Model/Codon/YNGKP_M8.h
@@ -77,13 +77,11 @@ class YNGKP_M8:
 private:
   std::auto_ptr<MixtureOfASubstitutionModel> pmixmodel_;
 
-  /*
-   *@brief indexes of 2 codons between which the substitution is
+  /**
+   * @brief indexes of 2 codons between which the substitution is
    * synonymous, to set a basis to the homogeneization of the rates.
-   *
    */
-
-  int synfrom_, synto_;
+  size_t synfrom_, synto_;
   
 public:
   /*
@@ -117,6 +115,7 @@ private:
 
   MixedSubstitutionModel& getMixedModel() { return *pmixmodel_.get(); }
 
+  const FrequenciesSet* getFrequenciesSet() const {return pmixmodel_->getNModel(1)->getFrequenciesSet();}
 };
 
 } //end of namespace bpp.
diff --git a/src/Bpp/Phyl/Model/FrequenciesSet/CodonFrequenciesSet.cpp b/src/Bpp/Phyl/Model/FrequenciesSet/CodonFrequenciesSet.cpp
index 59820c0..8729f81 100644
--- a/src/Bpp/Phyl/Model/FrequenciesSet/CodonFrequenciesSet.cpp
+++ b/src/Bpp/Phyl/Model/FrequenciesSet/CodonFrequenciesSet.cpp
@@ -39,6 +39,10 @@
 
 #include "CodonFrequenciesSet.h"
 #include "NucleotideFrequenciesSet.h"
+#include "../StateMap.h"
+
+// From bpp-core:
+#include <Bpp/Numeric/Prob/Simplex.h>
 
 using namespace bpp;
 using namespace std;
@@ -46,143 +50,150 @@ using namespace std;
 // ////////////////////////////
 // FullCodonFrequenciesSet
 
-FullCodonFrequenciesSet::FullCodonFrequenciesSet(const CodonAlphabet* alphabet, bool allowNullFreqs, const string& name) :
-  AbstractFrequenciesSet(alphabet->getSize(), alphabet, "Full.", name)
+FullCodonFrequenciesSet::FullCodonFrequenciesSet(const GeneticCode* gCode, bool allowNullFreqs, unsigned short method, const string& name) :
+  AbstractFrequenciesSet(
+    new CanonicalStateMap(gCode->getSourceAlphabet(), false),
+    "Full.",
+    name),
+  pgc_(gCode),
+  sFreq_(gCode->getSourceAlphabet()->getSize()  - gCode->getNumberOfStopCodons(), method, allowNullFreqs, "Full.")
 {
-  size_t size = alphabet->getSize() - alphabet->numberOfStopCodons();
-  size_t j = 0;
+  vector<double> vd;
+  double r = 1. / static_cast<double>(sFreq_.dimension());
 
-  for (size_t i = 0; i < alphabet->getSize() - 1; i++)
+  for (size_t i = 0; i < sFreq_.dimension(); i++)
   {
-    if (alphabet->isStop(static_cast<int>(i)))
-    {
-      getFreq_(i) = 0;
-    }
-    else
-    {
-      addParameter_(new Parameter(
-                      "Full.theta" + TextTools::toString(i + 1),
-                      1. / static_cast<double>(size - j),
-                      allowNullFreqs ?
-                      &Parameter::PROP_CONSTRAINT_IN :
-                      &FrequenciesSet::FREQUENCE_CONSTRAINT_MILLI));
-      getFreq_(i) = 1. / static_cast<double>(size);
-      j++;
-    }
+    vd.push_back(r);
   }
-  size_t i = alphabet->getSize() - 1;
-  getFreq_(i) = (alphabet->isStop(static_cast<int>(i))) ? 0 : 1. / static_cast<double>(size);
-}
 
+  sFreq_.setFrequencies(vd);
+  addParameters_(sFreq_.getParameters());
+  updateFreq_();
+}
 
-FullCodonFrequenciesSet::FullCodonFrequenciesSet(const CodonAlphabet* alphabet, const vector<double>& initFreqs, bool allowNullFreqs, const string& name) :
-  AbstractFrequenciesSet(alphabet->getSize(), alphabet, "Full.", name)
+FullCodonFrequenciesSet::FullCodonFrequenciesSet(
+  const GeneticCode* gCode,
+  const vector<double>& initFreqs,
+  bool allowNullFreqs,
+  unsigned short method,
+  const string& name) :
+  AbstractFrequenciesSet(new CanonicalStateMap(gCode->getSourceAlphabet(), false), "Full.", name),
+  pgc_(gCode),
+  sFreq_(gCode->getSourceAlphabet()->getSize() - gCode->getNumberOfStopCodons(), method, allowNullFreqs, "Full.")
 {
-  if (initFreqs.size() != alphabet->getSize())
-    throw Exception("FullCodonFrequenciesSet(constructor). There must be " + TextTools::toString(alphabet->getSize()) + " frequencies.");
-  double sum = 0.0;
+  if (initFreqs.size() != getAlphabet()->getSize())
+    throw Exception("FullCodonFrequenciesSet(constructor). There must be " + TextTools::toString(gCode->getSourceAlphabet()->getSize()) + " frequencies.");
 
-  for (size_t i = 0; i < initFreqs.size(); i++)
+  double sum = 0;
+  for (size_t i = 0; i < getAlphabet()->getSize(); i++)
   {
-    if (!alphabet->isStop(static_cast<int>(i)))
-    {
+    if (!pgc_->isStop(static_cast<int>(i)))
       sum += initFreqs[i];
-    }
   }
 
-  double y = 1;
-  for (size_t i = 0; i < alphabet->getSize() - 1; i++)
+  vector<double> vd;
+  for (size_t i = 0; i < getAlphabet()->getSize(); i++)
   {
-    if (alphabet->isStop(static_cast<int>(i)))
-    {
-      getFreq_(i) = 0;
-    }
-    else
-    {
-      addParameter_(new Parameter(
-                      "Full.theta" + TextTools::toString(i + 1),
-                      initFreqs[i] / sum / y,
-                      allowNullFreqs ?
-                      &Parameter::PROP_CONSTRAINT_IN :
-                      &FrequenciesSet::FREQUENCE_CONSTRAINT_MILLI));
-      getFreq_(i) = initFreqs[i] / sum;
-      y -= initFreqs[i] / sum;
-    }
+    if (!gCode->isStop(static_cast<int>(i)))
+      vd.push_back(initFreqs[i] / sum);
   }
-  size_t i = alphabet->getSize() - 1;
-  getFreq_(i) = (alphabet->isStop(static_cast<int>(i))) ? 0 : initFreqs[i] / sum;
+
+  sFreq_.setFrequencies(vd);
+  addParameters_(sFreq_.getParameters());
+  updateFreq_();
+}
+
+FullCodonFrequenciesSet::FullCodonFrequenciesSet(const FullCodonFrequenciesSet& fcfs) :
+  AbstractFrequenciesSet(fcfs),
+  pgc_(fcfs.pgc_),
+  sFreq_(fcfs.sFreq_)
+{}
+
+FullCodonFrequenciesSet& FullCodonFrequenciesSet::operator=(const FullCodonFrequenciesSet& fcfs)
+{
+  AbstractFrequenciesSet::operator=(fcfs);
+  pgc_ = fcfs.pgc_;
+  sFreq_ = fcfs.sFreq_;
+
+  return *this;
+}
+
+void FullCodonFrequenciesSet::setNamespace(const std::string& nameSpace)
+{
+  sFreq_.setNamespace(nameSpace);
+  AbstractFrequenciesSet::setNamespace(nameSpace);
 }
 
 void FullCodonFrequenciesSet::setFrequencies(const vector<double>& frequencies)
 {
   if (frequencies.size() != getAlphabet()->getSize())
     throw DimensionException("FullFrequenciesSet::setFrequencies", frequencies.size(), getAlphabet()->getSize());
-  const CodonAlphabet* alphabet = getAlphabet();
 
-  double sum = 0.0;
-  size_t i;
-  for (i = 0; i < frequencies.size(); i++)
+  double sum = 0;
+  for (size_t i = 0; i < getAlphabet()->getSize(); i++)
   {
-    if (!(alphabet->isStop(static_cast<int>(i))))
+    if (!pgc_->isStop(static_cast<int>(i)))
       sum += frequencies[i];
   }
 
-  double y = 1;
-  for (i = 0; i < alphabet->getSize() - 1; i++)
+  vector<double> vd;
+  for (size_t i = 0; i < getAlphabet()->getSize(); i++)
   {
-    if (alphabet->isStop(static_cast<int>(i)))
-    {
-      getFreq_(i) = 0;
-    }
-    else
-    {
-      getParameter_("theta" + TextTools::toString(i + 1)).setValue(frequencies[i] / sum / y);
-      y -= frequencies[i] / sum;
-      getFreq_(i) = frequencies[i] / sum;
-    }
+    if (!pgc_->isStop(static_cast<int>(i)))
+      vd.push_back(frequencies[i] / sum);
   }
-  i = alphabet->getSize() - 1;
-  getFreq_(i) = (alphabet->isStop(static_cast<int>(i))) ? 0 : frequencies[i] / sum;
+
+  sFreq_.setFrequencies(vd);
+  setParametersValues(sFreq_.getParameters());
+  updateFreq_();
 }
 
 void FullCodonFrequenciesSet::fireParameterChanged(const ParameterList& parameters)
 {
-  const CodonAlphabet* alphabet = getAlphabet();
-  double y = 1;
-  size_t i;
-  for (i = 0; i < alphabet->getSize() - 1; i++)
+  sFreq_.matchParametersValues(parameters);
+  updateFreq_();
+}
+
+void FullCodonFrequenciesSet::updateFreq_()
+{
+  size_t nbstop = 0;
+
+  for (size_t j = 0; j < getAlphabet()->getSize(); j++)
   {
-    if (!(alphabet->isStop(static_cast<int>(i))))
+    if (pgc_->isStop(static_cast<int>(j)))
     {
-      getFreq_(i) = getParameter_("theta" + TextTools::toString(i + 1)).getValue() * y;
-      y *= 1 - getParameter_("theta" + TextTools::toString(i + 1)).getValue();
+      getFreq_(j) = 0;
+      nbstop++;
     }
+    else
+      getFreq_(j) = sFreq_.prob(j - nbstop);
   }
-
-  i = alphabet->getSize() - 1;
-  getFreq_(i) = (alphabet->isStop(static_cast<int>(i))) ? 0 : y;
 }
 
 
 // ////////////////////////////
 // FullPerAACodonFrequenciesSet
 
-FullPerAACodonFrequenciesSet::FullPerAACodonFrequenciesSet(const GeneticCode* gencode,
-                                                           const ProteinFrequenciesSet* ppfs) :
-  AbstractFrequenciesSet(gencode->getSourceAlphabet()->getSize(), gencode->getSourceAlphabet(), "FullPerAA.", "FullPerAA"),
+FullPerAACodonFrequenciesSet::FullPerAACodonFrequenciesSet(
+  const GeneticCode* gencode,
+  ProteinFrequenciesSet* ppfs,
+  unsigned short method) :
+  AbstractFrequenciesSet(new CanonicalStateMap(gencode->getSourceAlphabet(), false), "FullPerAA.", "FullPerAA"),
   pgc_(gencode),
-  ppfs_(ppfs->clone()),
+  ppfs_(ppfs),
   vS_()
 {
   const ProteicAlphabet* ppa = dynamic_cast<const ProteicAlphabet*>(pgc_->getTargetAlphabet());
-
-  for (size_t i = 0; i < ppa->getSize(); i++)
+  const StateMap& aaStates = ppfs_->getStateMap();
+  for (size_t i = 0; i < aaStates.getNumberOfModelStates(); ++i)
   {
-    vector<int> vc = pgc_->getSynonymous(static_cast<int>(i));
-    vS_.push_back(Simplex(vc.size(), 1, ""));
+    int aa = aaStates.getAlphabetStateAsInt(i);
+    vector<int> vc = pgc_->getSynonymous(aa);
+    vS_.push_back(Simplex(vc.size(), method, 0, ""));
 
     Simplex& si = vS_[i];
-    si.setNamespace("FullPerAA." + ppa->getAbbr(static_cast<int>(i)) + "_");
+
+    si.setNamespace("FullPerAA." + ppa->getAbbr(aa) + "_");
     addParameters_(si.getParameters());
   }
 
@@ -192,21 +203,22 @@ FullPerAACodonFrequenciesSet::FullPerAACodonFrequenciesSet(const GeneticCode* ge
   updateFrequencies();
 }
 
-FullPerAACodonFrequenciesSet::FullPerAACodonFrequenciesSet(const GeneticCode* gencode) :
-  AbstractFrequenciesSet(gencode->getSourceAlphabet()->getSize(), gencode->getSourceAlphabet(), "FullPerAA.", "FullPerAA"),
+FullPerAACodonFrequenciesSet::FullPerAACodonFrequenciesSet(const GeneticCode* gencode, unsigned short method) :
+  AbstractFrequenciesSet(new CanonicalStateMap(gencode->getSourceAlphabet(), false), "FullPerAA.", "FullPerAA"),
   pgc_(gencode),
   ppfs_(new FixedProteinFrequenciesSet(dynamic_cast<const ProteicAlphabet*>(gencode->getTargetAlphabet()), "FullPerAA.")),
   vS_()
 {
   const ProteicAlphabet* ppa = dynamic_cast<const ProteicAlphabet*>(pgc_->getTargetAlphabet());
-
-  for (size_t i = 0; i < ppa->getSize(); i++)
+  const StateMap& aaStates = ppfs_->getStateMap();
+  for (size_t i = 0; i < aaStates.getNumberOfModelStates(); ++i)
   {
-    vector<int> vc = pgc_->getSynonymous(static_cast<int>(i));
-    vS_.push_back(Simplex(vc.size(), 1, ""));
+    int aa = aaStates.getAlphabetStateAsInt(i);
+    vector<int> vc = pgc_->getSynonymous(aa);
+    vS_.push_back(Simplex(vc.size(), method, 0, ""));
 
     Simplex& si = vS_[i];
-    si.setNamespace("FullPerAA." + ppa->getAbbr(static_cast<int>(i)) + "_");
+    si.setNamespace("FullPerAA." + ppa->getAbbr(aa) + "_");
     addParameters_(si.getParameters());
   }
 
@@ -223,22 +235,12 @@ FullPerAACodonFrequenciesSet::FullPerAACodonFrequenciesSet(const FullPerAACodonF
   updateFrequencies();
 }
 
-FullPerAACodonFrequenciesSet::~FullPerAACodonFrequenciesSet()
-{
-  if (ppfs_)
-    delete ppfs_;
-  ppfs_ = 0;
-}
-
 FullPerAACodonFrequenciesSet& FullPerAACodonFrequenciesSet::operator=(const FullPerAACodonFrequenciesSet& ffs)
 {
-  if (ppfs_)
-    delete ppfs_;
-
   CodonFrequenciesSet::operator=(ffs);
   AbstractFrequenciesSet::operator=(ffs);
   pgc_ = ffs.pgc_;
-  ppfs_ = ffs.ppfs_->clone();
+  ppfs_.reset(ffs.ppfs_->clone());
   vS_ = ffs.vS_;
 
   return *this;
@@ -246,8 +248,8 @@ FullPerAACodonFrequenciesSet& FullPerAACodonFrequenciesSet::operator=(const Full
 
 void FullPerAACodonFrequenciesSet::fireParameterChanged(const ParameterList& parameters)
 {
-  if (dynamic_cast<AbstractFrequenciesSet*>(ppfs_))
-    (dynamic_cast<AbstractFrequenciesSet*>(ppfs_))->matchParametersValues(parameters);
+  if (dynamic_cast<AbstractFrequenciesSet*>(ppfs_.get()))
+    (dynamic_cast<AbstractFrequenciesSet*>(ppfs_.get()))->matchParametersValues(parameters);
   for (size_t i = 0; i < vS_.size(); i++)
   {
     vS_[i].matchParametersValues(parameters);
@@ -257,45 +259,54 @@ void FullPerAACodonFrequenciesSet::fireParameterChanged(const ParameterList& par
 
 void FullPerAACodonFrequenciesSet::updateFrequencies()
 {
-  const ProteicAlphabet* ppa = dynamic_cast<const ProteicAlphabet*>(pgc_->getTargetAlphabet());
-
-  for (size_t i = 0; i < ppa->getSize(); i++)
+  const StateMap& aaStates = ppfs_->getStateMap();
+  for (size_t i = 0; i < aaStates.getNumberOfModelStates(); ++i)
   {
-    std::vector<int> vc = pgc_->getSynonymous(static_cast<int>(i));
+    int aa = aaStates.getAlphabetStateAsInt(i);
+    std::vector<int> vc = pgc_->getSynonymous(aa);
     for (size_t j = 0; j < vc.size(); j++)
     {
-      getFreq_(vc[j]) = (ppfs_->getFrequencies())[i] * vS_[i].prob(j);
+      //NB: only one alphabet state per model state here, as it is a CodonFreqSet.
+      getFreq_(getStateMap().getModelStates(vc[j])[0]) =
+        static_cast<double>(vc.size()) * ppfs_->getFrequencies()[i] * vS_[i].prob(j);
     }
   }
+  normalize();
 }
 
 void FullPerAACodonFrequenciesSet::setFrequencies(const vector<double>& frequencies)
 {
   if (frequencies.size() != getAlphabet()->getSize())
-    throw DimensionException("FullParAAFrequenciesSet::setFrequencies", frequencies.size(), getAlphabet()->getSize());
+    throw DimensionException("FullPerAAFrequenciesSet::setFrequencies", frequencies.size(), getAlphabet()->getSize());
 
-  const ProteicAlphabet* ppa = dynamic_cast<const ProteicAlphabet*>(pgc_->getTargetAlphabet());
-
-  vector<double> vaa;
-  double S = 0;
-  for (size_t i = 0; i < ppa->getSize(); i++)
+  double bigS = 0;
+  Vdouble vaa;
+  
+  const StateMap& aaStates = ppfs_->getStateMap();
+  for (size_t i = 0; i < aaStates.getNumberOfModelStates(); ++i)
   {
-    vector<double> vp;
+    int aa = aaStates.getAlphabetStateAsInt(i);
+    std::vector<int> vc = pgc_->getSynonymous(aa);
+    Vdouble vp;
     double s = 0;
-    std::vector<int> vc = pgc_->getSynonymous(static_cast<int>(i));
+    
     for (size_t j = 0; j < vc.size(); j++)
     {
-      vp.push_back(frequencies[vc[j]]);
-      s += frequencies[vc[j]];
+      size_t index = pgc_->getSourceAlphabet()->getStateIndex(vc[j]);
+      vp.push_back(frequencies[index-1]);
+      s += frequencies[index-1];
     }
-    S += s;
-    vaa.push_back(s);
+      
     vp /= s;
     vS_[i].setFrequencies(vp);
+
     matchParametersValues(vS_[i].getParameters());
+
+    bigS += s / static_cast<double>(vc.size());
+    vaa.push_back(s / static_cast<double>(vc.size()));
   }
 
-  vaa /= S; // to avoid counting of stop codons
+  vaa /= bigS; // to avoid counting of stop codons
   ppfs_->setFrequencies(vaa);
   matchParametersValues(ppfs_->getParameters());
   updateFrequencies();
@@ -317,20 +328,25 @@ void FullPerAACodonFrequenciesSet::setNamespace(const std::string& prefix)
 // ///////////////////////////////////////////
 // / FixedCodonFrequenciesSet
 
-FixedCodonFrequenciesSet::FixedCodonFrequenciesSet(const CodonAlphabet* alphabet, const vector<double>& initFreqs, const string& name) :
-  AbstractFrequenciesSet(alphabet->getSize(), alphabet, "Fixed.", name)
+FixedCodonFrequenciesSet::FixedCodonFrequenciesSet(
+  const GeneticCode* gCode,
+  const vector<double>& initFreqs,
+  const string& name) :
+  AbstractFrequenciesSet(new CanonicalStateMap(gCode->getSourceAlphabet(), false), "Fixed.", name),
+  pgc_(gCode)
 {
   setFrequencies(initFreqs);
 }
 
-FixedCodonFrequenciesSet::FixedCodonFrequenciesSet(const CodonAlphabet* alphabet, const string& name) :
-  AbstractFrequenciesSet(alphabet->getSize(), alphabet, "Fixed.", name)
+FixedCodonFrequenciesSet::FixedCodonFrequenciesSet(const GeneticCode* gCode, const string& name) :
+  AbstractFrequenciesSet(new CanonicalStateMap(gCode->getSourceAlphabet(), false), "Fixed.", name),
+  pgc_(gCode)
 {
-  size_t size = alphabet->getSize() - alphabet->numberOfStopCodons();
+  size_t size = gCode->getSourceAlphabet()->getSize() - gCode->getNumberOfStopCodons();
 
-  for (size_t i = 0; i < alphabet->getSize(); i++)
+  for (size_t i = 0; i < gCode->getSourceAlphabet()->getSize(); i++)
   {
-    getFreq_(i) = (alphabet->isStop(static_cast<int>(i))) ? 0 : 1. / static_cast<double>(size);
+    getFreq_(i) = (gCode->isStop(static_cast<int>(i))) ? 0 : 1. / static_cast<double>(size);
   }
 }
 
@@ -343,13 +359,13 @@ void FixedCodonFrequenciesSet::setFrequencies(const vector<double>& frequencies)
 
   for (size_t i = 0; i < frequencies.size(); i++)
   {
-    if (!(ca->isStop(static_cast<int>(i))))
+    if (!(pgc_->isStop(static_cast<int>(i))))
       sum += frequencies[i];
   }
 
   for (size_t i = 0; i < ca->getSize(); i++)
   {
-    getFreq_(i) = (ca->isStop(static_cast<int>(i))) ? 0 : frequencies[i] / sum;
+    getFreq_(i) = (pgc_->isStop(static_cast<int>(i))) ? 0 : frequencies[i] / sum;
   }
 }
 
@@ -359,39 +375,39 @@ void FixedCodonFrequenciesSet::setFrequencies(const vector<double>& frequencies)
 
 
 CodonFromIndependentFrequenciesSet::CodonFromIndependentFrequenciesSet(
-  const CodonAlphabet* pCA,
+  const GeneticCode* gCode,
   const std::vector<FrequenciesSet*>& freqvector,
   const string& name,
   const string& mgmtStopFreq) :
-  WordFromIndependentFrequenciesSet(pCA, freqvector, "", name),
+  WordFromIndependentFrequenciesSet(gCode->getSourceAlphabet(), freqvector, "", name),
   mStopNeigh_(),
-  mgmtStopFreq_(2)
+  mgmtStopFreq_(2),
+  pgc_(gCode)
 {
-  if (mgmtStopFreq=="uniform")
-    mgmtStopFreq_=0;
-  else if (mgmtStopFreq=="linear")
-    mgmtStopFreq_=1;
-  
+  if (mgmtStopFreq == "uniform")
+    mgmtStopFreq_ = 0;
+  else if (mgmtStopFreq == "linear")
+    mgmtStopFreq_ = 1;
+
   // fill the map of the stop codons
 
-  vector<int> vspcod = getAlphabet()->stopCodons();
+  vector<int> vspcod = gCode->getStopCodonsAsInt();
   for (size_t ispcod = 0; ispcod < vspcod.size(); ispcod++)
   {
     size_t pow = 1;
     int nspcod = vspcod[ispcod];
-    for (int ph = 0; ph < 3; ph++)
+    for (size_t ph = 0; ph < 3; ph++)
     {
-      size_t nspcod0 = nspcod - pow * getAlphabet()->getNPosition(nspcod, 2 - ph);
+      size_t nspcod0 = static_cast<size_t>(nspcod) - pow * static_cast<size_t>(getAlphabet()->getNPosition(nspcod, 2 - ph));
       for (size_t dec = 0; dec < 4; dec++)
       {
         size_t vois = nspcod0 + pow * dec;
-        if (!getAlphabet()->isStop(static_cast<int>(vois)))
+        if (!pgc_->isStop(static_cast<int>(vois)))
           mStopNeigh_[nspcod].push_back(static_cast<int>(vois));
       }
       pow *= 4;
     }
   }
-
   updateFrequencies();
 }
 
@@ -403,7 +419,8 @@ const CodonAlphabet* CodonFromIndependentFrequenciesSet::getAlphabet() const
 CodonFromIndependentFrequenciesSet::CodonFromIndependentFrequenciesSet(const CodonFromIndependentFrequenciesSet& iwfs) :
   WordFromIndependentFrequenciesSet(iwfs),
   mStopNeigh_(iwfs.mStopNeigh_),
-  mgmtStopFreq_(iwfs.mgmtStopFreq_)
+  mgmtStopFreq_(iwfs.mgmtStopFreq_),
+  pgc_(iwfs.pgc_)
 {
   updateFrequencies();
 }
@@ -413,6 +430,7 @@ CodonFromIndependentFrequenciesSet& CodonFromIndependentFrequenciesSet::operator
   WordFromIndependentFrequenciesSet::operator=(iwfs);
   mStopNeigh_ = iwfs.mStopNeigh_;
   mgmtStopFreq_ = iwfs.mgmtStopFreq_;
+  pgc_ = iwfs.pgc_;
   return *this;
 }
 
@@ -422,88 +440,97 @@ void CodonFromIndependentFrequenciesSet::updateFrequencies()
 
   size_t s = getAlphabet()->getSize();
 
-  if (mgmtStopFreq_!=0)
+  if (mgmtStopFreq_ != 0)
+  {
+    // The frequencies of the stop codons are distributed to all
+    // neighbour non-stop codons
+    double f[64];
+    for (size_t i = 0; i < s; i++)
+    {
+      f[i] = 0;
+    }
+
+    std::map<int, Vint>::iterator mStopNeigh_it(mStopNeigh_.begin());
+    while (mStopNeigh_it != mStopNeigh_.end())
+    {
+      int stNb = mStopNeigh_it->first;
+      Vint vneigh = mStopNeigh_it->second;
+      double sneifreq = 0;
+      for (size_t vn = 0; vn < vneigh.size(); vn++)
+      {
+        sneifreq += pow(getFreq_(static_cast<size_t>(vneigh[vn])), mgmtStopFreq_);
+      }
+      double x = getFreq_(static_cast<size_t>(stNb)) / sneifreq;
+      for (size_t vn = 0; vn < vneigh.size(); vn++)
+      {
+        f[vneigh[vn]] += pow(getFreq_(static_cast<size_t>(vneigh[vn])), mgmtStopFreq_) * x;
+      }
+      getFreq_(static_cast<size_t>(stNb)) = 0;
+      mStopNeigh_it++;
+    }
+
+    for (size_t i = 0; i < s; i++)
     {
-      // The frequencies of the stop codons are distributed to all
-      // neighbour non-stop codons
-      double f[64];
-      for (size_t i = 0; i < s; i++)
-        {
-          f[i] = 0;
-        }
-
-      std::map<int, Vint>::iterator mStopNeigh_it(mStopNeigh_.begin());
-      while (mStopNeigh_it != mStopNeigh_.end())
-        {
-          int stNb = mStopNeigh_it->first;
-          Vint vneigh = mStopNeigh_it->second;
-          double sneifreq = 0;
-          for (size_t vn = 0; vn < vneigh.size(); vn++)
-            {
-              sneifreq += pow(getFreq_(vneigh[vn]), mgmtStopFreq_);
-            }
-          double x = getFreq_(stNb) / sneifreq;
-          for (size_t vn = 0; vn < vneigh.size(); vn++)
-            {
-              f[vneigh[vn]] += pow(getFreq_(vneigh[vn]), mgmtStopFreq_) * x;
-            }
-          getFreq_(stNb) = 0;
-          mStopNeigh_it++;
-        }
-
-      for (size_t i = 0; i < s; i++)
-        {
-          getFreq_(i) += f[i];
-        }
+      getFreq_(i) += f[i];
     }
+  }
   else
+  {
+    double sum = 0.;
+    for (size_t i = 0; i < s; i++)
     {
-      double sum=0.;
-      for (unsigned int i = 0; i < s; i++)
-        if (!getAlphabet()->isStop(i))
-          sum+=getFreq_(i);
- 
-      for (unsigned int i = 0; i < s; i++)
-        if (getAlphabet()->isStop(i))
-          getFreq_(i)=0;
-        else
-          getFreq_(i)/=sum;
+      if (!pgc_->isStop(static_cast<int>(i)))
+        sum += getFreq_(i);
     }
+
+    for (size_t i = 0; i < s; i++)
+    {
+      if (pgc_->isStop(static_cast<int>(i)))
+        getFreq_(i) = 0;
+      else
+        getFreq_(i) /= sum;
+    }
+  }
 }
 
 // ///////////////////////////////////////////////////////////////////
 // // CodonFromUniqueFrequenciesSet
 
 
-CodonFromUniqueFrequenciesSet::CodonFromUniqueFrequenciesSet(const CodonAlphabet* pCA, FrequenciesSet* pfreq, const string& name, const string&  mgmtStopFreq) :
-  WordFromUniqueFrequenciesSet(pCA, pfreq, "", name),
+CodonFromUniqueFrequenciesSet::CodonFromUniqueFrequenciesSet(
+  const GeneticCode* gCode,
+  FrequenciesSet* pfreq,
+  const string& name,
+  const string& mgmtStopFreq) :
+  WordFromUniqueFrequenciesSet(gCode->getSourceAlphabet(), pfreq, "", name),
   mStopNeigh_(),
-  mgmtStopFreq_(2)
+  mgmtStopFreq_(2),
+  pgc_(gCode)
 {
-  if (mgmtStopFreq=="uniform")
-    mgmtStopFreq_=0;
-  else if (mgmtStopFreq=="linear")
-    mgmtStopFreq_=1;
-  
+  if (mgmtStopFreq == "uniform")
+    mgmtStopFreq_ = 0;
+  else if (mgmtStopFreq == "linear")
+    mgmtStopFreq_ = 1;
+
   // fill the map of the stop codons
 
-  vector<int> vspcod = getAlphabet()->stopCodons();
+  vector<int> vspcod = gCode->getStopCodonsAsInt();
   for (size_t ispcod = 0; ispcod < vspcod.size(); ispcod++)
+  {
+    size_t pow = 1;
+    int nspcod = vspcod[ispcod];
+    for (int ph = 0; ph < 3; ph++)
     {
-      size_t pow = 1;
-      int nspcod = vspcod[ispcod];
-      for (int ph = 0; ph < 3; ph++)
-        {
-          size_t nspcod0 = nspcod - pow * getAlphabet()->getNPosition(nspcod, 2 - ph);
-          for (size_t dec = 0; dec < 4; dec++)
-            {
-              size_t vois = nspcod0 + pow * dec;
-              if (!getAlphabet()->isStop(static_cast<int>(vois)))
-                mStopNeigh_[nspcod].push_back(static_cast<int>(vois));
-            }
-          pow *= 4;
-        }
+      size_t nspcod0 = static_cast<size_t>(nspcod) - pow * static_cast<size_t>(getAlphabet()->getNPosition(nspcod, static_cast<unsigned int>(2 - ph)));
+      for (size_t dec = 0; dec < 4; dec++)
+      {
+        size_t vois = nspcod0 + pow * dec;
+        if (!pgc_->isStop(static_cast<int>(vois)))
+          mStopNeigh_[nspcod].push_back(static_cast<int>(vois));
+      }
+      pow *= 4;
     }
+  }
 
   updateFrequencies();
 }
@@ -517,7 +544,8 @@ const CodonAlphabet* CodonFromUniqueFrequenciesSet::getAlphabet() const
 CodonFromUniqueFrequenciesSet::CodonFromUniqueFrequenciesSet(const CodonFromUniqueFrequenciesSet& iwfs) :
   WordFromUniqueFrequenciesSet(iwfs),
   mStopNeigh_(iwfs.mStopNeigh_),
-  mgmtStopFreq_(iwfs.mgmtStopFreq_)
+  mgmtStopFreq_(iwfs.mgmtStopFreq_),
+  pgc_(iwfs.pgc_)
 {
   updateFrequencies();
 }
@@ -527,6 +555,7 @@ CodonFromUniqueFrequenciesSet& CodonFromUniqueFrequenciesSet::operator=(const Co
   WordFromUniqueFrequenciesSet::operator=(iwfs);
   mStopNeigh_ = iwfs.mStopNeigh_;
   mgmtStopFreq_ = iwfs.mgmtStopFreq_;
+  pgc_ = iwfs.pgc_;
   return *this;
 }
 
@@ -536,75 +565,79 @@ void CodonFromUniqueFrequenciesSet::updateFrequencies()
 
   size_t s = getAlphabet()->getSize();
 
-  if (mgmtStopFreq_!=0)
+  if (mgmtStopFreq_ != 0)
+  {
+    // The frequencies of the stop codons are distributed to all
+    // neighbour non-stop codons
+    double f[64];
+    for (size_t i = 0; i < s; i++)
+    {
+      f[i] = 0;
+    }
+
+    std::map<int, Vint>::iterator mStopNeigh_it(mStopNeigh_.begin());
+    while (mStopNeigh_it != mStopNeigh_.end())
+    {
+      int stNb = mStopNeigh_it->first;
+      Vint vneigh = mStopNeigh_it->second;
+      double sneifreq = 0;
+      for (size_t vn = 0; vn < vneigh.size(); vn++)
+      {
+        sneifreq += pow(getFreq_(static_cast<size_t>(vneigh[vn])), mgmtStopFreq_);
+      }
+      double x = getFreq_(static_cast<size_t>(stNb)) / sneifreq;
+      for (size_t vn = 0; vn < vneigh.size(); vn++)
+      {
+        f[vneigh[vn]] += pow(getFreq_(static_cast<size_t>(vneigh[vn])), mgmtStopFreq_) * x;
+      }
+      getFreq_(static_cast<size_t>(stNb)) = 0;
+      mStopNeigh_it++;
+    }
+
+    for (size_t i = 0; i < s; i++)
     {
-      // The frequencies of the stop codons are distributed to all
-      // neighbour non-stop codons
-      double f[64];
-      for (size_t i = 0; i < s; i++)
-        {
-          f[i] = 0;
-        }
-
-      std::map<int, Vint>::iterator mStopNeigh_it(mStopNeigh_.begin());
-      while (mStopNeigh_it != mStopNeigh_.end())
-        {
-          int stNb = mStopNeigh_it->first;
-          Vint vneigh = mStopNeigh_it->second;
-          double sneifreq = 0;
-          for (size_t vn = 0; vn < vneigh.size(); vn++)
-            {
-              sneifreq += pow(getFreq_(vneigh[vn]), mgmtStopFreq_);
-            }
-          double x = getFreq_(stNb) / sneifreq;
-          for (size_t vn = 0; vn < vneigh.size(); vn++)
-            {
-              f[vneigh[vn]] += pow(getFreq_(vneigh[vn]), mgmtStopFreq_) * x;
-            }
-          getFreq_(stNb) = 0;
-          mStopNeigh_it++;
-        }
-
-      for (size_t i = 0; i < s; i++)
-        {
-          getFreq_(i) += f[i];
-        }
+      getFreq_(i) += f[i];
     }
+  }
   else
+  {
+    double sum = 0.;
+    for (size_t i = 0; i < s; i++)
+    {
+      if (!pgc_->isStop(static_cast<int>(i)))
+        sum += getFreq_(i);
+    }
+
+    for (unsigned int i = 0; i < s; i++)
     {
-      double sum=0.;
-      for (unsigned int i = 0; i < s; i++)
-        if (!getAlphabet()->isStop(i))
-          sum+=getFreq_(i);
- 
-      for (unsigned int i = 0; i < s; i++)
-        if (getAlphabet()->isStop(i))
-          getFreq_(i)=0;
-        else
-          getFreq_(i)/=sum;
+      if (pgc_->isStop(static_cast<int>(i)))
+        getFreq_(i) = 0;
+      else
+        getFreq_(i) /= sum;
     }
+  }
 }
 
 /*********************************************************************/
 
-FrequenciesSet* CodonFrequenciesSet::getFrequenciesSetForCodons(short option, const CodonAlphabet& CA, const string& mgmtStopFreq)
+FrequenciesSet* CodonFrequenciesSet::getFrequenciesSetForCodons(short option, const GeneticCode* gCode, const string& mgmtStopFreq, unsigned short method)
 {
   FrequenciesSet* codonFreqs;
 
   if (option == F0)
-    codonFreqs = new FixedCodonFrequenciesSet(&CA, "F0");
+    codonFreqs = new FixedCodonFrequenciesSet(gCode, "F0");
   else if (option == F1X4)
-    codonFreqs = new CodonFromUniqueFrequenciesSet(&CA, new FullNucleotideFrequenciesSet(CA.getNucleicAlphabet()), "F1X4", mgmtStopFreq);
+    codonFreqs = new CodonFromUniqueFrequenciesSet(gCode, new FullNucleotideFrequenciesSet(gCode->getSourceAlphabet()->getNucleicAlphabet()), "F1X4", mgmtStopFreq);
   else if (option == F3X4)
   {
     vector<FrequenciesSet*> v_AFS(3);
-    v_AFS[0] = new FullNucleotideFrequenciesSet(CA.getNucleicAlphabet());
-    v_AFS[1] = new FullNucleotideFrequenciesSet(CA.getNucleicAlphabet());
-    v_AFS[2] = new FullNucleotideFrequenciesSet(CA.getNucleicAlphabet());
-    codonFreqs = new CodonFromIndependentFrequenciesSet(&CA, v_AFS, "F3X4", mgmtStopFreq);
+    v_AFS[0] = new FullNucleotideFrequenciesSet(gCode->getSourceAlphabet()->getNucleicAlphabet());
+    v_AFS[1] = new FullNucleotideFrequenciesSet(gCode->getSourceAlphabet()->getNucleicAlphabet());
+    v_AFS[2] = new FullNucleotideFrequenciesSet(gCode->getSourceAlphabet()->getNucleicAlphabet());
+    codonFreqs = new CodonFromIndependentFrequenciesSet(gCode, v_AFS, "F3X4", mgmtStopFreq);
   }
   else if (option == F61)
-    codonFreqs = new FullCodonFrequenciesSet(&CA, "F61");
+    codonFreqs = new FullCodonFrequenciesSet(gCode, false, method, "F61");
   else
     throw Exception("FrequenciesSet::getFrequencySetForCodons(). Unvalid codon frequency set argument.");
 
@@ -619,4 +652,3 @@ const short CodonFrequenciesSet::F3X4 = 2;
 const short CodonFrequenciesSet::F61  = 3;
 
 /******************************************************************************/
-
diff --git a/src/Bpp/Phyl/Model/FrequenciesSet/CodonFrequenciesSet.h b/src/Bpp/Phyl/Model/FrequenciesSet/CodonFrequenciesSet.h
index fc44808..3de6ab2 100644
--- a/src/Bpp/Phyl/Model/FrequenciesSet/CodonFrequenciesSet.h
+++ b/src/Bpp/Phyl/Model/FrequenciesSet/CodonFrequenciesSet.h
@@ -5,37 +5,37 @@
 //
 
 /*
-  Copyright or (c) 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.
-*/
+   Copyright or (c) 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 _CODONFREQUENCIESSET_H_
 #define _CODONFREQUENCIESSET_H_
@@ -50,341 +50,407 @@
 
 namespace bpp
 {
+/**
+ * @brief Parametrize a set of state frequencies for codons.
+ */
+class CodonFrequenciesSet :
+  public virtual FrequenciesSet
+{
+public:
+#ifndef NO_VIRTUAL_COV
+  CodonFrequenciesSet* clone() const = 0;
+
+  const CodonAlphabet* getAlphabet() const = 0;
+#endif
 
+public:
   /**
-   * @brief Parametrize a set of state frequencies for codons.
+   * @return The associated genetic code.
    */
-  class CodonFrequenciesSet :
-    public virtual FrequenciesSet
-  {
-  public:
-#ifndef NO_VIRTUAL_COV
-    CodonFrequenciesSet* clone() const = 0;
-    
-    const CodonAlphabet* getAlphabet() const = 0;
-#endif
-    
-  public:
-    /**
-     * @brief A helper function that provide frequencies set for codon models
-     * according to PAML option.
-     *
-     * @param option A code describing the option, one of F61, F1X4 or F3X4.
-     * @param CA the Codon Alphabet to use.
-     * @param mgmtStopFreq the optional way the frequencies assigned
-     * to the stop codons are redistributed to the other codons, with
-     * F1X4 and F3X4 options. The available values are:
-     *  - uniform : each stop frequency is distributed evenly
-     *  - linear : each stop frequency is distributed to the neighbour
-     *     codons (ie 1 substitution away), in proportion to each
-     *     target codon frequency.
-     *  - quadratic (default): each stop frequency is distributed to the
-     *     neighbour codons (ie 1 substitution away), in proportion to
-     *     the square of each target codon frequency.
-     *
-     */
-    
-    static FrequenciesSet* getFrequenciesSetForCodons(short option, const CodonAlphabet& CA, const std::string& mgmtStopFreq = "quadratic");
-    
-    static const short F0;
-    static const short F1X4;
-    static const short F3X4;
-    static const short F61;
-    
-    
-  };
+  virtual const GeneticCode* getGeneticCode() const = 0;
 
+  /**
+   * @brief A helper function that provide frequencies set for codon models
+   * according to PAML option.
+   *
+   * @param option A code describing the option, one of F61, F1X4 or F3X4.
+   * @param gCode The genetic code to use. The underlying codon alphabet object will be passed to the FrequenciesSet instance.
+   * @param mgmtStopFreq the optional way the frequencies assigned
+   * to the stop codons are redistributed to the other codons, with
+   * F1X4 and F3X4 options. The available values are:
+   *  - uniform : each stop frequency is distributed evenly
+   *  - linear : each stop frequency is distributed to the neighbour
+   *     codons (ie 1 substitution away), in proportion to each
+   *     target codon frequency.
+   *  - quadratic (default): each stop frequency is distributed to the
+   *     neighbour codons (ie 1 substitution away), in proportion to
+   *     the square of each target codon frequency.
+   * @param method The parametrization used for F61. Default method
+   * is 1 (ie global ratio).
+   *
+   * @see Simplex
+   */
+  static FrequenciesSet* getFrequenciesSetForCodons(short option, const GeneticCode* gCode, const std::string& mgmtStopFreq = "quadratic", unsigned short method = 1);
+
+  static const short F0;
+  static const short F1X4;
+  static const short F3X4;
+  static const short F61;
+};
+
+
+/**
+ * @brief A generic FrequenciesSet for Full Codon alphabets.
+ *
+ * It is very similar to FullFrequencySet, but only the non-stop codon
+ *   frequencies are parameterized.
+ */
+class FullCodonFrequenciesSet :
+  public virtual CodonFrequenciesSet,
+  public AbstractFrequenciesSet
+{
+protected:
+  const GeneticCode* pgc_;
 
+private:
   /**
-   * @brief A generic FrequenciesSet for Full Codon alphabets.
+   * @brief Simplex to handle the probabilities and the parameters.
    *
-   * It is very similar to FullFrequencySet, but only the non-stop codon
-   *   frequencies are parameterized.
    */
-  class FullCodonFrequenciesSet :
-    public virtual CodonFrequenciesSet,
-    public AbstractFrequenciesSet
-  {
-  public:
-    /**
-     * @brief Construction with uniform frequencies on the letters of
-     * the alphabet. The stop codon frequencies are null.
-     */
-    FullCodonFrequenciesSet(const CodonAlphabet* alphabet, bool allowNullFreqs = false, const std::string& name = "Full");
-    FullCodonFrequenciesSet(const CodonAlphabet* alphabet, const std::vector<double>& initFreqs, bool allowNullFreqs = false, const std::string& name = "Full");
+
+  Simplex sFreq_;
+
+public:
+  /**
+   * @brief Construction with uniform frequencies on the letters of
+   * the alphabet. The stop codon frequencies are null.
+   */
+  FullCodonFrequenciesSet(const GeneticCode* gCode, bool allowNullFreqs = false, unsigned short method = 1, const std::string& name = "Full");
+  FullCodonFrequenciesSet(const GeneticCode* gCode, const std::vector<double>& initFreqs, bool allowNullFreqs = false, unsigned short method = 1, const std::string& name = "Full");
+
+  FullCodonFrequenciesSet(const FullCodonFrequenciesSet& fcfs);
+  FullCodonFrequenciesSet& operator=(const FullCodonFrequenciesSet& fcfs);
 
 #ifndef NO_VIRTUAL_COV
-    FullCodonFrequenciesSet*
+  FullCodonFrequenciesSet*
 #else
-    Clonable*
+  Clonable*
 #endif
-    clone() const { return new FullCodonFrequenciesSet(*this); }
+  clone() const { return new FullCodonFrequenciesSet(*this); }
 
-  public:
-    /**
-     * @brief the given frequencies are normalized such thaat the sum of
-     * the frequencies on the non-stop codons equals 1.
-     *
-     */
-    void setFrequencies(const std::vector<double>& frequencies);
+public:
+  const GeneticCode* getGeneticCode() const { return pgc_; }
+
+  /**
+   * @brief the given frequencies are normalized such that the sum of
+   * the frequencies on the non-stop codons equals 1.
+   *
+   */
+  void setFrequencies(const std::vector<double>& frequencies);
 
 #ifndef NO_VIRTUAL_COV
-    const CodonAlphabet* getAlphabet() const
-    {
-      return dynamic_cast<const CodonAlphabet*>(AbstractFrequenciesSet::getAlphabet());
-    }
+  const CodonAlphabet* getAlphabet() const
+  {
+    return dynamic_cast<const CodonAlphabet*>(AbstractFrequenciesSet::getAlphabet());
+  }
 #endif
 
-  protected:
-    void fireParameterChanged(const ParameterList& parameters);
-  };
+  void setNamespace(const std::string& nameSpace);
 
+  unsigned short getMethod() const
+  {
+    return sFreq_.getMethod();
+  }
+
+protected:
+  void fireParameterChanged(const ParameterList& parameters);
+
+  void updateFreq_();
+};
+
+
+/**
+ * @brief FrequenciesSet useful for homogeneous and stationary models, codon implementation
+ *
+ * This set contains no parameter.
+ */
+class FixedCodonFrequenciesSet :
+  public virtual CodonFrequenciesSet,
+  public AbstractFrequenciesSet
+{
+protected:
+  const GeneticCode* pgc_;
+
+public:
+  FixedCodonFrequenciesSet(const GeneticCode* gCode, const std::vector<double>& initFreqs, const std::string& name = "Fixed");
 
   /**
-   * @brief FrequenciesSet useful for homogeneous and stationary models, codon implementation
-   *
-   * This set contains no parameter.
+   * @brief Construction with uniform frequencies on the letters of
+   * the alphabet. The stop codon frequencies are null.
    */
-  class FixedCodonFrequenciesSet :
-    public virtual CodonFrequenciesSet,
-    public AbstractFrequenciesSet
-  {
-  public:
-    FixedCodonFrequenciesSet(const CodonAlphabet* alphabet, const std::vector<double>& initFreqs, const std::string& name = "Fixed");
+  FixedCodonFrequenciesSet(const GeneticCode* gCode, const std::string& name = "Fixed");
 
-    /**
-     * @brief Construction with uniform frequencies on the letters of
-     * the alphabet. The stop codon frequencies are null.
-     */
-    FixedCodonFrequenciesSet(const CodonAlphabet* alphabet, const std::string& name = "Fixed");
+  FixedCodonFrequenciesSet(const FixedCodonFrequenciesSet& fcfs) :
+    AbstractFrequenciesSet(fcfs),
+    pgc_(fcfs.pgc_)
+  {}
+
+  FixedCodonFrequenciesSet& operator=(const FixedCodonFrequenciesSet& fcfs)
+  {
+    AbstractFrequenciesSet::operator=(fcfs);
+    pgc_ = fcfs.pgc_;
+    return *this;
+  }
 
 #ifndef NO_VIRTUAL_COV
-    FixedCodonFrequenciesSet*
+  FixedCodonFrequenciesSet*
 #else
-    Clonable*
+  Clonable*
 #endif
-    clone() const { return new FixedCodonFrequenciesSet(*this); }
+  clone() const { return new FixedCodonFrequenciesSet(*this); }
+
+public:
+  const GeneticCode* getGeneticCode() const { return pgc_; }
 
-  public:
 #ifndef NO_VIRTUAL_COV
-    const CodonAlphabet* getAlphabet() const
-    {
-      return dynamic_cast<const CodonAlphabet*>(AbstractFrequenciesSet::getAlphabet());
-    }
+  const CodonAlphabet* getAlphabet() const
+  {
+    return dynamic_cast<const CodonAlphabet*>(AbstractFrequenciesSet::getAlphabet());
+  }
 #endif
-    /**
-     * @brief the given frequencies are normalized such thaat the sum of
-     * the frequencies on the non-stop codons equals 1.
-     *
-     */
-    void setFrequencies(const std::vector<double>& frequencies);
+  /**
+   * @brief the given frequencies are normalized such thaat the sum of
+   * the frequencies on the non-stop codons equals 1.
+   *
+   */
+  void setFrequencies(const std::vector<double>& frequencies);
+
+protected:
+  void fireParameterChanged(const ParameterList& parameters) {}
+};
+
+/**
+ * @brief FrequenciesSet integrating ProteinFrequenciesSet inside
+ * CodonFrequenciesSet. In this case, FrequencieSet defined inside
+ * each amino acid is parametrized as a FullFrequenciesSet. Hence
+ * there are 61-20=41 parameters in addition of the parameters of the
+ * ProteinFrequenciesSet.
+ *
+ * The parametrization depends on the method used.
+ * Default method is 1 (ie global ratio).
+ *
+ * @see Simplex
+ *
+ */
+
+class FullPerAACodonFrequenciesSet :
+  public virtual CodonFrequenciesSet,
+  public AbstractFrequenciesSet
+{
+private:
+  const GeneticCode* pgc_;
+  std::auto_ptr<ProteinFrequenciesSet> ppfs_;
+
+  /*
+     *@ brief vector of the simplexes, one for each AA
+   *
+   */
+
+  std::vector<Simplex> vS_;
 
-  protected:
-    void fireParameterChanged(const ParameterList& parameters) {}
-  };
+  void updateFrequencies();
 
+public:
   /**
-   * @brief FrequenciesSet integrating ProteinFrequenciesSet inside
-   * CodonFrequenciesSet. In this case, FrequencieSet defined inside
-   * each amino acid is parametrized as a FullFrequenciesSet. Hence
-   * there are 61-20=41 parameters in addition of the parameters of the
-   * ProteinFrequenciesSet.
-   *
+   * @brief Create a new FullPerAACodonFrequenciesSet object.
    *
+   * @param gencode The genetic code to use.
+   * @param ppfs The protein frequencies to use. The codon
+   * frequencies set will own the instance of the protein
+   * frequencies set.
+   * @param method the method used for parametrization.
    */
+  FullPerAACodonFrequenciesSet(const GeneticCode* gencode, ProteinFrequenciesSet* ppfs, unsigned short method = 1);
 
-  class FullPerAACodonFrequenciesSet :
-    public virtual CodonFrequenciesSet,
-    public AbstractFrequenciesSet
-  {
-  
-  private:
-    const GeneticCode* pgc_;
-    ProteinFrequenciesSet* ppfs_;
+  /**
+   * @brief Construction with fixed uniform frequencies on the amino acids.
+   * The stop codon frequencies are null.
+   * @param gencode The genetic code to use.
+   * @param method the method used for parametrization.
+   */
+
+  FullPerAACodonFrequenciesSet(const GeneticCode* gencode, unsigned short method = 1);
+
+  FullPerAACodonFrequenciesSet(const FullPerAACodonFrequenciesSet& ffs);
+
+  FullPerAACodonFrequenciesSet& operator=(const FullPerAACodonFrequenciesSet& ffs);
+
+  virtual ~FullPerAACodonFrequenciesSet() {}
 
-    /*
-     *@ brief vector of the simplexes, one for each AA
-     *
-     */
-  
-    std::vector<Simplex> vS_;
-
-    void updateFrequencies();
-  
-  public:
-  
-    FullPerAACodonFrequenciesSet(const GeneticCode* gencode, const ProteinFrequenciesSet* ppfs);
-
-    /**
-     * @brief Construction with fixed uniform frequencies on the amino acids.
-     * The stop codon frequencies are null.
-     */
-  
-    FullPerAACodonFrequenciesSet(const GeneticCode* gencode);
-
-    FullPerAACodonFrequenciesSet(const FullPerAACodonFrequenciesSet&);
-
-    FullPerAACodonFrequenciesSet& operator=(const FullPerAACodonFrequenciesSet&);
-
-    ~FullPerAACodonFrequenciesSet();
- 
 #ifndef NO_VIRTUAL_COV
-    FullPerAACodonFrequenciesSet*
+  FullPerAACodonFrequenciesSet*
 #else
-    Clonable*
+  Clonable*
 #endif
-    clone() const { return new FullPerAACodonFrequenciesSet(*this); }
+  clone() const { return new FullPerAACodonFrequenciesSet(*this); }
 
-  public:
+public:
 #ifndef NO_VIRTUAL_COV
-    const CodonAlphabet* getAlphabet() const
-    {
-      return dynamic_cast<const CodonAlphabet*>(AbstractFrequenciesSet::getAlphabet());
-    }
+  const CodonAlphabet* getAlphabet() const
+  {
+    return dynamic_cast<const CodonAlphabet*>(AbstractFrequenciesSet::getAlphabet());
+  }
 #endif
-    /**
-     * @brief the given frequencies are normalized such thaat the sum of
-     * the frequencies on the non-stop codons equals 1.
-     *
-     */
-    void setFrequencies(const std::vector<double>& frequencies);
 
-    void setNamespace(const std::string& prefix);
+  const GeneticCode* getGeneticCode() const { return pgc_; }
+
+  /**
+   * @brief the given frequencies are normalized such thaat the sum of
+   * the frequencies on the non-stop codons equals 1.
+   *
+   */
+  void setFrequencies(const std::vector<double>& frequencies);
 
-    const ProteinFrequenciesSet* getProteinFrequenciesSet() const
-    {
-      return ppfs_;
-    }
-    
-  protected:
-    void fireParameterChanged(const ParameterList& parameters);
-  };
+  void setNamespace(const std::string& prefix);
 
+  const ProteinFrequenciesSet* getProteinFrequenciesSet() const
+  {
+    return ppfs_.get();
+  }
 
+  unsigned short getMethod() const
+  {
+    return vS_.size() > 0 ? vS_[0].getMethod() : static_cast<unsigned short>(1);
+  }
+
+protected:
+  void fireParameterChanged(const ParameterList& parameters);
+};
+
+
+/**
+ * @brief the Frequencies in codons are the product of Independent
+ * Frequencies in letters with the frequencies of stop codons set to
+ * zero.
+ *
+ * @author Laurent Guéguen
+ */
+class CodonFromIndependentFrequenciesSet :
+  public virtual CodonFrequenciesSet,
+  public WordFromIndependentFrequenciesSet
+{
+private:
+  // a map associating stop codons numbers with numbers of neighbour non-stop codons
+  std::map<int, Vint> mStopNeigh_;
+
+  unsigned short mgmtStopFreq_;
+
+  const GeneticCode* pgc_;
+
+public:
   /**
-   * @brief the Frequencies in codons are the product of Independent
-   * Frequencies in letters with the frequencies of stop codons set to
-   * zero.
+   * @brief Constructor from a CodonAlphabet* and a vector of different FrequenciesSet*.
+   * Throws an Exception if their lengths do not match.
    *
+   * @param gCode a pointer to the genetic code to use.
+   * @param freqvector a vector of pointers to the phase specific FrequenciesSets
+   * @param name the optional name of the FrequenciesSet (default codon)
+   * @param mgmtStopFreq the optional way the frequencies assigned to the
+   * stop codons are redistributed to the other codons. The
+   * available values are:
+   *  - uniform : each stop frequency is distributed evenly
+   *  - linear : each stop frequency is distributed to the neighbour
+   *     codons (ie 1 substitution away), in proportion to each
+   *     target codon frequency.
+   *  - quadratic (default): each stop frequency is distributed to the
+   *     neighbour codons (ie 1 substitution away), in proportion to
+   *     the square of each target codon frequency.
    *
-   * @author Laurent Guéguen
    */
+  CodonFromIndependentFrequenciesSet(const GeneticCode* gCode, const std::vector<FrequenciesSet*>& freqvector, const std::string& name = "Codon", const std::string& mgmtStopFreq = "quadratic");
 
-  class CodonFromIndependentFrequenciesSet :
-    public virtual CodonFrequenciesSet,
-    public WordFromIndependentFrequenciesSet
-  {
-  private:
-
-    // a map associating stop codons numbers with numbers of neighbour non-stop codons
-    std::map<int, Vint> mStopNeigh_;
-
-    unsigned short mgmtStopFreq_;
-    
-  public:
-    /**
-     * @brief Constructor from a CodonAlphabet* and a vector of different FrequenciesSet*.
-     * Throws an Exception if their lengths do not match.
-     *
-     * @param pCA a pointer to the CodonAlphabet
-     * @param freqvector a vector of pointers to the phase specific FrequenciesSets
-     * @param name the optional name of the FrequenciesSet (default codon)
-     * @param mgmtStopFreq the optional way the frequencies assigned to the
-     * stop codons are redistributed to the other codons. The
-     * available values are:
-     *  - uniform : each stop frequency is distributed evenly
-     *  - linear : each stop frequency is distributed to the neighbour
-     *     codons (ie 1 substitution away), in proportion to each
-     *     target codon frequency.
-     *  - quadratic (default): each stop frequency is distributed to the
-     *     neighbour codons (ie 1 substitution away), in proportion to
-     *     the square of each target codon frequency.
-     *
-     */
-    CodonFromIndependentFrequenciesSet(const CodonAlphabet* pCA, const std::vector<FrequenciesSet*>& freqvector, const std::string& name = "Codon", const std::string& mgmtStopFreq = "quadratic");
-  
-    CodonFromIndependentFrequenciesSet(const CodonFromIndependentFrequenciesSet& iwfs);
-
-    ~CodonFromIndependentFrequenciesSet(){};
-  
-    CodonFromIndependentFrequenciesSet& operator=(const CodonFromIndependentFrequenciesSet& iwfs);
-  
-    CodonFromIndependentFrequenciesSet* clone() const { return new CodonFromIndependentFrequenciesSet(*this); }
-
-    const CodonAlphabet* getAlphabet() const;
-  
-    /*
-     *@ brief Update the frequencies given the parameters.
-     *
-     */
-
-    void updateFrequencies();
-  };
+  CodonFromIndependentFrequenciesSet(const CodonFromIndependentFrequenciesSet& iwfs);
+
+  virtual ~CodonFromIndependentFrequenciesSet(){}
 
+  CodonFromIndependentFrequenciesSet& operator=(const CodonFromIndependentFrequenciesSet& iwfs);
 
+  CodonFromIndependentFrequenciesSet* clone() const { return new CodonFromIndependentFrequenciesSet(*this); }
+
+  const CodonAlphabet* getAlphabet() const;
+
+  const GeneticCode* getGeneticCode() const { return pgc_; }
+
+  /**
+   * @ brief Update the frequencies given the parameters.
+   */
+  void updateFrequencies();
+};
+
+
+/**
+ * @brief the Frequencies in codons are the product of the frequencies
+ * for a unique FrequenciesSet in letters, with the frequencies of
+ * stop codons set to zero.
+ *
+ * @author Laurent Guéguen
+ */
+
+class CodonFromUniqueFrequenciesSet :
+  public virtual CodonFrequenciesSet,
+  public WordFromUniqueFrequenciesSet
+{
+private:
+  // a map associating stop codons numbers with numbers of neighbour non-stop codons
+  std::map<int, Vint> mStopNeigh_;
+
+  unsigned short mgmtStopFreq_;
+
+  const GeneticCode* pgc_;
+
+public:
   /**
-   * @brief the Frequencies in codons are the product of the frequencies
-   * for a unique FrequenciesSet in letters, with the frequencies of
-   * stop codons set to zero.
+   * @brief Constructor from a CodonAlphabet* and a FrequenciesSet*
+   *  repeated three times.
    *
-   * @author Laurent Guéguen
+   * @param gCode a pointer to a genetic code.
+   * @param pfreq a pointer to the nucleotidic FrequenciesSet
+   * @param name the optional name of the FrequenciesSet (default codon)
+   * @param mgmtStopFreq the optional way the frequencies assigned to the
+   * stop codons are redistributed to the other codons. The
+   * available values are:
+   *  - uniform : each stop frequency is distributed evenly
+   *  - linear : each stop frequency is distributed to the neighbour
+   *      codons (ie 1 substitution away), in proportion to each
+   *      target codon frequency.
+   *  - quadratic (default): each stop frequency is distributed to the
+   *      neighbour codons (ie 1 substitution away), in proportion to
+   *      the square of each target codon frequency.
    */
+  CodonFromUniqueFrequenciesSet(
+    const GeneticCode* gCode,
+    FrequenciesSet* pfreq,
+    const std::string& name = "Codon",
+    const std::string& mgmtStopFreq = "quadratic");
 
-  class CodonFromUniqueFrequenciesSet :
-    public virtual CodonFrequenciesSet,
-    public WordFromUniqueFrequenciesSet
-  {
-  private:
-
-    // a map associating stop codons numbers with numbers of neighbour non-stop codons
-    std::map<int, Vint> mStopNeigh_;
-
-    unsigned short mgmtStopFreq_;
-    
-  public:
-    /**
-     * @brief Constructor from a CodonAlphabet* and a FrequenciesSet*
-     *  repeated three times.
-     *
-     * @param pCA a pointer to the CodonAlphabet
-     * @param pfreq a pointer to the nucleotidic FrequenciesSet
-     * @param name the optional name of the FrequenciesSet (default codon)
-     * @param mgmtStopFreq the optional way the frequencies assigned to the
-     * stop codons are redistributed to the other codons. The
-     * available values are:
-     *  - uniform : each stop frequency is distributed evenly
-     *  - linear : each stop frequency is distributed to the neighbour
-     *      codons (ie 1 substitution away), in proportion to each
-     *      target codon frequency.
-     *  - quadratic (default): each stop frequency is distributed to the
-     *      neighbour codons (ie 1 substitution away), in proportion to
-     *      the square of each target codon frequency.
-     *
-     */
-
-    CodonFromUniqueFrequenciesSet(const CodonAlphabet* pCA, FrequenciesSet* pfreq, const std::string& name = "Codon", const std::string& mgmtStopFreq = "quadratic");
-  
-    CodonFromUniqueFrequenciesSet(const CodonFromUniqueFrequenciesSet& iwfs);
-  
-    ~CodonFromUniqueFrequenciesSet(){};
-  
-    CodonFromUniqueFrequenciesSet& operator=(const CodonFromUniqueFrequenciesSet& iwfs);
-  
-    CodonFromUniqueFrequenciesSet* clone() const { return new CodonFromUniqueFrequenciesSet(*this); }
-  
-    const CodonAlphabet* getAlphabet() const;
-
-    /*
-     *@ brief Update the frequencies given the parameters.
-     *
-     */
-
-    void updateFrequencies();
-  };
+  CodonFromUniqueFrequenciesSet(const CodonFromUniqueFrequenciesSet& iwfs);
 
+  virtual ~CodonFromUniqueFrequenciesSet() {}
 
-} // end of namespace bpp.
+  CodonFromUniqueFrequenciesSet& operator=(const CodonFromUniqueFrequenciesSet& iwfs);
 
-#endif // _CODONFREQUENCIESSET_H_
+  CodonFromUniqueFrequenciesSet* clone() const { return new CodonFromUniqueFrequenciesSet(*this); }
+
+  const CodonAlphabet* getAlphabet() const;
 
+  const GeneticCode* getGeneticCode() const { return pgc_; }
 
+  /**
+   * @brief Update the frequencies given the parameters.
+   *
+   */
+  void updateFrequencies();
+};
+} // end of namespace bpp.
+
+#endif // _CODONFREQUENCIESSET_H_
diff --git a/src/Bpp/Phyl/Model/FrequenciesSet/FrequenciesSet.cpp b/src/Bpp/Phyl/Model/FrequenciesSet/FrequenciesSet.cpp
index 57b8d69..3584e5e 100644
--- a/src/Bpp/Phyl/Model/FrequenciesSet/FrequenciesSet.cpp
+++ b/src/Bpp/Phyl/Model/FrequenciesSet/FrequenciesSet.cpp
@@ -55,127 +55,108 @@ IntervalConstraint FrequenciesSet::FREQUENCE_CONSTRAINT_SMALL(NumConstants::SMAL
 // AbstractFrequenciesSet
 
 
-void AbstractFrequenciesSet::setFrequenciesFromMap(const map<int, double>& frequencies)
+void AbstractFrequenciesSet::setFrequenciesFromAlphabetStatesFrequencies(const map<int, double>& frequencies)
 {
-  size_t s = getAlphabet()->getSize();
+  size_t s = stateMap_->getNumberOfModelStates();
   vector<double> freq(s);
   double x = 0;
-  for (size_t i = 0; i < s; i++)
+  for (size_t i = 0; i < s; ++i)
   {
-    map<int, double>::const_iterator it = frequencies.find(static_cast<int>(i));
+    map<int, double>::const_iterator it = frequencies.find(stateMap_->getAlphabetStateAsInt(i));
     if (it != frequencies.end())
       freq[i] = it->second;
     else
       freq[i] = 0;
     x += freq[i];
   }
-  for (size_t i = 0; i < s; i++)
+  for (size_t i = 0; i < s; ++i)
   {
     freq[i] /= x;
   }
   setFrequencies(freq);
 }
 
+const std::map<int, double> AbstractFrequenciesSet::getAlphabetStatesFrequencies() const
+{
+  map<int, double> fmap;
+  for (size_t i = 0; i < stateMap_->getNumberOfModelStates(); ++i) {
+    fmap[stateMap_->getAlphabetStateAsInt(i)] += freq_[i];
+  }
+  return fmap;
+}
+
 // ////////////////////////////
 // FullFrequenciesSet
 
-FullFrequenciesSet::FullFrequenciesSet(const Alphabet* alphabet, bool allowNullFreqs, const string& name) :
-  AbstractFrequenciesSet(alphabet->getSize(), alphabet, "Full.", name)
+FullFrequenciesSet::FullFrequenciesSet(StateMap* stateMap, bool allowNullFreqs, unsigned short method, const string& name) :
+  AbstractFrequenciesSet(stateMap, "Full.", name),
+  sFreq_(stateMap->getNumberOfModelStates(), method, allowNullFreqs, "Full.")
 {
-  size_t size = alphabet->getSize();
+  vector<double> vd;
+  double r = 1. / static_cast<double>(stateMap->getNumberOfModelStates());
 
-  for (size_t i = 0; i < alphabet->getSize() - 1; i++)
-  {
-    addParameter_(new Parameter(
-      "Full.theta" + TextTools::toString(i + 1),
-      1. / static_cast<double>(size - i),
-      allowNullFreqs ?
-      &Parameter::PROP_CONSTRAINT_IN :
-      &FrequenciesSet::FREQUENCE_CONSTRAINT_SMALL));
-    getFreq_(i) = 1. / static_cast<double>(size);
-  }
-  size_t i = alphabet->getSize() - 1;
-  getFreq_(i) = 1. / static_cast<double>(size);
+  for (size_t i = 0; i < stateMap->getNumberOfModelStates(); i++)
+    vd.push_back(r);
+
+  sFreq_.setFrequencies(vd);
+  addParameters_(sFreq_.getParameters());
+  updateFreq_();
 }
 
-FullFrequenciesSet::FullFrequenciesSet(const Alphabet* alphabet, const vector<double>& initFreqs, bool allowNullFreqs, const string& name) :
-  AbstractFrequenciesSet(alphabet->getSize(), alphabet, "Full.", name)
+FullFrequenciesSet::FullFrequenciesSet(StateMap* stateMap, const vector<double>& initFreqs, bool allowNullFreqs, unsigned short method, const string& name) :
+  AbstractFrequenciesSet(stateMap, "Full.", name),
+  sFreq_(stateMap->getNumberOfModelStates(), method, allowNullFreqs, "Full.")
 {
-  if (initFreqs.size() != alphabet->getSize())
-    throw Exception("FullFrequenciesSet(constructor). There must be " + TextTools::toString(alphabet->getSize()) + " frequencies.");
-  double sum = VectorTools::sum(initFreqs);
-  if (fabs(1. - sum) > NumConstants::SMALL())
-  {
-    throw Exception("Frequencies must equal 1 (sum = " + TextTools::toString(sum) + ").");
-  }
-
-  double y = 1;
-  for (size_t i = 0; i < alphabet->getSize() - 1; i++)
-  {
-    addParameter_(new Parameter(
-      "Full.theta" + TextTools::toString(i + 1),
-      initFreqs[i] / y,
-      allowNullFreqs ?
-      &Parameter::PROP_CONSTRAINT_IN :
-      &FrequenciesSet::FREQUENCE_CONSTRAINT_SMALL));
-    getFreq_(i) = initFreqs[i];
-    y -= initFreqs[i];
-  }
-  size_t i = alphabet->getSize() - 1;
-  getFreq_(i) = initFreqs[i];
+  sFreq_.setFrequencies(initFreqs);
+  addParameters_(sFreq_.getParameters());
+  updateFreq_();
 }
 
 void FullFrequenciesSet::setFrequencies(const vector<double>& frequencies) 
 {
-  const Alphabet* alphabet = getAlphabet();
-  if (frequencies.size() != getNumberOfFrequencies())
-    throw DimensionException("FullFrequenciesSet::setFrequencies. Invalid number of frequencies.", frequencies.size(), getNumberOfFrequencies());
-
-  if (fabs(1. - VectorTools::sum(frequencies)) >= NumConstants::SMALL())
-    throw Exception("FullFrequenciesSet::setFrequencies. Frequencies do not sum to 1 : " + TextTools::toString(VectorTools::sum(frequencies)));
+  
+  sFreq_.setFrequencies(frequencies);
+  setParametersValues(sFreq_.getParameters()); 
 
-  setFrequencies_(frequencies);
+  updateFreq_();
+}
 
-  double y = 1;
-  for (size_t i = 0; i < alphabet->getSize() - 1; i++)
-  {
-    getParameter_("theta" + TextTools::toString(i + 1)).setValue(frequencies[i] / y);
-    y -= frequencies[i];
-  }
+void FullFrequenciesSet::setNamespace(const std::string& nameSpace)
+{
+  sFreq_.setNamespace(nameSpace);
+  AbstractFrequenciesSet::setNamespace(nameSpace);
 }
 
 void FullFrequenciesSet::fireParameterChanged(const ParameterList& parameters)
 {
-  const Alphabet* alphabet = getAlphabet();
-  double y = 1;
-  size_t i;
-  for (i = 0; i < alphabet->getSize() - 1; i++)
-  {
-    getFreq_(i) = getParameter_("theta" + TextTools::toString(i + 1)).getValue() * y;
-    y *= 1 - getParameter_("theta" + TextTools::toString(i + 1)).getValue();
-  }
-
-  i = alphabet->getSize() - 1;
-  getFreq_(i) = y;
+  sFreq_.matchParametersValues(parameters);
+  updateFreq_();
 }
 
+void FullFrequenciesSet::updateFreq_()
+{
+  for (size_t i = 0; i < getAlphabet()->getSize(); i++)
+    getFreq_(i)=sFreq_.prob(i);
+}
 
 // ///////////////////////////////////////////
 // / FixedFrequenciesSet
 
-FixedFrequenciesSet::FixedFrequenciesSet(const Alphabet* alphabet, const vector<double>& initFreqs, const string& name) :
-  AbstractFrequenciesSet(initFreqs.size(), alphabet, "Fixed.", name)
+FixedFrequenciesSet::FixedFrequenciesSet(StateMap* stateMap, const vector<double>& initFreqs, const string& name) throw (Exception) :
+  AbstractFrequenciesSet(stateMap, "Fixed.", name)
 {
+  if (stateMap->getNumberOfModelStates() != initFreqs.size())
+    throw Exception("FixedFrequenciesSet::constructor. size of init vector does not match the number of states in the model.");
   setFrequencies(initFreqs);
 }
 
-FixedFrequenciesSet::FixedFrequenciesSet(const Alphabet* alphabet, size_t nFreqs, const string& name) :
-  AbstractFrequenciesSet(nFreqs, alphabet, "Fixed.", name)
+FixedFrequenciesSet::FixedFrequenciesSet(StateMap* stateMap, const string& name) :
+  AbstractFrequenciesSet(stateMap, "Fixed.", name)
 {
-  size_t size = nFreqs;
-  for (size_t i = 0; i < nFreqs; ++i)
+  size_t n = stateMap->getNumberOfModelStates();
+  for (size_t i = 0; i < n; ++i)
   {
-    getFreq_(i) = 1. / static_cast<double>(size);
+    getFreq_(i) = 1. / static_cast<double>(n);
   }
 }
 
@@ -194,7 +175,7 @@ void FixedFrequenciesSet::setFrequencies(const vector<double>& frequencies)
 }
 
 MarkovModulatedFrequenciesSet::MarkovModulatedFrequenciesSet(FrequenciesSet* freqSet, const std::vector<double>& rateFreqs) :
-  AbstractFrequenciesSet(freqSet->getAlphabet()->getSize() * rateFreqs.size(), freqSet->getAlphabet(), "MarkovModulated.", "MarkovModulated." + freqSet->getName()),
+  AbstractFrequenciesSet(new MarkovModulatedStateMap(freqSet->getStateMap(), static_cast<unsigned int>(rateFreqs.size())), "MarkovModulated.", "MarkovModulated." + freqSet->getName()),
   freqSet_(freqSet),
   rateFreqs_(rateFreqs)
 {
diff --git a/src/Bpp/Phyl/Model/FrequenciesSet/FrequenciesSet.h b/src/Bpp/Phyl/Model/FrequenciesSet/FrequenciesSet.h
index f43de46..6c27d54 100644
--- a/src/Bpp/Phyl/Model/FrequenciesSet/FrequenciesSet.h
+++ b/src/Bpp/Phyl/Model/FrequenciesSet/FrequenciesSet.h
@@ -41,15 +41,23 @@
 #ifndef _FREQUENCIESSET_H_
 #define _FREQUENCIESSET_H_
 
+#include "../StateMap.h"
+
+// From bpp-core:
 #include <Bpp/Numeric/Parametrizable.h>
 #include <Bpp/Numeric/AbstractParametrizable.h>
-#include <Bpp/Seq/Alphabet/Alphabet.h>
 #include <Bpp/Numeric/VectorTools.h>
+#include <Bpp/Numeric/Prob/Simplex.h>
+
+// From bpp-seq:
+#include <Bpp/Seq/Alphabet/Alphabet.h>
 
 namespace bpp
 {
 /**
  * @brief Parametrize a set of state frequencies.
+ *
+ * Frequencies are ordered according to alphabet states.
  */
 class FrequenciesSet :
   public virtual Parametrizable
@@ -66,9 +74,19 @@ public:
   virtual const Alphabet* getAlphabet() const = 0;
 
   /**
+   * @return The mapping of model states with alphabet states.
+   */
+  virtual const StateMap& getStateMap() const = 0;
+
+  /**
    * @return The frequencies values of the set.
    */
-  virtual const std::vector<double>& getFrequencies() const = 0;
+  virtual const std::vector<double> getFrequencies() const = 0;
+
+  /**
+   * @return The frequencies of each alphabet states according to this model.
+   */
+  virtual const std::map<int, double> getAlphabetStatesFrequencies() const = 0;
 
   /**
    * @brief Set the parameters in order to match a given set of frequencies.
@@ -86,13 +104,12 @@ public:
    *
    * @param frequencies The set of frequencies to match.
    */
-  virtual void setFrequenciesFromMap(const std::map<int, double>& frequencies) = 0;
+  virtual void setFrequenciesFromAlphabetStatesFrequencies(const std::map<int, double>& frequencies) = 0;
 
   virtual std::string getName() const = 0;
 
   /**
-   * @return The number of frequencies in the set. In most cases this will correspond to the size of the alphabet,
-   * but it needs not be.
+   * @return The number of frequencies in the set. This is equivalent to getStateMap().getNumberOfModelStates().
    */
   virtual size_t getNumberOfFrequencies() const = 0;
 
@@ -111,14 +128,16 @@ class AbstractFrequenciesSet :
 {
 private:
   const Alphabet* alphabet_;
+  std::auto_ptr<StateMap> stateMap_;
   std::vector<double> freq_;
   std::string name_;
 
 public:
-  AbstractFrequenciesSet(size_t n, const Alphabet* alphabet, const std::string& prefix, const std::string& name) :
+  AbstractFrequenciesSet(StateMap* stateMap, const std::string& prefix, const std::string& name) :
     AbstractParametrizable(prefix),
-    alphabet_(alphabet),
-    freq_(n),
+    alphabet_(stateMap->getAlphabet()),
+    stateMap_(stateMap),
+    freq_(stateMap->getNumberOfModelStates()),
     name_(name)
   {}
 
@@ -132,6 +151,7 @@ public:
   AbstractFrequenciesSet(const AbstractFrequenciesSet& af) :
     AbstractParametrizable(af),
     alphabet_(af.alphabet_),
+    stateMap_(af.stateMap_->clone()),
     freq_(af.freq_),
     name_(af.name_)
   {}
@@ -140,6 +160,7 @@ public:
   {
     AbstractParametrizable::operator=(af);
     alphabet_ = af.alphabet_;
+    stateMap_.reset(af.stateMap_->clone());
     freq_ = af.freq_;
     name_ = af.name_;
     return *this;
@@ -148,14 +169,35 @@ public:
 public:
   const Alphabet* getAlphabet() const { return alphabet_; }
 
-  const std::vector<double>& getFrequencies() const { return freq_; }
+  const StateMap& getStateMap() const { return *stateMap_; }
 
-  void setFrequenciesFromMap(const std::map<int, double>& frequencies);
+  const std::vector<double> getFrequencies() const { return freq_; }
+  
+  const std::map<int, double> getAlphabetStatesFrequencies() const;
+
+  /**
+   * @brief Set the Frequencies from the one of the map which keys
+   *  match with a letter of the Alphabet.
+   *  The frequencies are normalized so that the matching values sum 1.
+   *
+   * In this implementation, all model states with the same alphabet state are given the same frequency.
+   * 
+   * @param frequencies The set of frequencies to match.
+   */
+  void setFrequenciesFromAlphabetStatesFrequencies(const std::map<int, double>& frequencies);
 
   size_t getNumberOfFrequencies() const { return freq_.size(); }
 
   std::string getName() const { return(name_); }
 
+  void normalize()
+  {
+    double x = 0;
+    for (size_t i = 0; i < freq_.size(); i++)
+      x += freq_[i];
+    freq_ /= x;
+  }
+   
 protected:
   std::vector<double>& getFrequencies_() { return freq_; }
   double& getFreq_(size_t i) { return freq_[i]; }
@@ -166,26 +208,46 @@ protected:
 /**
  * @brief A generic FrequenciesSet allowing for the estimation of all frequencies.
  *
- * The FrequenciesSet has hence n-1 parameters, where n is the size of the input alphabet.
+ * The FrequenciesSet has hence n-1 parameters, where n is the size of
+ * the input alphabet.
+ *
+ * The parametrization depends on the method used.
+ * Default method is 1 (ie global ratio).
+ *
+ * @see Simplex
  */
+
 class FullFrequenciesSet :
   public AbstractFrequenciesSet
 {
+private:
+  /**
+   * @brief Simplex to handle the probabilities and the parameters.
+   */
+  Simplex sFreq_;
+  
 public:
   /**
-   * @brief Construction with uniform frequencies on the letters of
+   * @brief Construction with uniform frequencies on the states of
    * the alphabet.
    */
-  FullFrequenciesSet(const Alphabet* alphabet, bool allowNullFreqs = false, const std::string& name = "Full");
-  FullFrequenciesSet(const Alphabet* alphabet, const std::vector<double>& initFreqs, bool allowNullFreqs = false, const std::string& name = "Full");
+  FullFrequenciesSet(StateMap* stateMap, bool allowNullFreqs = false, unsigned short method = 1, const std::string& name = "Full.");
+  FullFrequenciesSet(StateMap* stateMap, const std::vector<double>& initFreqs, bool allowNullFreqs = false, unsigned short method = 1, const std::string& name = "Full.");
 
   FullFrequenciesSet* clone() const { return new FullFrequenciesSet(*this); }
 
 public:
   void setFrequencies(const std::vector<double>& frequencies);
 
+  unsigned short getMethod() const { return sFreq_.getMethod();}
+
+  void setNamespace(const std::string& nameSpace);
+  
 protected:
   void fireParameterChanged(const ParameterList& parameters);
+
+private:
+  void updateFreq_();
 };
 
 /**
@@ -238,12 +300,6 @@ public:
 
   const FrequenciesSet& getStatesFrequenciesSet() const { return *freqSet_; }
 
-  void setNamespace(const std::string& prefix)
-  {
-   AbstractFrequenciesSet::setNamespace(prefix);
-   freqSet_->setNamespace(prefix + freqSet_->getNamespace());
-  }
-
 };
 
 
@@ -258,24 +314,22 @@ class FixedFrequenciesSet :
 public:
 
   /**
-   * @brief Construction with uniform frequencies on the letters of
-   * the alphabet.
+   * @brief Construction with user-defined frequencies on the states of the model.
    *
-   * @param alphabet The alphabet for wich this frequencies set should be build.
-   * @param initFreqs The frequencies to use. The vector will determine the number of frequencies.
+   * @param stateMap The model states for which frequencies should be built.
+   * @param initFreqs The frequencies to use. The size of the vector should match the number of model states.
    * @param name The name of the set.
+   * @throw Exception In case the number of frequencies does not match the number of model states.
    */
-  FixedFrequenciesSet(const Alphabet* alphabet, const std::vector<double>& initFreqs, const std::string& name = "Fixed");
+  FixedFrequenciesSet(StateMap* stateMap, const std::vector<double>& initFreqs, const std::string& name = "Fixed") throw (Exception);
 
   /**
-   * @brief Construction with uniform frequencies on the letters of
-   * the alphabet.
+   * @brief Construction with uniform frequencies on the states of the model.
    *
-   * @param alphabet The alphabet for wich this frequencies set should be build.
-   * @param nFreqs The number of frequencies.
+   * @param stateMap The model states for which frequencies should be built.
    * @param name The name of the set.
    */
-  FixedFrequenciesSet(const Alphabet* alphabet, size_t nFreqs, const std::string& name = "Fixed");
+  FixedFrequenciesSet(StateMap* stateMap, const std::string& name = "Fixed");
 
   FixedFrequenciesSet* clone() const { return new FixedFrequenciesSet(*this); }
 
diff --git a/src/Bpp/Phyl/Model/FrequenciesSet/MvaFrequenciesSet.cpp b/src/Bpp/Phyl/Model/FrequenciesSet/MvaFrequenciesSet.cpp
index bcbec05..785ded9 100644
--- a/src/Bpp/Phyl/Model/FrequenciesSet/MvaFrequenciesSet.cpp
+++ b/src/Bpp/Phyl/Model/FrequenciesSet/MvaFrequenciesSet.cpp
@@ -38,19 +38,13 @@
  */
 #include "MvaFrequenciesSet.h"
 
-// #include "../Protein.all"
-
-// #include <Bpp/Numeric/NumConstants.h>
-// #include <Bpp/Numeric/VectorTools.h>
-// #include <Bpp/Numeric/Matrix/MatrixTools.h>
-
 using namespace bpp;
 
 #include <cmath>
 using namespace std;
 
 MvaFrequenciesSet::MvaFrequenciesSet(const ProteicAlphabet* alpha) :
-  AbstractFrequenciesSet(20, alpha, "MVA.", "MVAprotein"),
+  AbstractFrequenciesSet(new CanonicalStateMap(alpha, false), "MVA.", "MVAprotein"),
   tPpalAxes_(),
   rowCoords_(),
   nbrOfAxes_(0),
@@ -126,7 +120,7 @@ void MvaFrequenciesSet::updateFrequencies() throw (Exception)
   if (norm == true)
   {
     double s = VectorTools::sum(getFrequencies());
-    for (int i = 0; i < 20; i++)
+    for (size_t i = 0; i < 20; ++i)
     {
       getFreq_(i) = getFreq_(i) / s;
     }
diff --git a/src/Bpp/Phyl/Model/FrequenciesSet/NucleotideFrequenciesSet.cpp b/src/Bpp/Phyl/Model/FrequenciesSet/NucleotideFrequenciesSet.cpp
index 0faac35..3b66fe3 100644
--- a/src/Bpp/Phyl/Model/FrequenciesSet/NucleotideFrequenciesSet.cpp
+++ b/src/Bpp/Phyl/Model/FrequenciesSet/NucleotideFrequenciesSet.cpp
@@ -54,7 +54,7 @@ using namespace std;
 FullNucleotideFrequenciesSet::FullNucleotideFrequenciesSet(
   const NucleicAlphabet* alphabet, bool allowNullFreqs,
   const string& name) :
-  AbstractFrequenciesSet(4, alphabet, "Full.", name)
+  AbstractFrequenciesSet(new CanonicalStateMap(alphabet, false), "Full.", name)
 {
   addParameter_(new Parameter(
     "Full.theta", 0.5,
@@ -76,7 +76,7 @@ FullNucleotideFrequenciesSet::FullNucleotideFrequenciesSet(
 FullNucleotideFrequenciesSet::FullNucleotideFrequenciesSet(
   const NucleicAlphabet* alphabet, double theta, double theta1, double theta2,
   bool allowNullFreqs, const string& name) :
-  AbstractFrequenciesSet(4, alphabet, "Full.", name)
+  AbstractFrequenciesSet(new CanonicalStateMap(alphabet, false), "Full.", name)
 {
   addParameter_(new Parameter(
     "Full.theta",
diff --git a/src/Bpp/Phyl/Model/FrequenciesSet/NucleotideFrequenciesSet.h b/src/Bpp/Phyl/Model/FrequenciesSet/NucleotideFrequenciesSet.h
index 59b3ee1..4285183 100644
--- a/src/Bpp/Phyl/Model/FrequenciesSet/NucleotideFrequenciesSet.h
+++ b/src/Bpp/Phyl/Model/FrequenciesSet/NucleotideFrequenciesSet.h
@@ -69,14 +69,14 @@ class GCFrequenciesSet :
 {
 public:
   GCFrequenciesSet(const NucleicAlphabet* alphabet) :
-    AbstractFrequenciesSet(4, alphabet, "GC.", "GC")
+    AbstractFrequenciesSet(new CanonicalStateMap(alphabet, false), "GC.", "GC")
   {
     addParameter_(new Parameter("GC.theta", 0.5, &Parameter::PROP_CONSTRAINT_IN));
     getFreq_(0) = getFreq_(1) = getFreq_(2) = getFreq_(3) = 0.25;
   }
 
   GCFrequenciesSet(const NucleicAlphabet* alphabet, double theta) :
-    AbstractFrequenciesSet(4, alphabet, "GC.", "GC")
+    AbstractFrequenciesSet(new CanonicalStateMap(alphabet, false), "GC.", "GC")
   {
     addParameter_(new Parameter("GC.theta", theta, &Parameter::PROP_CONSTRAINT_IN));
     getFreq_(0) = getFreq_(3) = (1. - theta) / 2.;
@@ -124,9 +124,7 @@ protected:
  * \f]
  *
  * with \f$\pi_x\f$ the frequency of nucleotide \f$x\f$.
- *
  */
-  
 class FullNucleotideFrequenciesSet :
   public virtual NucleotideFrequenciesSet,
   public AbstractFrequenciesSet
@@ -169,14 +167,14 @@ class FixedNucleotideFrequenciesSet :
 {
 public:
   FixedNucleotideFrequenciesSet(const NucleicAlphabet* alphabet, const std::vector<double>& initFreqs, const std::string& name = "Fixed") :
-    FixedFrequenciesSet(alphabet, initFreqs, name) {}
+    FixedFrequenciesSet(new CanonicalStateMap(alphabet, false), initFreqs, name) {}
 
   /**
    * @brief Construction with uniform frequencies on the letters of
    * the alphabet.
    */
   FixedNucleotideFrequenciesSet(const NucleicAlphabet* alphabet, const std::string& name = "Fixed") :
-    FixedFrequenciesSet(alphabet, alphabet->getSize(), name) {}
+    FixedFrequenciesSet(new CanonicalStateMap(alphabet, false), name) {}
 
 #ifndef NO_VIRTUAL_COV
   FixedNucleotideFrequenciesSet*
diff --git a/src/Bpp/Phyl/Model/FrequenciesSet/ProteinFrequenciesSet.h b/src/Bpp/Phyl/Model/FrequenciesSet/ProteinFrequenciesSet.h
index 533facb..73423c7 100644
--- a/src/Bpp/Phyl/Model/FrequenciesSet/ProteinFrequenciesSet.h
+++ b/src/Bpp/Phyl/Model/FrequenciesSet/ProteinFrequenciesSet.h
@@ -61,20 +61,25 @@ public:
 };
 
 /**
- * @brief Protein FrequenciesSet using 19 independent parameters to modelize the 20 frequencies.
+ * @brief Protein FrequenciesSet using 19 independent parameters to
+ * model the 20 frequencies.
  *
- * The parameters are called @f$ \theta_{i \in 1..19} @f$, and are initialized so that all frequencies are equal to  0.005, that is
- * @f[ \theta_i = \frac{0.05}{0.956{i-1}},\quad i = 1..19 @f] or according to a user-specified vector of initial values.
+ * The parameters are called @f$ \theta_{i \in 1..19} @f$, and are
+ * initialized so that all frequencies are equal to 0.005. The
+ * parametrization depends on the method used. Default
+ * method is 1 (ie global ratio).
+ *
+ * @see Simplex
  */
 class FullProteinFrequenciesSet :
   public virtual ProteinFrequenciesSet,
   public FullFrequenciesSet
 {
 public:
-  FullProteinFrequenciesSet(const ProteicAlphabet* alphabet, bool allowNullFreqs = false, const std::string& name = "Full") :
-    FullFrequenciesSet(alphabet, allowNullFreqs, name) {}
-  FullProteinFrequenciesSet(const ProteicAlphabet* alphabet, const std::vector<double>& initFreqs, bool allowNullFreqs = false, const std::string& name = "Full") :
-    FullFrequenciesSet(alphabet, initFreqs, allowNullFreqs, name) {}
+  FullProteinFrequenciesSet(const ProteicAlphabet* alphabet, bool allowNullFreqs = false, unsigned short method = 1, const std::string& name = "Full") :
+    FullFrequenciesSet(new CanonicalStateMap(alphabet, false), allowNullFreqs, method, name) {}
+  FullProteinFrequenciesSet(const ProteicAlphabet* alphabet, const std::vector<double>& initFreqs, bool allowNullFreqs = false, unsigned short method = 1, const std::string& name = "Full") :
+    FullFrequenciesSet(new CanonicalStateMap(alphabet, false), initFreqs, allowNullFreqs, method, name) {}
 
 #ifndef NO_VIRTUAL_COV
   FullProteinFrequenciesSet*
@@ -103,14 +108,14 @@ class FixedProteinFrequenciesSet :
 {
 public:
   FixedProteinFrequenciesSet(const ProteicAlphabet* alphabet, const std::vector<double>& initFreqs, const std::string& name = "Fixed") :
-    FixedFrequenciesSet(alphabet, initFreqs, name) {}
+    FixedFrequenciesSet(new CanonicalStateMap(alphabet, false), initFreqs, name) {}
 
   /**
    * @brief Construction with uniform frequencies on the letters of
    * the alphabet.
    */
   FixedProteinFrequenciesSet(const ProteicAlphabet* alphabet, const std::string& name = "Fixed") :
-    FixedFrequenciesSet(alphabet, alphabet->getSize(), name) {}
+    FixedFrequenciesSet(new CanonicalStateMap(alphabet, false), name) {}
 
 #ifndef NO_VIRTUAL_COV
   FixedProteinFrequenciesSet*
diff --git a/src/Bpp/Phyl/Model/FrequenciesSet/WordFrequenciesSet.cpp b/src/Bpp/Phyl/Model/FrequenciesSet/WordFrequenciesSet.cpp
index 9499c70..23aa12f 100644
--- a/src/Bpp/Phyl/Model/FrequenciesSet/WordFrequenciesSet.cpp
+++ b/src/Bpp/Phyl/Model/FrequenciesSet/WordFrequenciesSet.cpp
@@ -58,8 +58,8 @@ size_t AbstractWordFrequenciesSet::getSizeFromVector(const std::vector<Frequenci
   return s;
 }
 
-AbstractWordFrequenciesSet::AbstractWordFrequenciesSet(size_t size, const Alphabet* palph, const string& prefix, const string& name) :
-  AbstractFrequenciesSet(size, palph, prefix, name)
+AbstractWordFrequenciesSet::AbstractWordFrequenciesSet(StateMap* stateMap, const string& prefix, const string& name) :
+  AbstractFrequenciesSet(stateMap, prefix, name)
 {}
 
 size_t AbstractWordFrequenciesSet::getLength() const
@@ -75,10 +75,10 @@ AbstractWordFrequenciesSet::~AbstractWordFrequenciesSet()
 
 
 WordFromIndependentFrequenciesSet::WordFromIndependentFrequenciesSet(
-                                                                     const WordAlphabet* pWA,
-                                                                     const std::vector<FrequenciesSet*>& freqVector,
-                                                                     const string& prefix, const string& name) :
-  AbstractWordFrequenciesSet(pWA->getSize(), pWA, prefix, name),
+    const WordAlphabet* pWA,
+    const std::vector<FrequenciesSet*>& freqVector,
+    const string& prefix, const string& name) :
+  AbstractWordFrequenciesSet(new CanonicalStateMap(pWA, false), prefix, name),
   vFreq_(),
   vNestedPrefix_()
 {
@@ -158,7 +158,7 @@ void WordFromIndependentFrequenciesSet::updateFrequencies()
 {
   size_t l = vFreq_.size();
   size_t s = getAlphabet()->getSize();
-  vector<double> f[l];
+  vector< vector<double> >f(l);
 
   size_t i, p, t, i2;
 
@@ -193,8 +193,7 @@ void WordFromIndependentFrequenciesSet::setFrequencies(const vector<double>& fre
   if (fabs(1. - sum) > 0.000001)
     throw Exception("WordFromIndependentFrequenciesSet::setFrequencies. Frequencies must equal 1 (sum = " + TextTools::toString(sum) + ").");
 
-  size_t d, i, j, s, l = vFreq_.size();
-  int k;
+  size_t d, i, j, k, s, l = vFreq_.size();
   vector<double> freq;
 
   d = size;
@@ -207,7 +206,7 @@ void WordFromIndependentFrequenciesSet::setFrequencies(const vector<double>& fre
     {
       freq[j] = 0;
     }
-    for (k = 0; k < (int)size; k++)
+    for (k = 0; k < size; k++)
     {
       freq[(k / d) % s] += frequencies[k];
     }
@@ -251,11 +250,12 @@ std::string WordFromIndependentFrequenciesSet::getDescription() const
 // // WordFromUniqueFrequenciesSet
 
 
-WordFromUniqueFrequenciesSet::WordFromUniqueFrequenciesSet(const WordAlphabet* pWA,
-                                                           FrequenciesSet* pabsfreq,
-                                                           const string& prefix,
-                                                           const string& name) :
-  AbstractWordFrequenciesSet(pWA->getSize(), pWA, prefix, name),
+WordFromUniqueFrequenciesSet::WordFromUniqueFrequenciesSet(
+    const WordAlphabet* pWA,
+    FrequenciesSet* pabsfreq,
+    const string& prefix,
+    const string& name) :
+  AbstractWordFrequenciesSet(new CanonicalStateMap(pWA, false), prefix, name),
   pFreq_(pabsfreq),
   NestedPrefix_(pabsfreq->getNamespace()),
   length_(pWA->getLength())
@@ -313,7 +313,7 @@ void WordFromUniqueFrequenciesSet::updateFrequencies()
 {
   size_t s = getAlphabet()->getSize();
   vector<double> f;
-  int letsi = pFreq_->getAlphabet()->getSize();
+  size_t letsi = pFreq_->getAlphabet()->getSize();
 
   size_t i, p, i2;
 
@@ -344,8 +344,7 @@ void WordFromUniqueFrequenciesSet::setFrequencies(const vector<double>& frequenc
   if (fabs(1. - sum) > 0.000001)
     throw Exception("WordFromUniqueFrequenciesSet::setFrequencies. Frequencies must equal 1 (sum = " + TextTools::toString(sum) + ").");
 
-  size_t d, i, j;
-  int k;
+  size_t d, i, j, k;
   vector<double> freq;
 
   size_t letsi = pFreq_->getAlphabet()->getSize();
@@ -360,7 +359,7 @@ void WordFromUniqueFrequenciesSet::setFrequencies(const vector<double>& frequenc
   for (i = 0; i < length_; i++)
   {
     d /= letsi;
-    for (k = 0; k < (int)size; k++)
+    for (k = 0; k < size; k++)
     {
       freq[(k / d) % letsi] += frequencies[k];
     }
diff --git a/src/Bpp/Phyl/Model/FrequenciesSet/WordFrequenciesSet.h b/src/Bpp/Phyl/Model/FrequenciesSet/WordFrequenciesSet.h
index 0f31b67..5e59a95 100644
--- a/src/Bpp/Phyl/Model/FrequenciesSet/WordFrequenciesSet.h
+++ b/src/Bpp/Phyl/Model/FrequenciesSet/WordFrequenciesSet.h
@@ -96,7 +96,7 @@ protected:
   size_t getSizeFromVector(const std::vector<FrequenciesSet*>& freqVector);
   
 public:
-  AbstractWordFrequenciesSet(size_t size, const Alphabet* palph, const std::string& prefix = "", const std::string& name="");
+  AbstractWordFrequenciesSet(StateMap* stateMap, const std::string& prefix = "", const std::string& name="");
 
 #ifndef NO_VIRTUAL_COV
   AbstractWordFrequenciesSet*
diff --git a/src/Bpp/Phyl/Model/G2001.h b/src/Bpp/Phyl/Model/G2001.h
index cd0f3b0..53ee9f0 100644
--- a/src/Bpp/Phyl/Model/G2001.h
+++ b/src/Bpp/Phyl/Model/G2001.h
@@ -79,13 +79,10 @@ public:
    * @param normalizeRateChanges Tell if the rate transition matrix should be normalized.
    */
   G2001(ReversibleSubstitutionModel* model, DiscreteDistribution* rDist, double nu = 1., bool normalizeRateChanges = false) :
-    MarkovModulatedSubstitutionModel(model, normalizeRateChanges, "G01."),
+    MarkovModulatedSubstitutionModel(model, static_cast<unsigned int>(rDist->getNumberOfCategories()), normalizeRateChanges, "G01."),
     rDist_(rDist),
     nestedRatePrefix_("rdist_" + rDist->getNamespace())
   {
-    nbRates_ = rDist_->getNumberOfCategories();
-    ratesExchangeability_.resize(nbRates_, nbRates_);
-    rates_.resize(nbRates_, nbRates_);
     ratesFreq_ = std::vector<double>(nbRates_, 1. / static_cast<double>(nbRates_));
     rDist_->setNamespace(getNamespace() + nestedRatePrefix_);
     addParameters_(rDist_->getIndependentParameters());
diff --git a/src/Bpp/Phyl/Model/MarkovModulatedSubstitutionModel.cpp b/src/Bpp/Phyl/Model/MarkovModulatedSubstitutionModel.cpp
index b5abb07..b4b32fa 100644
--- a/src/Bpp/Phyl/Model/MarkovModulatedSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/MarkovModulatedSubstitutionModel.cpp
@@ -52,13 +52,13 @@ MarkovModulatedSubstitutionModel::MarkovModulatedSubstitutionModel(
   const MarkovModulatedSubstitutionModel& model) :
   AbstractParameterAliasable(model),
   model_               (dynamic_cast<ReversibleSubstitutionModel*>(model.model_->clone())),
+  stateMap_            (model.stateMap_),
   nbStates_            (model.nbStates_),
   nbRates_             (model.nbRates_),
   rates_               (model.rates_),
   ratesExchangeability_(model.ratesExchangeability_),
   ratesFreq_           (model.ratesFreq_),
   ratesGenerator_      (model.ratesGenerator_),
-  chars_               (model.chars_),
   generator_           (model.generator_),
   exchangeability_     (model.exchangeability_),
   leftEigenVectors_    (model.leftEigenVectors_),
@@ -79,13 +79,13 @@ MarkovModulatedSubstitutionModel& MarkovModulatedSubstitutionModel::operator=(
 {
   AbstractParametrizable::operator=(model);
   model_                = dynamic_cast<ReversibleSubstitutionModel*>(model.model_->clone());
+  stateMap_             = model.stateMap_;
   nbStates_             = model.nbStates_;
   nbRates_              = model.nbRates_;
   rates_                = model.rates_;
   ratesExchangeability_ = model.ratesExchangeability_;
   ratesFreq_            = model.ratesFreq_;
   ratesGenerator_       = model.ratesGenerator_;
-  chars_                = model.chars_;
   generator_            = model.generator_;
   exchangeability_      = model.exchangeability_;
   leftEigenVectors_     = model.leftEigenVectors_;
@@ -109,7 +109,6 @@ void MarkovModulatedSubstitutionModel::updateMatrices()
   // ratesGenerator_ and rates_ must be initialized!
   nbStates_        = model_->getNumberOfStates();
   nbRates_         = rates_.getNumberOfColumns();
-  chars_           = VectorTools::rep(model_->getAlphabetChars(), nbRates_);
   RowMatrix<double> Tmp1, Tmp2;
   MatrixTools::diag(ratesFreq_, Tmp1);
   MatrixTools::mult(ratesExchangeability_, Tmp1, ratesGenerator_);
@@ -195,7 +194,7 @@ const Matrix<double>& MarkovModulatedSubstitutionModel::getdPij_dt(double t) con
 
 const Matrix<double>& MarkovModulatedSubstitutionModel::getd2Pij_dt2(double t) const
 {
-  MatrixTools::mult(rightEigenVectors_, NumTools::sqr(eigenValues_) * VectorTools::exp(eigenValues_ * t), leftEigenVectors_, d2pijt_);
+  MatrixTools::mult(rightEigenVectors_, VectorTools::sqr(eigenValues_) * VectorTools::exp(eigenValues_ * t), leftEigenVectors_, d2pijt_);
   return d2pijt_;
 }
 
@@ -210,7 +209,7 @@ double MarkovModulatedSubstitutionModel::getInitValue(size_t i, int state) const
   vector<int> states = model_->getAlphabet()->getAlias(state);
   for (size_t j = 0; j < states.size(); j++)
   {
-    if (getAlphabetChar(i) == states[j])
+    if (getAlphabetStateAsInt(i) == states[j])
       return 1.;
   }
   return 0.;
diff --git a/src/Bpp/Phyl/Model/MarkovModulatedSubstitutionModel.h b/src/Bpp/Phyl/Model/MarkovModulatedSubstitutionModel.h
index c022589..803e93d 100644
--- a/src/Bpp/Phyl/Model/MarkovModulatedSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/MarkovModulatedSubstitutionModel.h
@@ -79,6 +79,7 @@ namespace bpp
 
   protected:
     ReversibleSubstitutionModel* model_;
+    MarkovModulatedStateMap stateMap_;
     size_t nbStates_; //Number of states in model
     size_t nbRates_; //Number of rate classes
 
@@ -95,11 +96,6 @@ namespace bpp
     RowMatrix<double> ratesGenerator_;       //All rates transitions
     
     /**
-     * @brief The list of supported chars.
-     */
-    std::vector<int> chars_;
-
-    /**
      * @brief The generator matrix \f$Q\f$ of the model.
      */
     RowMatrix<double> generator_;
@@ -156,15 +152,17 @@ namespace bpp
      * @brief Build a new MarkovModulatedSubstitutionModel object.
      *
      * @param model The substitution model to use. Can be of any alphabet type, and will be owned by this instance.
+     * @param nbRates The number of rate classes
      * @param normalizeRateChanges Tells if the branch lengths must be computed in terms of rate and state
+     * NB: In most cases, this parameter should be set to false.
      * @param prefix The parameter namespace to be forwarded to the AbstractParametrizable constructor.
      * changes instead of state change only.
-     * NB: In most cases, this parameter should be set to false.
      */
-    MarkovModulatedSubstitutionModel(ReversibleSubstitutionModel* model, bool normalizeRateChanges, const std::string& prefix) :
+    MarkovModulatedSubstitutionModel(ReversibleSubstitutionModel* model, unsigned int nbRates, bool normalizeRateChanges, const std::string& prefix) :
       AbstractParameterAliasable(prefix),
-      model_(model), nbStates_(model->getNumberOfStates()), nbRates_(0), rates_(), ratesExchangeability_(),
-      ratesFreq_(), ratesGenerator_(), chars_(), generator_(), exchangeability_(),
+      model_(model), stateMap_(model->getStateMap(), nbRates), nbStates_(model->getNumberOfStates()),
+      nbRates_(nbRates), rates_(nbRates, nbRates), ratesExchangeability_(nbRates, nbRates),
+      ratesFreq_(nbRates), ratesGenerator_(nbRates, nbRates), generator_(), exchangeability_(),
       leftEigenVectors_(), rightEigenVectors_(), eigenValues_(), iEigenValues_(), eigenDecompose_(true), 
       pijt_(), dpijt_(), d2pijt_(), freq_(),
       normalizeRateChanges_(normalizeRateChanges),
@@ -192,6 +190,18 @@ namespace bpp
 
     size_t getNumberOfStates() const { return nbStates_ * nbRates_; }
 
+    const StateMap& getStateMap() const { return stateMap_; }
+
+    const std::vector<int>& getAlphabetStates() const { return stateMap_.getAlphabetStates(); }
+
+    std::string getAlphabetStateAsChar(size_t index) const { return stateMap_.getAlphabetStateAsChar(index); }
+
+    int getAlphabetStateAsInt(size_t index) const { return stateMap_.getAlphabetStateAsInt(index); }
+
+    std::vector<size_t> getModelStates(int code) const { return stateMap_.getModelStates(code); }
+  
+    std::vector<size_t> getModelStates(const std::string& code) const { return stateMap_.getModelStates(code); }
+
     const Vdouble& getFrequencies() const { return freq_; }
     
     const Matrix<double>& getExchangeabilityMatrix() const { return exchangeability_; }
@@ -227,25 +237,6 @@ namespace bpp
       updateMatrices();
     }
 
-    const std::vector<int>& getAlphabetChars() const
-    {
-      return chars_;
-    }
-
-    int getAlphabetChar(size_t i) const
-    {
-      return chars_[i]; 
-    }
-   
-    std::vector<size_t> getModelStates(int i) const
-    {
-      std::vector<size_t> states(nbRates_ * nbStates_);
-      std::vector<size_t> nestedStates = model_->getModelStates(i);
-      for(size_t j = 0; j < nbRates_; j++)
-        for(size_t k = 0; k < nestedStates.size(); k++)
-          states.push_back(j * nbRates_ + states[k]);
-      return states;
-    }
 
     const ReversibleSubstitutionModel* getNestedModel() const { return model_; }
 
diff --git a/src/Bpp/Phyl/Model/MixedSubstitutionModel.h b/src/Bpp/Phyl/Model/MixedSubstitutionModel.h
index 1c8c880..175df8c 100644
--- a/src/Bpp/Phyl/Model/MixedSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/MixedSubstitutionModel.h
@@ -4,7 +4,7 @@
 //
 
 /*
-  Copyright or © or Copr. CNRS, (November 16, 2004)
+  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.
diff --git a/src/Bpp/Phyl/Model/MixedSubstitutionModelSet.cpp b/src/Bpp/Phyl/Model/MixedSubstitutionModelSet.cpp
index 6516f42..9cb1de7 100644
--- a/src/Bpp/Phyl/Model/MixedSubstitutionModelSet.cpp
+++ b/src/Bpp/Phyl/Model/MixedSubstitutionModelSet.cpp
@@ -5,7 +5,7 @@
 //
 
 /*
-   Copyright or <A9> or Copr. CNRS, (November 16, 2004)
+   Copyright or <A9> or Copr. Bio++ Development Team, (November 16, 2004)
 
    This software is a computer program whose purpose is to provide classes
    for phylogenetic data analysis.
@@ -141,9 +141,9 @@ bool MixedSubstitutionModelSet::complete()
       int j(0), k(0);
       while (j < vs)
       {
-        while ((k < snd) && (nd[k] < j))
+        while ((k < snd) && (nd[static_cast<size_t>(k)] < j))
           k++;
-        if ((k >= snd) || (nd[k] > j))
+        if ((k >= snd) || (nd[static_cast<size_t>(k)] > j))
           an.push_back(j);
         j++;
       }
@@ -164,7 +164,7 @@ void MixedSubstitutionModelSet::addToHyperNode(size_t nM, const Vint& vnS, int n
   if (nM >= getNumberOfModels())
     throw IndexOutOfBoundsException("MixedSubstitutionModelSet::addToHyperNode. Bad Mixed Model number", nM, 0, getNumberOfModels());
 
-  vpHyperNodes_[nH]->addToModel(nM, vnS);
+  vpHyperNodes_[static_cast<size_t>(nH)]->addToModel(nM, vnS);
 }
 
 bool MixedSubstitutionModelSet::hasExclusivePaths() const
@@ -224,7 +224,7 @@ void MixedSubstitutionModelSet::computeHyperNodesProbabilities()
     double fprob = 0;
     for (size_t i = 0; i < fnd.size(); i++)
     {
-      fprob += pfSM->getNProbability(fnd[i]);
+      fprob += pfSM->getNProbability(static_cast<size_t>(fnd[i]));
     }
     h.setProbability(fprob);
   }
@@ -243,13 +243,13 @@ void MixedSubstitutionModelSet::computeHyperNodesProbabilities()
         double prob = 0;
         for (size_t j = 0; j < fnd.size(); j++)
         {
-          prob += pfSM->getNProbability(fnd[j]);
+          prob += pfSM->getNProbability(static_cast<size_t>(fnd[j]));
         }
 
         // sets the real probabilities
         for (size_t j = 0; j < fnd.size(); j++)
         {
-          pfSM->setNProbability(fnd[j], h.getProbability() * pfSM->getNProbability(fnd[j]) / prob);
+          pfSM->setNProbability(static_cast<size_t>(fnd[j]), h.getProbability() * pfSM->getNProbability(static_cast<size_t>(fnd[j])) / prob);
         }
       }
 
@@ -265,7 +265,7 @@ void MixedSubstitutionModelSet::computeHyperNodesProbabilities()
         const MixedSubstitutionModelSet::HyperNode::Node& fnd = h.getNode(iM);
         for (size_t j = 0; j < fnd.size(); j++)
         {
-          pfSM->setNProbability(fnd[j], pfSM->getNProbability(fnd[j]) / h.getProbability());
+          pfSM->setNProbability(static_cast<size_t>(fnd[j]), pfSM->getNProbability(static_cast<size_t>(fnd[j])) / h.getProbability());
         }
       }
     }
@@ -287,7 +287,7 @@ double MixedSubstitutionModelSet::getHyperNodeProbability(const HyperNode& hn) c
 
       for (size_t i = 0; i < fnd.size(); i++)
       {
-        x += pfSM->getNProbability(fnd[i]);
+        x += pfSM->getNProbability(static_cast<size_t>(fnd[i]));
       }
 
       fprob *= x;
@@ -358,13 +358,13 @@ void MixedSubstitutionModelSet::HyperNode::setModel(size_t nM, const Vint& vnS)
 
 bool MixedSubstitutionModelSet::HyperNode::isComplete() const
 {
-  int k;
-  int vUs = (int)vUnused_.size();
-  for (int i = 0; i < (int)vNumbers_.size(); i++)
+  size_t k;
+  size_t vUs = vUnused_.size();
+  for (size_t i = 0; i < vNumbers_.size(); ++i)
   {
     for (k = 0; k < vUs; k++)
     {
-      if (vUnused_[k] == i)
+      if (vUnused_[k] == static_cast<int>(i))
         break;
     }
     if ((k == vUs) && vNumbers_[i].size() == 0)
diff --git a/src/Bpp/Phyl/Model/MixedSubstitutionModelSet.h b/src/Bpp/Phyl/Model/MixedSubstitutionModelSet.h
index af90dc6..1195327 100644
--- a/src/Bpp/Phyl/Model/MixedSubstitutionModelSet.h
+++ b/src/Bpp/Phyl/Model/MixedSubstitutionModelSet.h
@@ -49,351 +49,343 @@
 
 namespace bpp
 {
-  /**
-   * @brief Substitution models manager for Mixed Substitution Models.
-   * This class inherits from SubstitutionModelSet.
-   *
-   * This class is done to handle specific cases of choices among the
-   * submodels of mixed substitution models. Each branch of the tree
-   * is labelled by a mixed model, and a site may be restricted to a
-   * set of submodels it is allowed to follow. These sets are defined
-   * through an hypergrap, ie a list of hypernodes.
-   *
-   * For example, suppose there are 3 mixed models (M1,M2 and M3),
-   * with 2, 3, 4 submodels (S1, S2, ...) each.
-   *
-   * If the sites are allowed to follow any combination of submodels
-   * (12 combinations) the corresponding hypergraph has only one
-   * hypernode: (<1,2>,<1,2,3>,<1,2,3,4>).
-   *
-   * The hypergraph with hypernodes
-   * ((<1>,<1,2>,<1,2>),(<2>,<3>,<3,4>)) means that a site either
-   * follows 6 combinations:
-   *
-   * M1:S1, M2:S1 or M2:S2, and M3:S1 or M3:S2.
-   *
-   * or
-   *
-   * M1:S2, M2:S3, and M3:S3 or M3:S4.
-   *
-   *
-   * Actually, additional coordinates are set when there are non mixed
-   * models, with no value in them, and not used in practice.
-   *
-   * An hypernode is valid only if each mixed model is represented at
-   * least by one submodel.
-   *
-   * Dependency of the submodels entails constraints in the
-   * probabilities of the submodels, and definition of the hypernodes
-   * must be taken with care for the whole modelling to be possible.
-   *
-   *
-   *
-   * In this implementation, for sake of simplification (and for
-   * reason of time), all the submodels must belong to exactly one
-   * given hypernode, but in theory more complex dependencies are 
-   * possible.
-   *
-   * Concerning the probabilities of the submodels in each hypernode,
-   * the first coordinate (ie set of submodels inside a mixed model)
-   * in the list defines the probability of each hypernode. For each
-   * coordinate (the first included), when there are several
-   * submodels, their probabilities are conditional probabilities,
-   * which means that they sum 1 and their ratio are unchanged.
-   *
-   * For instance, for hypergraph ((<1>,<1,2>,<1,2>),(<2>,<3>,<3,4>)),
-   * the probabilities of hypernodes are the probabilities of M1:S1
-   * and M1:S2. In the first hypernode, the probabilities of M2:S1 and
-   * M2:S2 are P(M2:S1)/(P(M2:S1)+P(M2:S2)) and
-   * P(M2:S2)/(P(M2:S1)+P(M2:S2)).
-   *
-   * We do not certify that the probability parameters of the mixed
-   * models are all useful, and then identifiability problems may be
-   * encountered. 
-   *
-   * There is a method ("complete") that creates an additional
-   * hypernode to ensure that all submodels belong to at least an
-   * hypernode.
-   * 
-   *
-   */
-  
-  class MixedSubstitutionModelSet :
-    public SubstitutionModelSet
+/**
+ * @brief Substitution models manager for Mixed Substitution Models.
+ * This class inherits from SubstitutionModelSet.
+ *
+ * This class is done to handle specific cases of choices among the
+ * submodels of mixed substitution models. Each branch of the tree
+ * is labelled by a mixed model, and a site may be restricted to a
+ * set of submodels it is allowed to follow. These sets are defined
+ * through an hypergrap, ie a list of hypernodes.
+ *
+ * For example, suppose there are 3 mixed models (M1,M2 and M3),
+ * with 2, 3, 4 submodels (S1, S2, ...) each.
+ *
+ * If the sites are allowed to follow any combination of submodels
+ * (12 combinations) the corresponding hypergraph has only one
+ * hypernode: (<1,2>,<1,2,3>,<1,2,3,4>).
+ *
+ * The hypergraph with hypernodes
+ * ((<1>,<1,2>,<1,2>),(<2>,<3>,<3,4>)) means that a site either
+ * follows 6 combinations:
+ *
+ * M1:S1, M2:S1 or M2:S2, and M3:S1 or M3:S2.
+ *
+ * or
+ *
+ * M1:S2, M2:S3, and M3:S3 or M3:S4.
+ *
+ *
+ * Actually, additional coordinates are set when there are non mixed
+ * models, with no value in them, and not used in practice.
+ *
+ * An hypernode is valid only if each mixed model is represented at
+ * least by one submodel.
+ *
+ * Dependency of the submodels entails constraints in the
+ * probabilities of the submodels, and definition of the hypernodes
+ * must be taken with care for the whole modelling to be possible.
+ *
+ *
+ *
+ * In this implementation, for sake of simplification (and for
+ * reason of time), all the submodels must belong to exactly one
+ * given hypernode, but in theory more complex dependencies are
+ * possible.
+ *
+ * Concerning the probabilities of the submodels in each hypernode,
+ * the first coordinate (ie set of submodels inside a mixed model)
+ * in the list defines the probability of each hypernode. For each
+ * coordinate (the first included), when there are several
+ * submodels, their probabilities are conditional probabilities,
+ * which means that they sum 1 and their ratio are unchanged.
+ *
+ * For instance, for hypergraph ((<1>,<1,2>,<1,2>),(<2>,<3>,<3,4>)),
+ * the probabilities of hypernodes are the probabilities of M1:S1
+ * and M1:S2. In the first hypernode, the probabilities of M2:S1 and
+ * M2:S2 are P(M2:S1)/(P(M2:S1)+P(M2:S2)) and
+ * P(M2:S2)/(P(M2:S1)+P(M2:S2)).
+ *
+ * We do not certify that the probability parameters of the mixed
+ * models are all useful, and then identifiability problems may be
+ * encountered.
+ *
+ * There is a method ("complete") that creates an additional
+ * hypernode to ensure that all submodels belong to at least an
+ * hypernode.
+ *
+ *
+ */
+
+class MixedSubstitutionModelSet :
+  public SubstitutionModelSet
+{
+public:
+  class HyperNode
   {
-  public:
-     class HyperNode
-     {
-     public: 
-       class Node {
-
-         /**
-          * A vector<int> where all elements are different and in
-          * increasing order.
-          *
-          */
-
-         Vint vNumb_;
-
-       public:
-         Node() : vNumb_() {};
-         Node(const Node& n): vNumb_(n.vNumb_){};
-         Node& operator=(const Node& n){
-           vNumb_=n.vNumb_;
-           return *this;
-         }
-         
-         ~Node(){};
-
-         Node& operator=(const Vint& n) {
-           vNumb_=n;
-           return *this;
-         }
-
-         void insertN(const Vint& vn);
-
-         size_t size() const{
-           return vNumb_.size();
-         }
-
-         /*
-          *@brief Cumulates the elements of the given Node into this one.
-          *
-          */
-
-         Node& operator+=(const Node&);
-         
-         /*
-          *@brief checks if this Node is included in another one.
-          *
-          */
-
-         bool operator<=(const Node&) const;
-
-         /*
-          *@brief checks if this HyperNode includes another one.
-          *
-          */
-
-         bool operator>=(const Node&) const;
-
-         /*
-          *@brief checks if this Node intersects another one.
-          *
-          */
-       
-         bool intersects(const Node&) const;
-
-         int operator[](size_t i) const { return vNumb_[i]; }
-
-       };
-
-     private:
-       
-       std::vector<Node> vNumbers_;
-
-       /*
-        *@brief the coordinates of the Nodes that are not used.
-        *
-        */
-       
-       Vint vUnused_;
-
-       /*
-        *@brief probability of this HyperNode.
-        *
-        */
-
-       double proba_;
-       
-     public:
-       HyperNode(const MixedSubstitutionModelSet*);
-       HyperNode(const HyperNode&);
-       HyperNode& operator=(const HyperNode&);
-       ~HyperNode(){};
-
-       /*
-        *@brief sets submodel numbers in the nMth mixed model. Checks
-        *  if all the numbers are valid.
-        *
-        *@param nM number of the mixed model
-        *@param vnS vector of numbers of the submodel
-        */
-    
-       void setModel(size_t nM, const Vint& vnS);
-
-       /*
-        *@brief adds submodel numbers to the nMth mixed model. Checks
-        *  if all the numbers are valid.
-        *
-        *@param nM number of the mixed model
-        *@param vnS vector of numbers of the submodel
-        */
-    
-       void addToModel(size_t nM, const Vint& vnS);
-       /*
-        *@brief Cumulates the Nodes of the given HyperNode into this one.
-        *
-        */
-
-       HyperNode& operator+=(const HyperNode&);
-         
-       /*
-        *@brief checks if this HyperNode is included in another one.
-        *
-        */
-       
-       bool operator<=(const HyperNode&) const;
-
-       /*
-        *@brief checks if this HyperNode includes at least a submodel of each mixed model
-        *
-        */
-       bool isComplete() const;
-       /*
-        *@brief checks if this HyperNode includes another one.
-        *
-        */
-       bool operator>=(const HyperNode&) const;
-
-       /*
-        *@brief checks if this HyperNode intersects another one.
-        *
-        */       
-       bool intersects(const HyperNode&) const;
-
-       /*
-        *@brief returns the probability
-        *
-        */
-
-       double getProbability() const {return proba_;}
-
-       /*
-        *@brief sets the probability
-        *
-        */
-
-       void setProbability(double x) { proba_ = x; }
-       
-       const Node& getNode(size_t i) const { return vNumbers_[i]; }
-
-     };
-
-  private:
-    
-    std::vector<HyperNode*> vpHyperNodes_;
-
-  public:
+public:
+    class Node
+    {
+      /**
+       * @brief A vector<int> where all elements are different and in
+       * increasing order.
+       */
+      Vint vNumb_;
+
+public:
+      Node() : vNumb_() {}
+      Node(const Node& n) : vNumb_(n.vNumb_){}
+      Node& operator=(const Node& n)
+      {
+        vNumb_ = n.vNumb_;
+        return *this;
+      }
+
+      ~Node(){}
+
+      Node& operator=(const Vint& n)
+      {
+        vNumb_ = n;
+        return *this;
+      }
+
+      void insertN(const Vint& vn);
+
+      size_t size() const
+      {
+        return vNumb_.size();
+      }
+
+      /**
+       * @brief Cumulates the elements of the given Node into this one.
+       *
+       */
+
+      Node& operator+=(const Node&);
+
+      /**
+       * @brief checks if this Node is included in another one.
+       *
+       */
+
+      bool operator<=(const Node&) const;
+
+      /**
+       * @brief checks if this HyperNode includes another one.
+       *
+       */
+
+      bool operator>=(const Node&) const;
+
+      /**
+       * @brief checks if this Node intersects another one.
+       *
+       */
+
+      bool intersects(const Node&) const;
+
+      int operator[](size_t i) const { return vNumb_[i]; }
+    };
+
+private:
+    std::vector<Node> vNumbers_;
+
     /**
-     * @brief Create a model set according to the specified alphabet.
+     * @brief the coordinates of the Nodes that are not used.
      *
-     * @param alpha The alphabet to use for this set.
      */
-    MixedSubstitutionModelSet(const Alphabet* alpha): 
-      SubstitutionModelSet(alpha), vpHyperNodes_() {}
-    
-    ~MixedSubstitutionModelSet();
-    
-    MixedSubstitutionModelSet(const MixedSubstitutionModelSet& set);
-    
-    MixedSubstitutionModelSet(const SubstitutionModelSet& set);
-
-    MixedSubstitutionModelSet& operator=(const MixedSubstitutionModelSet& set);
-    
-#ifndef NO_VIRTUAL_COV
-    MixedSubstitutionModelSet*
-#else
-    Clonable*
-#endif
-    clone() const { return new MixedSubstitutionModelSet(*this); }
+
+    Vint vUnused_;
 
     /**
-     * @brief Resets the list of the HyperNodes
+     * @brief probability of this HyperNode.
+     *
      */
-    
-    void clear();
 
-    /*
-     *@brief adds a new empty HyperNode to the end of the HyperNodes
-     * list.
+    double proba_;
+
+public:
+    HyperNode(const MixedSubstitutionModelSet*);
+    HyperNode(const HyperNode&);
+    HyperNode& operator=(const HyperNode&);
+    ~HyperNode(){}
+
+    /**
+     * @brief sets submodel numbers in the nMth mixed model. Checks
+     *  if all the numbers are valid.
+     *
+     * @param nM number of the mixed model
+     * @param vnS vector of numbers of the submodel
      */
-    
-    void addEmptyHyperNode();
 
-    /*
-     *@brief adds the copy of an HyperNode to the end of the
-     * HyperNodes list.
+    void setModel(size_t nM, const Vint& vnS);
+
+    /**
+     * @brief adds submodel numbers to the nMth mixed model. Checks
+     *  if all the numbers are valid.
+     *
+     * @param nM number of the mixed model
+     * @param vnS vector of numbers of the submodel
      */
-    
-    void addHyperNode(const HyperNode& hn);
 
-    /*
-     *@brief If necessary, adds a new HyperNode such that all
-     *       submodels of the mixture models are at least in an
-     *       HyperNode.
+    void addToModel(size_t nM, const Vint& vnS);
+    /**
+     * @brief Cumulates the Nodes of the given HyperNode into this one.
      *
-     * Returns true iff a new path has been built.
-     * 
      */
+    HyperNode& operator+=(const HyperNode&);
 
-    bool complete();
-    
-    /*
-     *@brief adds a submodel number to the nMth mixed model of the
-     *  nHth HyperNode of the list (default nH=0). Checks if all the
-     *  numbers are valid.
+    /**
+     * @brief checks if this HyperNode is included in another one.
      *
-     *@param nM number of the mixed model
-     *@param vnS number of the submodel
-     *@param nH number of the concerned HyperNode (default the last element of
-     *     the list)
      */
-    
-    void addToHyperNode(size_t nM, const Vint& vnS, int nH = -1);
+    bool operator<=(const HyperNode&) const;
 
-    size_t getNumberOfHyperNodes() const{ return vpHyperNodes_.size();}
+    /**
+     * @brief checks if this HyperNode includes at least a submodel of each mixed model
+     *
+     */
+    bool isComplete() const;
+    /**
+     * @brief checks if this HyperNode includes another one.
+     *
+     */
+    bool operator>=(const HyperNode&) const;
 
-    HyperNode& getHyperNode(size_t i) {return *vpHyperNodes_[i];} 
+    /**
+     * @brief checks if this HyperNode intersects another one.
+     *
+     */
+    bool intersects(const HyperNode&) const;
 
-    const HyperNode& getHyperNode(size_t i) const {return *vpHyperNodes_[i];} 
+    /**
+     * @brief returns the probability
+     *
+     */
+    double getProbability() const {return proba_; }
 
-    /*
-     *@brief Checks if all the path (ie hypernodes) are exclusive.
+    /**
+     * @brief sets the probability
      *
      */
-    
-    bool hasExclusivePaths() const;
+    void setProbability(double x) { proba_ = x; }
+
+    const Node& getNode(size_t i) const { return vNumbers_[i]; }
+  };
+
+private:
+  std::vector<HyperNode*> vpHyperNodes_;
+
+public:
+  /**
+   * @brief Create a model set according to the specified alphabet.
+   *
+   * @param alpha The alphabet to use for this set.
+   */
+  MixedSubstitutionModelSet(const Alphabet* alpha) :
+    SubstitutionModelSet(alpha),
+    vpHyperNodes_() {}
+
+  ~MixedSubstitutionModelSet();
+
+  MixedSubstitutionModelSet(const MixedSubstitutionModelSet& set);
+
+  MixedSubstitutionModelSet(const SubstitutionModelSet& set);
+
+  MixedSubstitutionModelSet& operator=(const MixedSubstitutionModelSet& set);
+
+#ifndef NO_VIRTUAL_COV
+  MixedSubstitutionModelSet*
+#else
+  Clonable*
+#endif
+  clone() const { return new MixedSubstitutionModelSet(*this); }
+
+  /**
+   * @brief Resets the list of the HyperNodes
+   */
+
+  void clear();
+
+  /*
+     *@brief adds a new empty HyperNode to the end of the HyperNodes
+   * list.
+   */
+
+  void addEmptyHyperNode();
+
+  /*
+     *@brief adds the copy of an HyperNode to the end of the
+   * HyperNodes list.
+   */
 
-    void fireParameterChanged(const ParameterList& parameters);
+  void addHyperNode(const HyperNode& hn);
 
-    /*
+  /*
+     *@brief If necessary, adds a new HyperNode such that all
+   *       submodels of the mixture models are at least in an
+   *       HyperNode.
+   *
+   * Returns true iff a new path has been built.
+   *
+   */
+
+  bool complete();
+
+  /*
+     *@brief adds a submodel number to the nMth mixed model of the
+   *  nHth HyperNode of the list (default nH=0). Checks if all the
+   *  numbers are valid.
+   *
+   ***@param nM number of the mixed model
+   ***@param vnS number of the submodel
+   ***@param nH number of the concerned HyperNode (default the last element of
+   *     the list)
+   */
+
+  void addToHyperNode(size_t nM, const Vint& vnS, int nH = -1);
+
+  size_t getNumberOfHyperNodes() const { return vpHyperNodes_.size(); }
+
+  HyperNode& getHyperNode(size_t i) {return *vpHyperNodes_[i]; }
+
+  const HyperNode& getHyperNode(size_t i) const {return *vpHyperNodes_[i]; }
+
+  /*
+     *@brief Checks if all the path (ie hypernodes) are exclusive.
+   *
+   */
+
+  bool hasExclusivePaths() const;
+
+  void fireParameterChanged(const ParameterList& parameters);
+
+  /*
      *@brief compute the probabilities in all the HyperNodes
-     *
-     */
+   *
+   */
 
-    void computeHyperNodesProbabilities();
+  void computeHyperNodesProbabilities();
 
-    /*
+  /*
      *@brief computes the probability of an HyperNode, given
-     *     the conditional probabilities of the submodels computed
-     *     from the hypernodes of this MixedSubstitutionModelSet
-     *     object. If the HyperNode does not match the structure of
-     *     allowed by this MixedSubstitutionModelSet, an Exception
-     *     is thrown.
-     *
-     *     The probability of an HyperNode is the product -- on the
-     *     set of the mixed models -- of the sums of the
-     *     conditional probabilities of the submodels that belon to
-     *     this hypernode for each mixed model.
-     *
-     *@param hn the HyperNode which conditional probability is computed.
-     */
-
-    double getHyperNodeProbability(const HyperNode& hn) const;
+   *     the conditional probabilities of the submodels computed
+   *     from the hypernodes of this MixedSubstitutionModelSet
+   *     object. If the HyperNode does not match the structure of
+   *     allowed by this MixedSubstitutionModelSet, an Exception
+   *     is thrown.
+   *
+   *     The probability of an HyperNode is the product -- on the
+   *     set of the mixed models -- of the sums of the
+   *     conditional probabilities of the submodels that belon to
+   *     this hypernode for each mixed model.
+   *
+   ***@param hn the HyperNode which conditional probability is computed.
+   */
 
-  };
-  
+  double getHyperNodeProbability(const HyperNode& hn) const;
+};
 } // end of namespace bpp.
 
 #endif // _MIXEDSUBSTITUTIONMODELSET_H_
diff --git a/src/Bpp/Phyl/Model/MixtureOfASubstitutionModel.cpp b/src/Bpp/Phyl/Model/MixtureOfASubstitutionModel.cpp
index f3cd0a3..c3e9edd 100644
--- a/src/Bpp/Phyl/Model/MixtureOfASubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/MixtureOfASubstitutionModel.cpp
@@ -39,9 +39,7 @@
 #include "MixtureOfASubstitutionModel.h"
 
 #include <Bpp/Numeric/NumConstants.h>
-
 #include <Bpp/Numeric/Prob/ConstantDistribution.h>
-
 #include <Bpp/Exceptions.h>
 
 #include <string>
@@ -57,7 +55,7 @@ MixtureOfASubstitutionModel::MixtureOfASubstitutionModel(
   int ffrom,
   int tto) throw (Exception) :
   AbstractParameterAliasable(model->getNamespace()),
-  AbstractMixedSubstitutionModel(alpha, model->getNamespace()),
+  AbstractMixedSubstitutionModel(alpha, model->getStateMap().clone(), model->getNamespace()),
   distributionMap_(),
   from_(ffrom),
   to_(tto)
@@ -185,7 +183,7 @@ MixtureOfASubstitutionModel::~MixtureOfASubstitutionModel()
 
 const DiscreteDistribution* MixtureOfASubstitutionModel::getDistribution(std::string& parName) const
 {
-  if (distributionMap_.find(parName)!=distributionMap_.end())
+  if (distributionMap_.find(parName) != distributionMap_.end())
     return distributionMap_.find(parName)->second;
   else
     return NULL;
@@ -265,7 +263,7 @@ void MixtureOfASubstitutionModel::updateMatrices()
 
     for (j = 0; j < modelsContainer_.size(); j++)
     {
-      vd.push_back(1 / getNModel(j)->Qij(from_, to_));
+      vd.push_back(1 / getNModel(j)->Qij(static_cast<size_t>(from_), static_cast<size_t>(to_)));
     }
 
     setVRates(vd);
@@ -291,15 +289,15 @@ Vint MixtureOfASubstitutionModel::getSubmodelNumbers(string& desc) const
     string::size_type index = param.rfind("_");
     if (index == string::npos)
       throw Exception("MixtureOfASubstitutionModel::getSubmodelNumbers parameter description should contain a number" + param);
-    msubn[param.substr(0, index)] = TextTools::toInt(param.substr(index + 1, 4)) - 1;
+    msubn[param.substr(0, index)] = TextTools::to<size_t>(param.substr(index + 1, 4)) - 1;
   }
 
   Vint submodnb;
   size_t i, j, l;
   string s;
 
-  bool nameok=false;
-  
+  bool nameok = false;
+
   for (i = 0; i < modelsContainer_.size(); i++)
   {
     j = i;
@@ -308,12 +306,13 @@ Vint MixtureOfASubstitutionModel::getSubmodelNumbers(string& desc) const
       s = it->first;
       l = j % it->second->getNumberOfCategories();
 
-      if (msubn.find(s) != msubn.end()){
+      if (msubn.find(s) != msubn.end())
+      {
         nameok = true;
         if (msubn[s] != l)
           break;
       }
-      
+
       j = j / it->second->getNumberOfCategories();
     }
     if (nameok && it == distributionMap_.end())
@@ -322,4 +321,3 @@ Vint MixtureOfASubstitutionModel::getSubmodelNumbers(string& desc) const
 
   return submodnb;
 }
-
diff --git a/src/Bpp/Phyl/Model/MixtureOfASubstitutionModel.h b/src/Bpp/Phyl/Model/MixtureOfASubstitutionModel.h
index 889c7a9..dc39832 100644
--- a/src/Bpp/Phyl/Model/MixtureOfASubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/MixtureOfASubstitutionModel.h
@@ -106,18 +106,19 @@ class MixtureOfASubstitutionModel :
 private:
   std::map<std::string, DiscreteDistribution*> distributionMap_;
   int from_, to_;
-  
+
 public:
-  MixtureOfASubstitutionModel(const Alphabet* alpha,
-                              SubstitutionModel* model,
-                              std::map<std::string, DiscreteDistribution*> parametersDistributionsList,
-                              int ffrom=-1, int tto=-1) throw(Exception);
+  MixtureOfASubstitutionModel(
+      const Alphabet* alpha,
+      SubstitutionModel* model,
+      std::map<std::string, DiscreteDistribution*> parametersDistributionsList,
+      int ffrom = -1, int tto = -1) throw (Exception);
 
   MixtureOfASubstitutionModel(const MixtureOfASubstitutionModel&);
-  
+
   MixtureOfASubstitutionModel& operator=(const MixtureOfASubstitutionModel&);
 
-  ~MixtureOfASubstitutionModel();
+  virtual ~MixtureOfASubstitutionModel();
 
   MixtureOfASubstitutionModel* clone() const { return new MixtureOfASubstitutionModel(*this); }
 
@@ -127,14 +128,14 @@ public:
   void updateMatrices();
 
   /*
-   *@brief Returns the vector of numbers of the submodels in the
-   *mixture that match a description of the parameters numbers.
+     *@brief Returns the vector of numbers of the submodels in the
+     *mixture that match a description of the parameters numbers.
    *
-   *@param desc is the description of the class indexes of the mixed
-   *parameters. Syntax is like: kappa_1,gamma_3,delta_2
+   **@param desc is the description of the class indexes of the mixed
+   **parameters. Syntax is like: kappa_1,gamma_3,delta_2
    *
    */
-  
+
   Vint getSubmodelNumbers(std::string& desc) const;
 
   /**
@@ -144,7 +145,7 @@ public:
    *
    */
 
-  void setFreq(std::map<int,double>&);
+  void setFreq(std::map<int, double>&);
 
   /**
    * @brief returns the DiscreteDistribution associated with a given
@@ -155,14 +156,13 @@ public:
   const DiscreteDistribution* getDistribution(std::string& parName) const;
 
   /**
-   *@brief Numbers of the states between which the substitution rates
-   *of all the submodels must be equal. If they are set to -1, this
-   *constraint does not exist among the submodels.
+     *@brief Numbers of the states between which the substitution rates
+     *of all the submodels must be equal. If they are set to -1, this
+     *constraint does not exist among the submodels.
    *
    */
-  
-  int from() const { return from_;}
-  int to() const { return to_;}
+  int from() const { return from_; }
+  int to() const { return to_; }
 };
 } // end of namespace bpp.
 
diff --git a/src/Bpp/Phyl/Model/MixtureOfSubstitutionModels.cpp b/src/Bpp/Phyl/Model/MixtureOfSubstitutionModels.cpp
index f98761f..639e077 100644
--- a/src/Bpp/Phyl/Model/MixtureOfSubstitutionModels.cpp
+++ b/src/Bpp/Phyl/Model/MixtureOfSubstitutionModels.cpp
@@ -4,7 +4,7 @@
 // Date: mardi 14 septembre 2010, à 20h 43
 //
 /*
-   Copyright or © or Copr. CNRS, (November 16, 2004)
+   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.
@@ -46,20 +46,21 @@
 using namespace bpp;
 using namespace std;
 
-MixtureOfSubstitutionModels::MixtureOfSubstitutionModels(const Alphabet* alpha,
-                                                         vector<SubstitutionModel*> vpModel_) :
+MixtureOfSubstitutionModels::MixtureOfSubstitutionModels(
+  const Alphabet* alpha,
+  vector<SubstitutionModel*> vpModel) :
   AbstractParameterAliasable("Mixture."),
-  AbstractMixedSubstitutionModel(alpha, "Mixture.")
+  AbstractMixedSubstitutionModel(alpha, vpModel[0]->getStateMap().clone(), "Mixture.")
 {
-  size_t i, nbmod = vpModel_.size();
+  size_t i, nbmod = vpModel.size();
 
   for (i = 0; i < nbmod; i++)
   {
-    if (!vpModel_[i])
+    if (!vpModel[i])
       throw Exception("Empty model number " + TextTools::toString(i) + " in MixtureOfSubstitutionModels constructor");
     for (size_t j = i + 1; j < nbmod; j++)
     {
-      if (vpModel_[i] == vpModel_[j])
+      if (vpModel[i] == vpModel[j])
         throw Exception("Same model at positions " + TextTools::toString(i) + " and " +
                         TextTools::toString(j) + " in MixtureOfSubstitutionModels constructor");
     }
@@ -69,7 +70,7 @@ MixtureOfSubstitutionModels::MixtureOfSubstitutionModels(const Alphabet* alpha,
 
   for (i = 0; i < nbmod; i++)
   {
-    modelsContainer_.push_back(vpModel_[i]);
+    modelsContainer_.push_back(vpModel[i]);
     vProbas_.push_back(1.0 / static_cast<double>(nbmod));
     vRates_.push_back(1.0);
   }
@@ -87,34 +88,35 @@ MixtureOfSubstitutionModels::MixtureOfSubstitutionModels(const Alphabet* alpha,
 
   for (i = 0; i < nbmod; i++)
   {
-    modelsContainer_[i]->setNamespace("Mixture." + TextTools::toString(i + 1) + "_" + vpModel_[i]->getNamespace());
-    addParameters_(vpModel_[i]->getParameters());
+    modelsContainer_[i]->setNamespace("Mixture." + TextTools::toString(i + 1) + "_" + vpModel[i]->getNamespace());
+    addParameters_(vpModel[i]->getParameters());
   }
 
   for (i = 0; i < nbmod; i++)
   {
-    vpModel_[i]->addRateParameter();
+    vpModel[i]->addRateParameter();
   }
 
   updateMatrices();
 }
 
-MixtureOfSubstitutionModels::MixtureOfSubstitutionModels(const Alphabet* alpha,
-                                                         vector<SubstitutionModel*> vpModel_,
-                                                         Vdouble& vproba,
-                                                         Vdouble& vrate) :
+MixtureOfSubstitutionModels::MixtureOfSubstitutionModels(
+    const Alphabet* alpha,
+    vector<SubstitutionModel*> vpModel,
+    Vdouble& vproba,
+    Vdouble& vrate) :
   AbstractParameterAliasable("Mixture."),
-  AbstractMixedSubstitutionModel(alpha, "Mixture.")
+  AbstractMixedSubstitutionModel(alpha, vpModel[0]->getStateMap().clone(), "Mixture.")
 {
-  size_t i, nbmod = vpModel_.size();
+  size_t i, nbmod = vpModel.size();
 
   for (i = 0; i < nbmod; i++)
   {
-    if (!vpModel_[i])
+    if (!vpModel[i])
       throw Exception("Empty model number " + TextTools::toString(i) + " in MixtureOfSubstitutionModels constructor");
     for (size_t j = i + 1; j < nbmod; j++)
     {
-      if (vpModel_[i] == vpModel_[j])
+      if (vpModel[i] == vpModel[j])
         throw Exception("Same model at positions " + TextTools::toString(i) + " and " +
                         TextTools::toString(j) + " in MixtureOfSubstitutionModels constructor");
     }
@@ -143,7 +145,7 @@ MixtureOfSubstitutionModels::MixtureOfSubstitutionModels(const Alphabet* alpha,
 
   for (i = 0; i < nbmod; i++)
   {
-    modelsContainer_.push_back(vpModel_[i]);
+    modelsContainer_.push_back(vpModel[i]);
   }
 
   // rates & probas
@@ -172,13 +174,13 @@ MixtureOfSubstitutionModels::MixtureOfSubstitutionModels(const Alphabet* alpha,
 
   for (i = 0; i < nbmod; i++)
   {
-    modelsContainer_[i]->setNamespace("Mixture." + TextTools::toString(i + 1) + "_" + vpModel_[i]->getNamespace());
-    addParameters_(vpModel_[i]->getParameters());
+    modelsContainer_[i]->setNamespace("Mixture." + TextTools::toString(i + 1) + "_" + vpModel[i]->getNamespace());
+    addParameters_(vpModel[i]->getParameters());
   }
 
   for (i = 0; i < nbmod; i++)
   {
-    vpModel_[i]->addRateParameter();
+    vpModel[i]->addRateParameter();
   }
 
   updateMatrices();
@@ -304,7 +306,7 @@ void MixtureOfSubstitutionModels::setVRates(const Vdouble& vd)
 
 Vint MixtureOfSubstitutionModels::getSubmodelNumbers(string& desc) const
 {
-  unsigned int i;
+  size_t i;
   for (i = 0; i < getNumberOfModels(); i++)
   {
     if (getNModel(i)->getName() == desc)
@@ -314,7 +316,7 @@ Vint MixtureOfSubstitutionModels::getSubmodelNumbers(string& desc) const
     throw Exception("MixtureOfSubstitutionModels::getSubmodelNumbers model description do not match " + desc);
 
   Vint submodnb;
-  submodnb.push_back(i);
+  submodnb.push_back(static_cast<int>(i));
 
   return submodnb;
 }
diff --git a/src/Bpp/Phyl/Model/MixtureOfSubstitutionModels.h b/src/Bpp/Phyl/Model/MixtureOfSubstitutionModels.h
index dfbab7a..67b691a 100644
--- a/src/Bpp/Phyl/Model/MixtureOfSubstitutionModels.h
+++ b/src/Bpp/Phyl/Model/MixtureOfSubstitutionModels.h
@@ -5,42 +5,41 @@
 //
 
 /*
-  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.
-*/
+   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 _MIXTUREOFSUBSTITUTIONMODELS_H_
 #define _MIXTUREOFSUBSTITUTIONMODELS_H_
 
-// #include <Bpp/Numeric/Prob.all>
 #include <Bpp/Numeric/VectorTools.h>
 #include "AbstractMixedSubstitutionModel.h"
 
@@ -51,149 +50,145 @@
 
 namespace bpp
 {
+/**
+ * @brief Substitution models defined as a mixture of several
+ * substitution models.
+ * @author Laurent Guéguen
+ *
+ * All the models can be of different types (for example T92 or
+ * GY94), and each model has a specific probability and rate.
+ *
+ *
+ * The probabilities and rates of the models are independent
+ * parameters, handled directly, under the constraint that the
+ * expectation of the rates on the distribution of the models must
+ * equal one.
+ *
+ * If there are @f$n at f$ models, @f$p_i at f$ is the probability of
+ * model i (@f$\sum_{i=1}^{n} p_i = 1 at f$) and the probabilities
+ * are defined by relative probabilities parameters @f$rp_i at f$
+ * (called "relprobai") with:
+ * @f[
+ * 1 <= i < n, p_i = (1-rp_1)*(1-rp_2)...(1-rp_{i-1})*rp_{i}
+ * @f]
+ * @f[
+ * p_n = (1-rp_1)*(1-rp_2)...(1-rp_{n-1})
+ * @f]
+ * and
+ * @f[
+ * \forall 1 <= i < n, rp_i = \frac{p_i}{1-(p_1+...+p_{i-1})}
+ * @f]
+ * where @f$p_i at f$ stands for the probability of model @f$i at f$.
+ *
+ *
+ * If there are @f$n at f$ models, @f$\rho_i at f$ is the rate and @f$p_i at f$
+ * is the probability of model i (@f$\sum_{i=1}^{n} p_i * \rho_i =
+ * 1 at f$), the rates are defined by relative rates parameters
+ * @f$r_i at f$ (called "relratei") with:
+ * @f[
+ * 1 <= i < n, \rho_i = (1-r_1)*(1-r_2)...(1-r_{i-1})*\frac{r_{i}}{p_i}
+ * @f]
+ * @f[
+ * \rho_n = \frac{(1-r_1)*(1-r_2)*...*(1-r_{n-1})}{p_n}
+ * @f]
+ * and
+ * @f[
+ * \forall 1 <= i < n, r_i = \frac{\rho_i*p_i}{1-(p_1*\rho_1+...+p_{i-1}*\rho_{i-1})} < 1.
+ * @f]
+ *
+ * For example:
+ *
+ * Mixture(model1=HKY85(kappa=3), model2=T92(theta=0.1),
+ *         model2=L95(gamma=2), relrate1=0.2, relrate2=0.9,
+ *         relproba1=0.1,relproba2=0.8)
+ *
+ * define a model as a mixture of 3 different models: HKY85 has
+ * probability 0.1 and rate 2, T92 has probability 0.4 and rate 1.8,
+ * and L95 has probability 0.5 and rate 0.16.
+ *
+ *
+ * The parameters are named \c "Mixture.relrate1", \c
+ * "Mixture.relrate2", \c "Mixture.relproba1", \c
+ * "Mixture.relproba2"... in addition to the parameters of the
+ * submodels that are prefixed by "Mixture.i_", where i is the order
+ * of the model.
+ */
+
+class MixtureOfSubstitutionModels :
+  public AbstractMixedSubstitutionModel
+{
+public:
   /**
-   * @brief Substitution models defined as a mixture of several
-   * substitution models.
-   * @author Laurent Guéguen
-   *
-   * All the models can be of different types (for example T92 or
-   * GY94), and each model has a specific probability and rate. 
-   *
-   *
-   * The probabilities and rates of the models are independent
-   * parameters, handled directly, under the constraint that the
-   * expectation of the rates on the distribution of the models must
-   * equal one. 
-   *
-   * If there are @f$n at f$ models, @f$p_i at f$ is the probability of
-   * model i (@f$\sum_{i=1}^{n} p_i = 1 at f$) and the probabilities
-   * are defined by relative probabilities parameters @f$rp_i at f$
-   * (called "relprobai") with:
-   * @f[
-   * 1 <= i < n, p_i = (1-rp_1)*(1-rp_2)...(1-rp_{i-1})*rp_{i}
-   * @f]
-   * @f[
-   * p_n = (1-rp_1)*(1-rp_2)...(1-rp_{n-1})
-   * @f]
-   * and
-   * @f[
-   * \forall 1 <= i < n, rp_i = \frac{p_i}{1-(p_1+...+p_{i-1})}
-   * @f]
-   * where @f$p_i at f$ stands for the probability of model @f$i at f$.
-   *
-   *
-   * If there are @f$n at f$ models, @f$\rho_i at f$ is the rate and @f$p_i at f$
-   * is the probability of model i (@f$\sum_{i=1}^{n} p_i * \rho_i =
-   * 1 at f$), the rates are defined by relative rates parameters
-   * @f$r_i at f$ (called "relratei") with:
-   * @f[
-   * 1 <= i < n, \rho_i = (1-r_1)*(1-r_2)...(1-r_{i-1})*\frac{r_{i}}{p_i} 
-   * @f]
-   * @f[
-   * \rho_n = \frac{(1-r_1)*(1-r_2)*...*(1-r_{n-1})}{p_n}
-   * @f]
-   * and
-   * @f[
-   * \forall 1 <= i < n, r_i = \frac{\rho_i*p_i}{1-(p_1*\rho_1+...+p_{i-1}*\rho_{i-1})} < 1.
-   * @f]
+   * @brief Constructor of a MixtureOfSubstitutionModels, where all
+   * the models have rate 1 and equal probability.
    *
-   * For example:
-   *
-   * Mixture(model1=HKY85(kappa=3), model2=T92(theta=0.1),
-   *         model2=L95(gamma=2), relrate1=0.2, relrate2=0.9,
-   *         relproba1=0.1,relproba2=0.8)
+   * @param alpha pointer to the Alphabet
+   * @param vpModel vector of pointers to SubstitutionModels. All the
+   *   SubstitutionModels are owned by the instance.
+   * @warning providing a vpModel with size 0 will generate a segmentation fault!
+   */
+  MixtureOfSubstitutionModels(
+      const Alphabet* alpha,
+      std::vector<SubstitutionModel*> vpModel);
+
+  /**
+   * @brief Constructor of a MixtureOfSubstitutionModels.
    *
-   * define a model as a mixture of 3 different models: HKY85 has
-   * probability 0.1 and rate 2, T92 has probability 0.4 and rate 1.8,
-   * and L95 has probability 0.5 and rate 0.16.
+   * @param alpha pointer to the Alphabet
+   * @param vpModel vector of pointers to SubstitutionModels. All the
+   *   SubstitutionModels are owned by the instance.
+   * @param vproba vector of the probabilities of the models
+   * @param vrate vector of the rates of the models
+   * @warning providing a vpModel with size 0 will generate a segmentation fault!
    *
+   * See above the constraints on the rates and the probabilities of
+   * the vectors.
+   */
+
+  MixtureOfSubstitutionModels(
+      const Alphabet* alpha,
+      std::vector<SubstitutionModel*> vpModel,
+      Vdouble& vproba, Vdouble& vrate);
+
+  MixtureOfSubstitutionModels(const MixtureOfSubstitutionModels&);
+
+  MixtureOfSubstitutionModels& operator=(const MixtureOfSubstitutionModels&);
+
+  virtual ~MixtureOfSubstitutionModels();
+
+  MixtureOfSubstitutionModels* clone() const { return new MixtureOfSubstitutionModels(*this); }
+
+public:
+  std::string getName() const { return "Mixture"; }
+
+  void updateMatrices();
+
+  /**
+   * @brief Sets the rates of the submodels to follow the constraint
+   * that the mean rate of the mixture equals rate_.
+   * @param vd a vector of positive values such that the rates of
+   * the respective submodels are in the same proportions (ie this
+   * vector does not need to be normalized).
+   */
+  virtual void setVRates(const Vdouble& vd);
+
+  /**
+   * @brief Returns the vector of numbers of the submodels in the
+   * mixture that match a description of the parameters numbers.
    *
-   * The parameters are named \c "Mixture.relrate1", \c
-   * "Mixture.relrate2", \c "Mixture.relproba1", \c
-   * "Mixture.relproba2"... in addition to the parameters of the
-   * submodels that are prefixed by "Mixture.i_", where i is the order
-   * of the model.
+   * @param desc is the description of the class indexes of the mixed
+   * parameters. Syntax is like: kappa_1,gamma_3,delta_2
+   */
+  Vint getSubmodelNumbers(std::string& desc) const;
 
+  /**
+   * @brief applies setFreq to all the models of the mixture and
+   * recovers the parameters values.
    */
+  void setFreq(std::map<int, double>&);
 
-  class MixtureOfSubstitutionModels :
-    public AbstractMixedSubstitutionModel
-  {
-  public:
-
-    /*
-     *@brief Constructor of a MixtureOfSubstitutionModels, where all
-     *the models have rate 1 and equal probability.
-     *
-     *@param alpha pointer to the Alphabet
-     *@param vpModel vector of pointers to SubstitutionModels. All the
-     *   SubstitutionModels are owned by the instance.
-     */
-    
-    MixtureOfSubstitutionModels(const Alphabet* alpha,
-                                std::vector<SubstitutionModel*> vpModel);
-    
-    /*
-     *@brief Constructor of a MixtureOfSubstitutionModels.
-     *
-     *@param alpha pointer to the Alphabet
-     *@param vpModel vector of pointers to SubstitutionModels. All the
-     *   SubstitutionModels are owned by the instance.
-     *@param vproba vector of the probabilities of the models
-     *@param vrate vector of the rates of the models
-     *
-     * See above the constraints on the rates and the probabilities of
-     * the vectors.
-     */
-    
-    MixtureOfSubstitutionModels(const Alphabet* alpha,
-                                std::vector<SubstitutionModel*> vpModel,
-                                Vdouble& vproba, Vdouble& vrate);
-
-    MixtureOfSubstitutionModels(const MixtureOfSubstitutionModels&);
-    
-    MixtureOfSubstitutionModels& operator=(const MixtureOfSubstitutionModels&);
-    
-    ~MixtureOfSubstitutionModels();
-    
-    MixtureOfSubstitutionModels* clone() const { return new MixtureOfSubstitutionModels(*this); }
-
-  public:
-    std::string getName() const { return "Mixture"; }
-
-    void updateMatrices();
-  
-    /**
-     * @brief Sets the rates of the submodels to follow the constraint
-     * that the mean rate of the mixture equals rate_.
-     
-     * @param vd a vector of positive values such that the rates of
-     * the respective submodels are in the same proportions (ie this
-     * vector does not need to be normalized).
-     */
-
-    virtual void setVRates(const Vdouble& vd);
-
-    /*
-     *@brief Returns the vector of numbers of the submodels in the
-     *mixture that match a description of the parameters numbers.
-     *
-     *@param desc is the description of the class indexes of the mixed
-     *parameters. Syntax is like: kappa_1,gamma_3,delta_2
-     *
-     */
-  
-    Vint getSubmodelNumbers(std::string& desc) const;
-
-    /**
-     * @brief applies setFreq to all the models of the mixture and
-     * recovers the parameters values.
-     *
-     **/
-  
-    void setFreq(std::map<int,double>&);
-
-  };
+};
 } // end of namespace bpp.
 
 #endif  // _MIXTUREOFSUBSTITUTIONMODELS_H_
+
diff --git a/src/Bpp/Phyl/Model/Nucleotide/F84.cpp b/src/Bpp/Phyl/Model/Nucleotide/F84.cpp
index 11f2e49..a74cd58 100644
--- a/src/Bpp/Phyl/Model/Nucleotide/F84.cpp
+++ b/src/Bpp/Phyl/Model/Nucleotide/F84.cpp
@@ -61,8 +61,7 @@ F84::F84(
     double piG,
     double piT) :
   AbstractParameterAliasable("F84."),
-  AbstractSubstitutionModel(alpha, "F84."),
-  AbstractReversibleSubstitutionModel(alpha, "F84."),
+  AbstractReversibleSubstitutionModel(alpha, new CanonicalStateMap(alpha, false), "F84."),
   kappa_(kappa), piA_(piA), piC_(piC), piG_(piG), piT_(piT), piY_(), piR_(),
   r_(), k1_(), k2_(), theta_(piG + piC), theta1_(piA / (1. - theta_)), theta2_(piG / theta_),
   l_(), exp1_(), exp2_(), p_(size_, size_)
@@ -192,7 +191,7 @@ void F84::updateMatrices()
   
 /******************************************************************************/
 
-double F84::Pij_t(int i, int j, double d) const
+double F84::Pij_t(size_t i, size_t j, double d) const
 {
   l_ = rate_ * r_ * d;
   exp1_ = exp(-k1_*l_);
@@ -241,7 +240,7 @@ double F84::Pij_t(int i, int j, double d) const
 
 /******************************************************************************/
 
-double F84::dPij_dt(int i, int j, double d) const
+double F84::dPij_dt(size_t i, size_t j, double d) const
 {
   l_ = rate_ * r_ * d;
   exp1_ = exp(-k1_*l_);
@@ -290,7 +289,7 @@ double F84::dPij_dt(int i, int j, double d) const
 
 /******************************************************************************/
 
-double F84::d2Pij_dt2(int i, int j, double d) const
+double F84::d2Pij_dt2(size_t i, size_t j, double d) const
 {
   double r_2 = rate_ * rate_ * r_ * r_;
   l_ = rate_ * r_ * d;
diff --git a/src/Bpp/Phyl/Model/Nucleotide/F84.h b/src/Bpp/Phyl/Model/Nucleotide/F84.h
index 99c1422..23611a9 100644
--- a/src/Bpp/Phyl/Model/Nucleotide/F84.h
+++ b/src/Bpp/Phyl/Model/Nucleotide/F84.h
@@ -5,7 +5,7 @@
 //
 
 /*
-Copyright or © or Copr. CNRS, (November 16, 2004)
+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.
@@ -204,12 +204,12 @@ class F84:
 
   public:
 
-    double Pij_t    (int i, int j, double d) const;
-    double dPij_dt  (int i, int j, double d) const;
-    double d2Pij_dt2(int i, int j, double d) const;
-    const Matrix<double> & getPij_t    (double d) const;
-    const Matrix<double> & getdPij_dt  (double d) const;
-    const Matrix<double> & getd2Pij_dt2(double d) const;
+    double Pij_t    (size_t i, size_t j, double d) const;
+    double dPij_dt  (size_t i, size_t j, double d) const;
+    double d2Pij_dt2(size_t i, size_t j, double d) const;
+    const Matrix<double>& getPij_t    (double d) const;
+    const Matrix<double>& getdPij_dt  (double d) const;
+    const Matrix<double>& getd2Pij_dt2(double d) const;
 
     std::string getName() const { return "F84"; }
 
diff --git a/src/Bpp/Phyl/Model/Nucleotide/GTR.cpp b/src/Bpp/Phyl/Model/Nucleotide/GTR.cpp
index 736f38e..f0b6ecf 100755
--- a/src/Bpp/Phyl/Model/Nucleotide/GTR.cpp
+++ b/src/Bpp/Phyl/Model/Nucleotide/GTR.cpp
@@ -65,8 +65,7 @@ GTR::GTR(
     double piG,
     double piT) :
   AbstractParameterAliasable("GTR."),
-  AbstractSubstitutionModel(alpha, "GTR."),
-  AbstractReversibleSubstitutionModel(alpha, "GTR."),
+  AbstractReversibleSubstitutionModel(alpha, new CanonicalStateMap(alpha, false), "GTR."),
   a_(a), b_(b), c_(c), d_(d), e_(e), piA_(piA), piC_(piC), piG_(piG), piT_(piT), theta_(piG + piC), theta1_(piA / (1. - theta_)), theta2_(piG / theta_), p_()
 {
   addParameter_(new Parameter("GTR.a", a, &Parameter::R_PLUS_STAR));
diff --git a/src/Bpp/Phyl/Model/Nucleotide/HKY85.cpp b/src/Bpp/Phyl/Model/Nucleotide/HKY85.cpp
index 574b66f..483b275 100755
--- a/src/Bpp/Phyl/Model/Nucleotide/HKY85.cpp
+++ b/src/Bpp/Phyl/Model/Nucleotide/HKY85.cpp
@@ -5,36 +5,36 @@
 //
 
 /*
-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.
+  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 "HKY85.h"
@@ -55,295 +55,294 @@ using namespace std;
 /******************************************************************************/
 
 HKY85::HKY85(
-	const NucleicAlphabet* alpha,
-	double kappa,
-	double piA,
-	double piC,
-	double piG,
-	double piT):
+  const NucleicAlphabet* alpha,
+  double kappa,
+  double piA,
+  double piC,
+  double piG,
+  double piT):
   AbstractParameterAliasable("HKY85."),
-  AbstractSubstitutionModel(alpha, "HKY85."),
-  AbstractReversibleSubstitutionModel(alpha, "HKY85."),
+  AbstractReversibleSubstitutionModel(alpha, new CanonicalStateMap(alpha, false), "HKY85."),
   kappa_(kappa), k1_(), k2_(), r_(),
   piA_(piA), piC_(piC), piG_(piG), piT_(piT), piY_(), piR_(),
   theta_(piG + piC), theta1_(piA / (1. - theta_)), theta2_(piG / theta_),
   exp1_(), exp21_(), exp22_(), l_(), p_(size_, size_)
 {
-	addParameter_(new Parameter("HKY85.kappa", kappa, &Parameter::R_PLUS_STAR));
-	addParameter_(new Parameter("HKY85.theta" , theta_, &FrequenciesSet::FREQUENCE_CONSTRAINT_SMALL));
-	addParameter_(new Parameter("HKY85.theta1", theta1_, &FrequenciesSet::FREQUENCE_CONSTRAINT_SMALL));
-	addParameter_(new Parameter("HKY85.theta2", theta2_, &FrequenciesSet::FREQUENCE_CONSTRAINT_SMALL));
-	updateMatrices();
+  addParameter_(new Parameter("HKY85.kappa", kappa, &Parameter::R_PLUS_STAR));
+  addParameter_(new Parameter("HKY85.theta" , theta_, &FrequenciesSet::FREQUENCE_CONSTRAINT_SMALL));
+  addParameter_(new Parameter("HKY85.theta1", theta1_, &FrequenciesSet::FREQUENCE_CONSTRAINT_SMALL));
+  addParameter_(new Parameter("HKY85.theta2", theta2_, &FrequenciesSet::FREQUENCE_CONSTRAINT_SMALL));
+  updateMatrices();
 }
 
 /******************************************************************************/
 
 void HKY85::updateMatrices()
 {
-	kappa_  = getParameterValue("kappa");
-	theta_  = getParameterValue("theta");
-	theta1_ = getParameterValue("theta1");
-	theta2_ = getParameterValue("theta2");
+  kappa_  = getParameterValue("kappa");
+  theta_  = getParameterValue("theta");
+  theta1_ = getParameterValue("theta1");
+  theta2_ = getParameterValue("theta2");
   piA_ = theta1_ * (1. - theta_);
   piC_ = (1. - theta2_) * theta_;
   piG_ = theta2_ * theta_;
   piT_ = (1. - theta1_) * (1. - theta_);
-	piR_   = piA_ + piG_;
-	piY_   = piT_ + piC_;
-	k1_    = kappa_ * piY_ + piR_;
-	k2_    = kappa_ * piR_ + piY_;
+  piR_   = piA_ + piG_;
+  piY_   = piT_ + piC_;
+  k1_    = kappa_ * piY_ + piR_;
+  k2_    = kappa_ * piR_ + piY_;
 
   freq_[0] = piA_;
   freq_[1] = piC_;
   freq_[2] = piG_;
   freq_[3] = piT_;
 	
-	generator_(0, 0) = -(                     piC_ + kappa_*piG_ +        piT_);
-	generator_(1, 1) = -(       piA_ +                      piG_ + kappa_*piT_); 
-	generator_(2, 2) = -(kappa_*piA_ +        piC_               +       piT_);
-	generator_(3, 3) = -(       piA_ + kappa_*piC_ +        piG_             );
-
-	generator_(1, 0) = piA_;
-	generator_(3, 0) = piA_;
-	generator_(0, 1) = piC_;
-	generator_(2, 1) = piC_;
-	generator_(1, 2) = piG_;
-	generator_(3, 2) = piG_;
-	generator_(0, 3) = piT_;
-	generator_(2, 3) = piT_;
+  generator_(0, 0) = -(                     piC_ + kappa_*piG_ +        piT_);
+  generator_(1, 1) = -(       piA_ +                      piG_ + kappa_*piT_); 
+  generator_(2, 2) = -(kappa_*piA_ +        piC_               +       piT_);
+  generator_(3, 3) = -(       piA_ + kappa_*piC_ +        piG_             );
+
+  generator_(1, 0) = piA_;
+  generator_(3, 0) = piA_;
+  generator_(0, 1) = piC_;
+  generator_(2, 1) = piC_;
+  generator_(1, 2) = piG_;
+  generator_(3, 2) = piG_;
+  generator_(0, 3) = piT_;
+  generator_(2, 3) = piT_;
 	
-	generator_(2, 0) = kappa_ * piA_;
-	generator_(3, 1) = kappa_ * piC_;
-	generator_(0, 2) = kappa_ * piG_;
-	generator_(1, 3) = kappa_ * piT_;
+  generator_(2, 0) = kappa_ * piA_;
+  generator_(3, 1) = kappa_ * piC_;
+  generator_(0, 2) = kappa_ * piG_;
+  generator_(1, 3) = kappa_ * piT_;
 	
-	// Normalization:
-	r_ = 1. / (2. * (piA_ * piC_ + piC_ * piG_ + piA_ * piT_ + piG_ * piT_ + kappa_ * (piC_ * piT_ + piA_ * piG_)));
-	MatrixTools::scale(generator_, r_);
+  // Normalization:
+  r_ = 1. / (2. * (piA_ * piC_ + piC_ * piG_ + piA_ * piT_ + piG_ * piT_ + kappa_ * (piC_ * piT_ + piA_ * piG_)));
+  MatrixTools::scale(generator_, r_);
 	
-	// Exchangeability:
-	exchangeability_(0,0) = generator_(0,0) / piA_;
-	exchangeability_(0,1) = generator_(0,1) / piC_; 
-	exchangeability_(0,2) = generator_(0,2) / piG_; 
-	exchangeability_(0,3) = generator_(0,3) / piT_;
-
-	exchangeability_(1,0) = generator_(1,0) / piA_; 
-	exchangeability_(1,1) = generator_(1,1) / piC_; 
-	exchangeability_(1,2) = generator_(1,2) / piG_; 
-	exchangeability_(1,3) = generator_(1,3) / piT_; 
+  // Exchangeability:
+  exchangeability_(0,0) = generator_(0,0) / piA_;
+  exchangeability_(0,1) = generator_(0,1) / piC_; 
+  exchangeability_(0,2) = generator_(0,2) / piG_; 
+  exchangeability_(0,3) = generator_(0,3) / piT_;
+
+  exchangeability_(1,0) = generator_(1,0) / piA_; 
+  exchangeability_(1,1) = generator_(1,1) / piC_; 
+  exchangeability_(1,2) = generator_(1,2) / piG_; 
+  exchangeability_(1,3) = generator_(1,3) / piT_; 
 	
-	exchangeability_(2,0) = generator_(2,0) / piA_; 
-	exchangeability_(2,1) = generator_(2,1) / piC_; 
-	exchangeability_(2,2) = generator_(2,2) / piG_; 
-	exchangeability_(2,3) = generator_(2,3) / piT_; 
+  exchangeability_(2,0) = generator_(2,0) / piA_; 
+  exchangeability_(2,1) = generator_(2,1) / piC_; 
+  exchangeability_(2,2) = generator_(2,2) / piG_; 
+  exchangeability_(2,3) = generator_(2,3) / piT_; 
 	
-	exchangeability_(3,0) = generator_(3,0) / piA_;
-	exchangeability_(3,1) = generator_(3,1) / piC_; 
-	exchangeability_(3,2) = generator_(3,2) / piG_; 
-	exchangeability_(3,3) = generator_(3,3) / piT_;
-
-	// Eigen values:
-	eigenValues_[0] = 0;
-	eigenValues_[1] = -r_ * (kappa_ * piY_ + piR_);
-	eigenValues_[2] = -r_ * (kappa_ * piR_ + piY_); 
-	eigenValues_[3] = -r_;
+  exchangeability_(3,0) = generator_(3,0) / piA_;
+  exchangeability_(3,1) = generator_(3,1) / piC_; 
+  exchangeability_(3,2) = generator_(3,2) / piG_; 
+  exchangeability_(3,3) = generator_(3,3) / piT_;
+
+  // Eigen values:
+  eigenValues_[0] = 0;
+  eigenValues_[1] = -r_ * (kappa_ * piY_ + piR_);
+  eigenValues_[2] = -r_ * (kappa_ * piR_ + piY_); 
+  eigenValues_[3] = -r_;
 	
-	// Eigen vectors:
-	leftEigenVectors_(0,0) = piA_;
-	leftEigenVectors_(0,1) = piC_;
-	leftEigenVectors_(0,2) = piG_;
-	leftEigenVectors_(0,3) = piT_;
-
-	leftEigenVectors_(1,0) = 0.;
-	leftEigenVectors_(1,1) = piT_ / piY_;
-	leftEigenVectors_(1,2) = 0.;
-	leftEigenVectors_(1,3) = -piT_ / piY_;
-
-	leftEigenVectors_(2,0) = piG_ / piR_;
-	leftEigenVectors_(2,1) = 0.;
-	leftEigenVectors_(2,2) = -piG_ / piR_;
-	leftEigenVectors_(2,3) = 0.;
-
-	leftEigenVectors_(3,0) = piA_*piY_ / piR_;
-	leftEigenVectors_(3,1) = -piC_;
-	leftEigenVectors_(3,2) = piG_*piY_ / piR_;
-	leftEigenVectors_(3,3) = -piT_;
-
-	rightEigenVectors_(0,0) = 1.;
-	rightEigenVectors_(0,1) = 0.;
-	rightEigenVectors_(0,2) = 1.;
-	rightEigenVectors_(0,3) = 1.;
+  // Eigen vectors:
+  leftEigenVectors_(0,0) = piA_;
+  leftEigenVectors_(0,1) = piC_;
+  leftEigenVectors_(0,2) = piG_;
+  leftEigenVectors_(0,3) = piT_;
+
+  leftEigenVectors_(1,0) = 0.;
+  leftEigenVectors_(1,1) = piT_ / piY_;
+  leftEigenVectors_(1,2) = 0.;
+  leftEigenVectors_(1,3) = -piT_ / piY_;
+
+  leftEigenVectors_(2,0) = piG_ / piR_;
+  leftEigenVectors_(2,1) = 0.;
+  leftEigenVectors_(2,2) = -piG_ / piR_;
+  leftEigenVectors_(2,3) = 0.;
+
+  leftEigenVectors_(3,0) = piA_*piY_ / piR_;
+  leftEigenVectors_(3,1) = -piC_;
+  leftEigenVectors_(3,2) = piG_*piY_ / piR_;
+  leftEigenVectors_(3,3) = -piT_;
+
+  rightEigenVectors_(0,0) = 1.;
+  rightEigenVectors_(0,1) = 0.;
+  rightEigenVectors_(0,2) = 1.;
+  rightEigenVectors_(0,3) = 1.;
 	
-	rightEigenVectors_(1,0) = 1.;
-	rightEigenVectors_(1,1) = 1.;
-	rightEigenVectors_(1,2) = 0.;;
-	rightEigenVectors_(1,3) = -piR_ / piY_;
-
-	rightEigenVectors_(2,0) = 1.;
-	rightEigenVectors_(2,1) = 0.;
-	rightEigenVectors_(2,2) = -piA_ / piG_;
-	rightEigenVectors_(2,3) = 1.;
-
-	rightEigenVectors_(3,0) = 1.;
-	rightEigenVectors_(3,1) = -piC_ / piT_;
-	rightEigenVectors_(3,2) = 0.;
-	rightEigenVectors_(3,3) = -piR_ / piY_;
+  rightEigenVectors_(1,0) = 1.;
+  rightEigenVectors_(1,1) = 1.;
+  rightEigenVectors_(1,2) = 0.;;
+  rightEigenVectors_(1,3) = -piR_ / piY_;
+
+  rightEigenVectors_(2,0) = 1.;
+  rightEigenVectors_(2,1) = 0.;
+  rightEigenVectors_(2,2) = -piA_ / piG_;
+  rightEigenVectors_(2,3) = 1.;
+
+  rightEigenVectors_(3,0) = 1.;
+  rightEigenVectors_(3,1) = -piC_ / piT_;
+  rightEigenVectors_(3,2) = 0.;
+  rightEigenVectors_(3,3) = -piR_ / piY_;
 }
 	
 /******************************************************************************/
 
-double HKY85::Pij_t(int i, int j, double d) const
+double HKY85::Pij_t(size_t i, size_t j, double d) const
 {
-	l_     = rate_ * r_ * d;
-	exp1_  = exp(-l_);
-	exp22_ = exp(-k2_ * l_);
-	exp21_ = exp(-k1_ * l_);
+  l_     = rate_ * r_ * d;
+  exp1_  = exp(-l_);
+  exp22_ = exp(-k2_ * l_);
+  exp21_ = exp(-k1_ * l_);
 	
-	switch(i)
+  switch(i)
   {
-		//A
-		case 0 : {
-			switch(j) {
-				case 0 : return piA_ * (1. + (piY_/piR_) * exp1_) + (piG_/piR_) * exp22_; //A
-				case 1 : return piC_ * (1. -               exp1_);                        //C
-				case 2 : return piG_ * (1. + (piY_/piR_) * exp1_) - (piG_/piR_) * exp22_; //G
-				case 3 : return piT_ * (1. -               exp1_);                        //T, U
-			}
-		} 
-		//C
-		case 1 : {
-			switch(j) {
-				case 0 : return piA_ * (1. -               exp1_);                        //A
-				case 1 : return piC_ * (1. + (piR_/piY_) * exp1_) + (piT_/piY_) * exp21_; //C
-				case 2 : return piG_ * (1. -               exp1_);                        //G
-				case 3 : return piT_ * (1. + (piR_/piY_) * exp1_) - (piT_/piY_) * exp21_; //T, U
-			}
-		}
-		//G
-		case 2 : {
-			switch(j) {
-				case 0 : return piA_ * (1. + (piY_/piR_) * exp1_) - (piA_/piR_) * exp22_; //A
-				case 1 : return piC_ * (1. -               exp1_);                        //C
-				case 2 : return piG_ * (1. + (piY_/piR_) * exp1_) + (piA_/piR_) * exp22_; //G
-				case 3 : return piT_ * (1. -               exp1_);                        //T, U
-			}
-		}
-		//T, U
-		case 3 : {
-			switch(j) {
-				case 0 : return piA_ * (1. -               exp1_);                        //A
-				case 1 : return piC_ * (1. + (piR_/piY_) * exp1_) - (piC_/piY_) * exp21_; //C
-				case 2 : return piG_ * (1. -               exp1_);                        //G
-				case 3 : return piT_ * (1. + (piR_/piY_) * exp1_) + (piC_/piY_) * exp21_; //T, U
-			}
-		}
-	}
-	return 0;
+    //A
+  case 0 : {
+    switch(j) {
+    case 0 : return piA_ * (1. + (piY_/piR_) * exp1_) + (piG_/piR_) * exp22_; //A
+    case 1 : return piC_ * (1. -               exp1_);                        //C
+    case 2 : return piG_ * (1. + (piY_/piR_) * exp1_) - (piG_/piR_) * exp22_; //G
+    case 3 : return piT_ * (1. -               exp1_);                        //T, U
+    }
+  } 
+    //C
+  case 1 : {
+    switch(j) {
+    case 0 : return piA_ * (1. -               exp1_);                        //A
+    case 1 : return piC_ * (1. + (piR_/piY_) * exp1_) + (piT_/piY_) * exp21_; //C
+    case 2 : return piG_ * (1. -               exp1_);                        //G
+    case 3 : return piT_ * (1. + (piR_/piY_) * exp1_) - (piT_/piY_) * exp21_; //T, U
+    }
+  }
+    //G
+  case 2 : {
+    switch(j) {
+    case 0 : return piA_ * (1. + (piY_/piR_) * exp1_) - (piA_/piR_) * exp22_; //A
+    case 1 : return piC_ * (1. -               exp1_);                        //C
+    case 2 : return piG_ * (1. + (piY_/piR_) * exp1_) + (piA_/piR_) * exp22_; //G
+    case 3 : return piT_ * (1. -               exp1_);                        //T, U
+    }
+  }
+    //T, U
+  case 3 : {
+    switch(j) {
+    case 0 : return piA_ * (1. -               exp1_);                        //A
+    case 1 : return piC_ * (1. + (piR_/piY_) * exp1_) - (piC_/piY_) * exp21_; //C
+    case 2 : return piG_ * (1. -               exp1_);                        //G
+    case 3 : return piT_ * (1. + (piR_/piY_) * exp1_) + (piC_/piY_) * exp21_; //T, U
+    }
+  }
+  }
+  return 0;
 }
 
 /******************************************************************************/
 
-double HKY85::dPij_dt(int i, int j, double d) const
+double HKY85::dPij_dt(size_t i, size_t j, double d) const
 {
-	l_     = rate_ * r_ * d;
-	exp1_  = exp(-l_);
-	exp22_ = exp(-k2_ * l_);
-	exp21_ = exp(-k1_ * l_);
+  l_     = rate_ * r_ * d;
+  exp1_  = exp(-l_);
+  exp22_ = exp(-k2_ * l_);
+  exp21_ = exp(-k1_ * l_);
 	
-	switch(i)
+  switch(i)
   {
-		//A
-		case 0 : {
-			switch(j) {
-				case 0 : return rate_ * r_ * (piA_ * -(piY_/piR_) * exp1_ - (piG_/piR_) * k2_ * exp22_); //A
-				case 1 : return rate_ * r_ * (piC_ *                exp1_);                              //C
-				case 2 : return rate_ * r_ * (piG_ * -(piY_/piR_) * exp1_ + (piG_/piR_) * k2_ * exp22_); //G
-				case 3 : return rate_ * r_ * (piT_ *                exp1_);                              //T, U
-			}
-		} 
-		//C
-		case 1 : {
-			switch(j) {
-				case 0 : return rate_ * r_ * (piA_ *                exp1_);                              //A
-				case 1 : return rate_ * r_ * (piC_ * -(piR_/piY_) * exp1_ - (piT_/piY_) * k1_ * exp21_); //C
-				case 2 : return rate_ * r_ * (piG_ *                exp1_);                              //G
-				case 3 : return rate_ * r_ * (piT_ * -(piR_/piY_) * exp1_ + (piT_/piY_) * k1_ * exp21_); //T, U
-			}
-		}
-		//G
-		case 2 : {
-			switch(j) {
-				case 0 : return rate_ * r_ * (piA_ * -(piY_/piR_) * exp1_ + (piA_/piR_) * k2_ * exp22_); //A
-				case 1 : return rate_ * r_ * (piC_ *                exp1_);                              //C
-				case 2 : return rate_ * r_ * (piG_ * -(piY_/piR_) * exp1_ - (piA_/piR_) * k2_ * exp22_); //G
-				case 3 : return rate_ * r_ * (piT_ *                exp1_);                              //T, U
-			}
-		}
-		//T, U
-		case 3 : {
-			switch(j) {
-				case 0 : return rate_ * r_ * (piA_ *                exp1_);                              //A
-				case 1 : return rate_ * r_ * (piC_ * -(piR_/piY_) * exp1_ + (piC_/piY_) * k1_ * exp21_); //C
-				case 2 : return rate_ * r_ * (piG_ *                exp1_);                              //G
-				case 3 : return rate_ * r_ * (piT_ * -(piR_/piY_) * exp1_ - (piC_/piY_) * k1_ * exp21_); //T, U
-			}
-		}
-	}
-	return 0;
+    //A
+  case 0 : {
+    switch(j) {
+    case 0 : return rate_ * r_ * (piA_ * -(piY_/piR_) * exp1_ - (piG_/piR_) * k2_ * exp22_); //A
+    case 1 : return rate_ * r_ * (piC_ *                exp1_);                              //C
+    case 2 : return rate_ * r_ * (piG_ * -(piY_/piR_) * exp1_ + (piG_/piR_) * k2_ * exp22_); //G
+    case 3 : return rate_ * r_ * (piT_ *                exp1_);                              //T, U
+    }
+  } 
+    //C
+  case 1 : {
+    switch(j) {
+    case 0 : return rate_ * r_ * (piA_ *                exp1_);                              //A
+    case 1 : return rate_ * r_ * (piC_ * -(piR_/piY_) * exp1_ - (piT_/piY_) * k1_ * exp21_); //C
+    case 2 : return rate_ * r_ * (piG_ *                exp1_);                              //G
+    case 3 : return rate_ * r_ * (piT_ * -(piR_/piY_) * exp1_ + (piT_/piY_) * k1_ * exp21_); //T, U
+    }
+  }
+    //G
+  case 2 : {
+    switch(j) {
+    case 0 : return rate_ * r_ * (piA_ * -(piY_/piR_) * exp1_ + (piA_/piR_) * k2_ * exp22_); //A
+    case 1 : return rate_ * r_ * (piC_ *                exp1_);                              //C
+    case 2 : return rate_ * r_ * (piG_ * -(piY_/piR_) * exp1_ - (piA_/piR_) * k2_ * exp22_); //G
+    case 3 : return rate_ * r_ * (piT_ *                exp1_);                              //T, U
+    }
+  }
+    //T, U
+  case 3 : {
+    switch(j) {
+    case 0 : return rate_ * r_ * (piA_ *                exp1_);                              //A
+    case 1 : return rate_ * r_ * (piC_ * -(piR_/piY_) * exp1_ + (piC_/piY_) * k1_ * exp21_); //C
+    case 2 : return rate_ * r_ * (piG_ *                exp1_);                              //G
+    case 3 : return rate_ * r_ * (piT_ * -(piR_/piY_) * exp1_ - (piC_/piY_) * k1_ * exp21_); //T, U
+    }
+  }
+  }
+  return 0;
 }
 
 /******************************************************************************/
 
-double HKY85::d2Pij_dt2(int i, int j, double d) const
+double HKY85::d2Pij_dt2(size_t i, size_t j, double d) const
 {
-	double r_2 = rate_ * rate_ * r_ * r_;
-	l_ = rate_ * r_ * d;
-	double k1_2 = k1_ * k1_;
-	double k2_2 = k2_ * k2_;
-	exp1_ = exp(-l_);
-	exp22_ = exp(-k2_ * l_);
-	exp21_ = exp(-k1_ * l_);
+  double r_2 = rate_ * rate_ * r_ * r_;
+  l_ = rate_ * r_ * d;
+  double k1_2 = k1_ * k1_;
+  double k2_2 = k2_ * k2_;
+  exp1_ = exp(-l_);
+  exp22_ = exp(-k2_ * l_);
+  exp21_ = exp(-k1_ * l_);
 	
-	switch(i)
+  switch(i)
   {
-		//A
-		case 0 : {
-			switch(j) {
-				case 0 : return r_2 * (piA_ * (piY_/piR_) * exp1_ + (piG_/piR_) * k2_2 * exp22_); //A
-				case 1 : return r_2 * (piC_ *             - exp1_);                               //C
-				case 2 : return r_2 * (piG_ * (piY_/piR_) * exp1_ - (piG_/piR_) * k2_2 * exp22_); //G
-				case 3 : return r_2 * (piT_ *             - exp1_);                               //T, U
-			}
-		} 
-		//C
-		case 1 : {
-			switch(j) {
-				case 0 : return r_2 * (piA_ *             - exp1_);                               //A
-				case 1 : return r_2 * (piC_ * (piR_/piY_) * exp1_ + (piT_/piY_) * k1_2 * exp21_); //C
-				case 2 : return r_2 * (piG_ *             - exp1_);                               //G
-				case 3 : return r_2 * (piT_ * (piR_/piY_) * exp1_ - (piT_/piY_) * k1_2 * exp21_); //T, U
-			}
-		}
-		//G
-		case 2 : {
-			switch(j) {
-				case 0 : return r_2 * (piA_ * (piY_/piR_) * exp1_ - (piA_/piR_) * k2_2 * exp22_); //A
-				case 1 : return r_2 * (piC_ *             - exp1_);                               //C
-				case 2 : return r_2 * (piG_ * (piY_/piR_) * exp1_ + (piA_/piR_) * k2_2 * exp22_); //G
-				case 3 : return r_2 * (piT_ *             - exp1_);                               //T, U
-			}
-		}
-		//T, U
-		case 3 : {
-			switch(j) {
-				case 0 : return r_2 * (piA_ *             - exp1_);                              //A
-				case 1 : return r_2 * (piC_ * (piR_/piY_) * exp1_ - (piC_/piY_) * k1_2 * exp21_); //C
-				case 2 : return r_2 * (piG_ *             - exp1_);                              //G
-				case 3 : return r_2 * (piT_ * (piR_/piY_) * exp1_ + (piC_/piY_) * k1_2 * exp21_); //T, U
-			}
-		}
-	}
-	return 0;
+    //A
+  case 0 : {
+    switch(j) {
+    case 0 : return r_2 * (piA_ * (piY_/piR_) * exp1_ + (piG_/piR_) * k2_2 * exp22_); //A
+    case 1 : return r_2 * (piC_ *             - exp1_);                               //C
+    case 2 : return r_2 * (piG_ * (piY_/piR_) * exp1_ - (piG_/piR_) * k2_2 * exp22_); //G
+    case 3 : return r_2 * (piT_ *             - exp1_);                               //T, U
+    }
+  } 
+    //C
+  case 1 : {
+    switch(j) {
+    case 0 : return r_2 * (piA_ *             - exp1_);                               //A
+    case 1 : return r_2 * (piC_ * (piR_/piY_) * exp1_ + (piT_/piY_) * k1_2 * exp21_); //C
+    case 2 : return r_2 * (piG_ *             - exp1_);                               //G
+    case 3 : return r_2 * (piT_ * (piR_/piY_) * exp1_ - (piT_/piY_) * k1_2 * exp21_); //T, U
+    }
+  }
+    //G
+  case 2 : {
+    switch(j) {
+    case 0 : return r_2 * (piA_ * (piY_/piR_) * exp1_ - (piA_/piR_) * k2_2 * exp22_); //A
+    case 1 : return r_2 * (piC_ *             - exp1_);                               //C
+    case 2 : return r_2 * (piG_ * (piY_/piR_) * exp1_ + (piA_/piR_) * k2_2 * exp22_); //G
+    case 3 : return r_2 * (piT_ *             - exp1_);                               //T, U
+    }
+  }
+    //T, U
+  case 3 : {
+    switch(j) {
+    case 0 : return r_2 * (piA_ *             - exp1_);                              //A
+    case 1 : return r_2 * (piC_ * (piR_/piY_) * exp1_ - (piC_/piY_) * k1_2 * exp21_); //C
+    case 2 : return r_2 * (piG_ *             - exp1_);                              //G
+    case 3 : return r_2 * (piT_ * (piR_/piY_) * exp1_ + (piC_/piY_) * k1_2 * exp21_); //T, U
+    }
+  }
+  }
+  return 0;
 }
 
 /******************************************************************************/
@@ -351,106 +350,106 @@ double HKY85::d2Pij_dt2(int i, int j, double d) const
 const Matrix<double> & HKY85::getPij_t(double d) const
 {
   l_ = rate_ * r_ * d;
-	exp1_ = exp(-l_);
-	exp22_ = exp(-k2_ * l_);
-	exp21_ = exp(-k1_ * l_);
-
-	//A
-	p_(0, 0) = piA_ * (1. + (piY_/piR_) * exp1_) + (piG_/piR_) * exp22_; //A
-	p_(0, 1) = piC_ * (1. -               exp1_);                        //C
-	p_(0, 2) = piG_ * (1. + (piY_/piR_) * exp1_) - (piG_/piR_) * exp22_; //G
-	p_(0, 3) = piT_ * (1. -               exp1_);                        //T, U
-
-	//C
-	p_(1, 0) = piA_ * (1. -               exp1_);                        //A
-	p_(1, 1) = piC_ * (1. + (piR_/piY_) * exp1_) + (piT_/piY_) * exp21_; //C
-	p_(1, 2) = piG_ * (1. -               exp1_);                        //G
-	p_(1, 3) = piT_ * (1. + (piR_/piY_) * exp1_) - (piT_/piY_) * exp21_; //T, U
-
-	//G
-	p_(2, 0) = piA_ * (1. + (piY_/piR_) * exp1_) - (piA_/piR_) * exp22_; //A
-	p_(2, 1) = piC_ * (1. -               exp1_);                        //C
-	p_(2, 2) = piG_ * (1. + (piY_/piR_) * exp1_) + (piA_/piR_) * exp22_; //G
-	p_(2, 3) = piT_ * (1. -               exp1_);                        //T, U
-
-	//T, U
-	p_(3, 0) = piA_ * (1. -               exp1_);                        //A
-	p_(3, 1) = piC_ * (1. + (piR_/piY_) * exp1_) - (piC_/piY_) * exp21_; //C
-	p_(3, 2) = piG_ * (1. -               exp1_);                        //G
-	p_(3, 3) = piT_ * (1. + (piR_/piY_) * exp1_) + (piC_/piY_) * exp21_; //T, U
-
-	return p_;
+  exp1_ = exp(-l_);
+  exp22_ = exp(-k2_ * l_);
+  exp21_ = exp(-k1_ * l_);
+
+  //A
+  p_(0, 0) = piA_ * (1. + (piY_/piR_) * exp1_) + (piG_/piR_) * exp22_; //A
+  p_(0, 1) = piC_ * (1. -               exp1_);                        //C
+  p_(0, 2) = piG_ * (1. + (piY_/piR_) * exp1_) - (piG_/piR_) * exp22_; //G
+  p_(0, 3) = piT_ * (1. -               exp1_);                        //T, U
+
+  //C
+  p_(1, 0) = piA_ * (1. -               exp1_);                        //A
+  p_(1, 1) = piC_ * (1. + (piR_/piY_) * exp1_) + (piT_/piY_) * exp21_; //C
+  p_(1, 2) = piG_ * (1. -               exp1_);                        //G
+  p_(1, 3) = piT_ * (1. + (piR_/piY_) * exp1_) - (piT_/piY_) * exp21_; //T, U
+
+  //G
+  p_(2, 0) = piA_ * (1. + (piY_/piR_) * exp1_) - (piA_/piR_) * exp22_; //A
+  p_(2, 1) = piC_ * (1. -               exp1_);                        //C
+  p_(2, 2) = piG_ * (1. + (piY_/piR_) * exp1_) + (piA_/piR_) * exp22_; //G
+  p_(2, 3) = piT_ * (1. -               exp1_);                        //T, U
+
+  //T, U
+  p_(3, 0) = piA_ * (1. -               exp1_);                        //A
+  p_(3, 1) = piC_ * (1. + (piR_/piY_) * exp1_) - (piC_/piY_) * exp21_; //C
+  p_(3, 2) = piG_ * (1. -               exp1_);                        //G
+  p_(3, 3) = piT_ * (1. + (piR_/piY_) * exp1_) + (piC_/piY_) * exp21_; //T, U
+
+  return p_;
 }
 
 const Matrix<double> & HKY85::getdPij_dt(double d) const
 {
-	l_ = rate_ * r_ * d;
-	exp1_ = exp(-l_);
-	exp22_ = exp(-k2_ * l_);
-	exp21_ = exp(-k1_ * l_);
-
-	//A
-	p_(0, 0) = rate_ * r_ * (piA_ * -(piY_/piR_) * exp1_ - (piG_/piR_) * k2_ * exp22_); //A
-	p_(0, 1) = rate_ * r_ * (piC_ *                exp1_);                              //C
-	p_(0, 2) = rate_ * r_ * (piG_ * -(piY_/piR_) * exp1_ + (piG_/piR_) * k2_ * exp22_); //G
-	p_(0, 3) = rate_ * r_ * (piT_ *                exp1_);                              //T, U
-
-	//C
-	p_(1, 0) = rate_ * r_ * (piA_ *                exp1_);                              //A
-	p_(1, 1) = rate_ * r_ * (piC_ * -(piR_/piY_) * exp1_ - (piT_/piY_) * k1_ * exp21_); //C
-	p_(1, 2) = rate_ * r_ * (piG_ *                exp1_);                              //G
-	p_(1, 3) = rate_ * r_ * (piT_ * -(piR_/piY_) * exp1_ + (piT_/piY_) * k1_ * exp21_); //T, U
-
-	//G
-	p_(2, 0) = rate_ * r_ * (piA_ * -(piY_/piR_) * exp1_ + (piA_/piR_) * k2_ * exp22_); //A
-	p_(2, 1) = rate_ * r_ * (piC_ *                exp1_);                              //C
-	p_(2, 2) = rate_ * r_ * (piG_ * -(piY_/piR_) * exp1_ - (piA_/piR_) * k2_ * exp22_); //G
-	p_(2, 3) = rate_ * r_ * (piT_ *                exp1_);                              //T, U
-
-	//T, U
-	p_(3, 0) = rate_ * r_ * (piA_ *                exp1_);                              //A
-	p_(3, 1) = rate_ * r_ * (piC_ * -(piR_/piY_) * exp1_ + (piC_/piY_) * k1_ * exp21_); //C
-	p_(3, 2) = rate_ * r_ * (piG_ *                exp1_);                              //G
-	p_(3, 3) = rate_ * r_ * (piT_ * -(piR_/piY_) * exp1_ - (piC_/piY_) * k1_ * exp21_); //T, U
-
-	return p_;
+  l_ = rate_ * r_ * d;
+  exp1_ = exp(-l_);
+  exp22_ = exp(-k2_ * l_);
+  exp21_ = exp(-k1_ * l_);
+
+  //A
+  p_(0, 0) = rate_ * r_ * (piA_ * -(piY_/piR_) * exp1_ - (piG_/piR_) * k2_ * exp22_); //A
+  p_(0, 1) = rate_ * r_ * (piC_ *                exp1_);                              //C
+  p_(0, 2) = rate_ * r_ * (piG_ * -(piY_/piR_) * exp1_ + (piG_/piR_) * k2_ * exp22_); //G
+  p_(0, 3) = rate_ * r_ * (piT_ *                exp1_);                              //T, U
+
+  //C
+  p_(1, 0) = rate_ * r_ * (piA_ *                exp1_);                              //A
+  p_(1, 1) = rate_ * r_ * (piC_ * -(piR_/piY_) * exp1_ - (piT_/piY_) * k1_ * exp21_); //C
+  p_(1, 2) = rate_ * r_ * (piG_ *                exp1_);                              //G
+  p_(1, 3) = rate_ * r_ * (piT_ * -(piR_/piY_) * exp1_ + (piT_/piY_) * k1_ * exp21_); //T, U
+
+  //G
+  p_(2, 0) = rate_ * r_ * (piA_ * -(piY_/piR_) * exp1_ + (piA_/piR_) * k2_ * exp22_); //A
+  p_(2, 1) = rate_ * r_ * (piC_ *                exp1_);                              //C
+  p_(2, 2) = rate_ * r_ * (piG_ * -(piY_/piR_) * exp1_ - (piA_/piR_) * k2_ * exp22_); //G
+  p_(2, 3) = rate_ * r_ * (piT_ *                exp1_);                              //T, U
+
+  //T, U
+  p_(3, 0) = rate_ * r_ * (piA_ *                exp1_);                              //A
+  p_(3, 1) = rate_ * r_ * (piC_ * -(piR_/piY_) * exp1_ + (piC_/piY_) * k1_ * exp21_); //C
+  p_(3, 2) = rate_ * r_ * (piG_ *                exp1_);                              //G
+  p_(3, 3) = rate_ * r_ * (piT_ * -(piR_/piY_) * exp1_ - (piC_/piY_) * k1_ * exp21_); //T, U
+
+  return p_;
 }
 
 const Matrix<double> & HKY85::getd2Pij_dt2(double d) const
 {
-	double r_2 = rate_ * rate_ * r_ * r_;
-	l_ = rate_ * r_ * d;
-	double k1_2 = k1_ * k1_;
-	double k2_2 = k2_ * k2_;
-	exp1_ = exp(-l_);
-	exp22_ = exp(-k2_ * l_);
-	exp21_ = exp(-k1_ * l_);
-
-	//A
-	p_(0, 0) = r_2 * (piA_ * (piY_/piR_) * exp1_ + (piG_/piR_) * k2_2 * exp22_); //A
-	p_(0, 1) = r_2 * (piC_ *             - exp1_);                               //C
-	p_(0, 2) = r_2 * (piG_ * (piY_/piR_) * exp1_ - (piG_/piR_) * k2_2 * exp22_); //G
-	p_(0, 3) = r_2 * (piT_ *             - exp1_);                               //T, U
-
-	//C
-	p_(1, 0) = r_2 * (piA_ *             - exp1_);                               //A
-	p_(1, 1) = r_2 * (piC_ * (piR_/piY_) * exp1_ + (piT_/piY_) * k1_2 * exp21_); //C
-	p_(1, 2) = r_2 * (piG_ *             - exp1_);                               //G
-	p_(1, 3) = r_2 * (piT_ * (piR_/piY_) * exp1_ - (piT_/piY_) * k1_2 * exp21_); //T, U
-
-	//G
-	p_(2, 0) = r_2 * (piA_ * (piY_/piR_) * exp1_ - (piA_/piR_) * k2_2 * exp22_); //A
-	p_(2, 1) = r_2 * (piC_ *             - exp1_);                               //C
-	p_(2, 2) = r_2 * (piG_ * (piY_/piR_) * exp1_ + (piA_/piR_) * k2_2 * exp22_); //G
-	p_(2, 3) = r_2 * (piT_ *             - exp1_);                               //T, U
-
-	//T, U
-	p_(3, 0) = r_2 * (piA_ *             - exp1_);                               //A
-	p_(3, 1) = r_2 * (piC_ * (piR_/piY_) * exp1_ - (piC_/piY_) * k1_2 * exp21_); //C
-	p_(3, 2) = r_2 * (piG_ *             - exp1_);                               //G
-	p_(3, 3) = r_2 * (piT_ * (piR_/piY_) * exp1_ + (piC_/piY_) * k1_2 * exp21_); //T, U
-
-	return p_;
+  double r_2 = rate_ * rate_ * r_ * r_;
+  l_ = rate_ * r_ * d;
+  double k1_2 = k1_ * k1_;
+  double k2_2 = k2_ * k2_;
+  exp1_ = exp(-l_);
+  exp22_ = exp(-k2_ * l_);
+  exp21_ = exp(-k1_ * l_);
+
+  //A
+  p_(0, 0) = r_2 * (piA_ * (piY_/piR_) * exp1_ + (piG_/piR_) * k2_2 * exp22_); //A
+  p_(0, 1) = r_2 * (piC_ *             - exp1_);                               //C
+  p_(0, 2) = r_2 * (piG_ * (piY_/piR_) * exp1_ - (piG_/piR_) * k2_2 * exp22_); //G
+  p_(0, 3) = r_2 * (piT_ *             - exp1_);                               //T, U
+
+  //C
+  p_(1, 0) = r_2 * (piA_ *             - exp1_);                               //A
+  p_(1, 1) = r_2 * (piC_ * (piR_/piY_) * exp1_ + (piT_/piY_) * k1_2 * exp21_); //C
+  p_(1, 2) = r_2 * (piG_ *             - exp1_);                               //G
+  p_(1, 3) = r_2 * (piT_ * (piR_/piY_) * exp1_ - (piT_/piY_) * k1_2 * exp21_); //T, U
+
+  //G
+  p_(2, 0) = r_2 * (piA_ * (piY_/piR_) * exp1_ - (piA_/piR_) * k2_2 * exp22_); //A
+  p_(2, 1) = r_2 * (piC_ *             - exp1_);                               //C
+  p_(2, 2) = r_2 * (piG_ * (piY_/piR_) * exp1_ + (piA_/piR_) * k2_2 * exp22_); //G
+  p_(2, 3) = r_2 * (piT_ *             - exp1_);                               //T, U
+
+  //T, U
+  p_(3, 0) = r_2 * (piA_ *             - exp1_);                               //A
+  p_(3, 1) = r_2 * (piC_ * (piR_/piY_) * exp1_ - (piC_/piY_) * k1_2 * exp21_); //C
+  p_(3, 2) = r_2 * (piG_ *             - exp1_);                               //G
+  p_(3, 3) = r_2 * (piT_ * (piR_/piY_) * exp1_ + (piC_/piY_) * k1_2 * exp21_); //T, U
+
+  return p_;
 }
 
 /******************************************************************************/
diff --git a/src/Bpp/Phyl/Model/Nucleotide/HKY85.h b/src/Bpp/Phyl/Model/Nucleotide/HKY85.h
index 19b56a8..dee98b8 100755
--- a/src/Bpp/Phyl/Model/Nucleotide/HKY85.h
+++ b/src/Bpp/Phyl/Model/Nucleotide/HKY85.h
@@ -5,7 +5,7 @@
 //
 
 /*
-Copyright or © or Copr. CNRS, (November 16, 2004)
+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.
@@ -204,9 +204,9 @@ class HKY85:
     clone() const { return new HKY85(*this); }
 
   public:
-		double Pij_t    (int i, int j, double d) const;
-		double dPij_dt  (int i, int j, double d) const;
-		double d2Pij_dt2(int i, int j, double d) const;
+		double Pij_t    (size_t i, size_t j, double d) const;
+		double dPij_dt  (size_t i, size_t j, double d) const;
+		double d2Pij_dt2(size_t i, size_t j, double d) const;
 		const Matrix<double> & getPij_t    (double d) const;
 		const Matrix<double> & getdPij_dt  (double d) const;
 		const Matrix<double> & getd2Pij_dt2(double d) const;
diff --git a/src/Bpp/Phyl/Model/Nucleotide/JCnuc.cpp b/src/Bpp/Phyl/Model/Nucleotide/JCnuc.cpp
index 8546d3c..061cd16 100644
--- a/src/Bpp/Phyl/Model/Nucleotide/JCnuc.cpp
+++ b/src/Bpp/Phyl/Model/Nucleotide/JCnuc.cpp
@@ -49,8 +49,7 @@ using namespace std;
 
 JCnuc::JCnuc(const NucleicAlphabet* alpha) :
   AbstractParameterAliasable("JC69."),
-  AbstractSubstitutionModel(alpha, "JC69."),
-  AbstractReversibleSubstitutionModel(alpha, "JC69."),
+  AbstractReversibleSubstitutionModel(alpha, new CanonicalStateMap(alpha, false), "JC69."),
   exp_(),
   p_(size_, size_)
 {
@@ -65,9 +64,9 @@ void JCnuc::updateMatrices()
   freq_[0] = freq_[1] = freq_[2] = freq_[3] = 1. / 4.;
 
   // Generator and exchangeabilities:
-  for (int i = 0; i < 4; i++)
+  for (size_t i = 0; i < 4; ++i)
   {
-    for (int j = 0; j < 4; j++)
+    for (size_t j = 0; j < 4; ++j)
     {
       generator_(i, j) = (i == j) ? -1. : 1. / 3.;
       exchangeability_(i, j) = generator_(i, j) * 4.;
diff --git a/src/Bpp/Phyl/Model/Nucleotide/JCnuc.h b/src/Bpp/Phyl/Model/Nucleotide/JCnuc.h
index ae5dfc6..8cfd5a0 100644
--- a/src/Bpp/Phyl/Model/Nucleotide/JCnuc.h
+++ b/src/Bpp/Phyl/Model/Nucleotide/JCnuc.h
@@ -161,9 +161,10 @@ public:
    *
    * Consider using the HKY85 model for instance if you want to set frequencies as parameters.
    *
-   * @param data Useless parameter.
+   * @param data Unused parameter.
+   * @param pseudoCount Unused parameter.
    */
-  void setFreqFromData(const SequenceContainer& data) {}
+  void setFreqFromData(const SequenceContainer& data, double pseudoCount = 0) {}
 
 protected:
   /**
diff --git a/src/Bpp/Phyl/Model/Nucleotide/K80.cpp b/src/Bpp/Phyl/Model/Nucleotide/K80.cpp
index c0b8e45..8cd163a 100755
--- a/src/Bpp/Phyl/Model/Nucleotide/K80.cpp
+++ b/src/Bpp/Phyl/Model/Nucleotide/K80.cpp
@@ -5,36 +5,36 @@
 //
 
 /*
-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.
+  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 "K80.h"
@@ -51,13 +51,12 @@ using namespace std;
 /******************************************************************************/
 
 K80::K80(const NucleicAlphabet* alpha, double kappa) :
-  AbstractParameterAliasable("K80."),
-  AbstractSubstitutionModel(alpha, "K80."),
-  AbstractReversibleSubstitutionModel(alpha, "K80."),
+AbstractParameterAliasable("K80."),
+  AbstractReversibleSubstitutionModel(alpha, new CanonicalStateMap(alpha, false), "K80."),
   kappa_(kappa), r_(), l_(), k_(), exp1_(), exp2_(), p_(size_, size_)
 {
-	addParameter_(new Parameter(getNamespace() + "kappa", kappa, &Parameter::R_PLUS_STAR));
-	updateMatrices();
+  addParameter_(new Parameter("K80.kappa", kappa, &Parameter::R_PLUS_STAR));
+  updateMatrices();
 }
 
 /******************************************************************************/
@@ -65,228 +64,228 @@ K80::K80(const NucleicAlphabet* alpha, double kappa) :
 void K80::updateMatrices()
 {
   kappa_ = getParameterValue("kappa");
-	k_ = (kappa_ + 1.) / 2.;
-	r_ = 4. / (kappa_ + 2.);
+  k_ = (kappa_ + 1.) / 2.;
+  r_ = 4. / (kappa_ + 2.);
 	
   // Frequences:
-	freq_[0] = freq_[1] = freq_[2] = freq_[3] = 1. / 4.;
-
-	// Generator:
-	generator_(0, 0) = -2. - kappa_;
-	generator_(1, 1) = -2. - kappa_;
-	generator_(2, 2) = -2. - kappa_;
-	generator_(3, 3) = -2. - kappa_;
-
-	generator_(0, 1) = 1.;
-	generator_(0, 3) = 1.;
-	generator_(1, 0) = 1.;
-	generator_(1, 2) = 1.;
-	generator_(2, 1) = 1.;
-	generator_(2, 3) = 1.;
-	generator_(3, 0) = 1.;
-	generator_(3, 2) = 1.;
+  freq_[0] = freq_[1] = freq_[2] = freq_[3] = 1. / 4.;
+
+  // Generator:
+  generator_(0, 0) = -2. - kappa_;
+  generator_(1, 1) = -2. - kappa_;
+  generator_(2, 2) = -2. - kappa_;
+  generator_(3, 3) = -2. - kappa_;
+
+  generator_(0, 1) = 1.;
+  generator_(0, 3) = 1.;
+  generator_(1, 0) = 1.;
+  generator_(1, 2) = 1.;
+  generator_(2, 1) = 1.;
+  generator_(2, 3) = 1.;
+  generator_(3, 0) = 1.;
+  generator_(3, 2) = 1.;
 	
-	generator_(0, 2) = kappa_;
-	generator_(1, 3) = kappa_;
-	generator_(2, 0) = kappa_;
-	generator_(3, 1) = kappa_;
-
-	// Normalization:
-	MatrixTools::scale(generator_, r_/4);
-
-	// Exchangeability:
-	exchangeability_ = generator_;
-	MatrixTools::scale(exchangeability_, 4.);
-
-	// Eigen values:
-	eigenValues_[0] = 0;
-	eigenValues_[1] = -r_ * (1. + kappa_)/2;
-	eigenValues_[2] = -r_ * (1. + kappa_)/2;
-	eigenValues_[3] = -r_;
+  generator_(0, 2) = kappa_;
+  generator_(1, 3) = kappa_;
+  generator_(2, 0) = kappa_;
+  generator_(3, 1) = kappa_;
+
+  // Normalization:
+  MatrixTools::scale(generator_, r_/4);
+
+  // Exchangeability:
+  exchangeability_ = generator_;
+  MatrixTools::scale(exchangeability_, 4.);
+
+  // Eigen values:
+  eigenValues_[0] = 0;
+  eigenValues_[1] = -r_ * (1. + kappa_)/2;
+  eigenValues_[2] = -r_ * (1. + kappa_)/2;
+  eigenValues_[3] = -r_;
 	
-	// Eigen vectors:
-	leftEigenVectors_(0,0) = 1. / 4.;
-	leftEigenVectors_(0,1) = 1. / 4.;
-	leftEigenVectors_(0,2) = 1. / 4.;
-	leftEigenVectors_(0,3) = 1. / 4.;
-	leftEigenVectors_(1,0) = 0.;
-	leftEigenVectors_(1,1) = 1. / 2.;
-	leftEigenVectors_(1,2) = 0.;
-	leftEigenVectors_(1,3) = -1. / 2.;
-	leftEigenVectors_(2,0) = 1. / 2.;
-	leftEigenVectors_(2,1) = 0.;
-	leftEigenVectors_(2,2) = -1. / 2.;
-	leftEigenVectors_(2,3) = 0.;
-	leftEigenVectors_(3,0) = 1. / 4.;
-	leftEigenVectors_(3,1) = -1. / 4.;
-	leftEigenVectors_(3,2) = 1. / 4.;
-	leftEigenVectors_(3,3) = -1. / 4.;
-
-	rightEigenVectors_(0,0) = 1.;
-	rightEigenVectors_(0,1) = 0.;
-	rightEigenVectors_(0,2) = 1.;
-	rightEigenVectors_(0,3) = 1.;
-	rightEigenVectors_(1,0) = 1.;
-	rightEigenVectors_(1,1) = 1.;
-	rightEigenVectors_(1,2) = 0.;
-	rightEigenVectors_(1,3) = -1.;
-	rightEigenVectors_(2,0) = 1.;
-	rightEigenVectors_(2,1) = 0.;
-	rightEigenVectors_(2,2) = -1.;
-	rightEigenVectors_(2,3) = 1.;
-	rightEigenVectors_(3,0) = 1.;
-	rightEigenVectors_(3,1) = -1.;
-	rightEigenVectors_(3,2) = 0;
-	rightEigenVectors_(3,3) = -1.;
+  // Eigen vectors:
+  leftEigenVectors_(0,0) = 1. / 4.;
+  leftEigenVectors_(0,1) = 1. / 4.;
+  leftEigenVectors_(0,2) = 1. / 4.;
+  leftEigenVectors_(0,3) = 1. / 4.;
+  leftEigenVectors_(1,0) = 0.;
+  leftEigenVectors_(1,1) = 1. / 2.;
+  leftEigenVectors_(1,2) = 0.;
+  leftEigenVectors_(1,3) = -1. / 2.;
+  leftEigenVectors_(2,0) = 1. / 2.;
+  leftEigenVectors_(2,1) = 0.;
+  leftEigenVectors_(2,2) = -1. / 2.;
+  leftEigenVectors_(2,3) = 0.;
+  leftEigenVectors_(3,0) = 1. / 4.;
+  leftEigenVectors_(3,1) = -1. / 4.;
+  leftEigenVectors_(3,2) = 1. / 4.;
+  leftEigenVectors_(3,3) = -1. / 4.;
+
+  rightEigenVectors_(0,0) = 1.;
+  rightEigenVectors_(0,1) = 0.;
+  rightEigenVectors_(0,2) = 1.;
+  rightEigenVectors_(0,3) = 1.;
+  rightEigenVectors_(1,0) = 1.;
+  rightEigenVectors_(1,1) = 1.;
+  rightEigenVectors_(1,2) = 0.;
+  rightEigenVectors_(1,3) = -1.;
+  rightEigenVectors_(2,0) = 1.;
+  rightEigenVectors_(2,1) = 0.;
+  rightEigenVectors_(2,2) = -1.;
+  rightEigenVectors_(2,3) = 1.;
+  rightEigenVectors_(3,0) = 1.;
+  rightEigenVectors_(3,1) = -1.;
+  rightEigenVectors_(3,2) = 0;
+  rightEigenVectors_(3,3) = -1.;
 }
 	
 /******************************************************************************/
 
-double K80::Pij_t(int i, int j, double d) const
+double K80::Pij_t(size_t i, size_t j, double d) const
 {
-	l_ = rate_ * r_ * d;
-	exp1_ = exp(-l_);
-	exp2_ = exp(-k_ * l_);
+  l_ = rate_ * r_ * d;
+  exp1_ = exp(-l_);
+  exp2_ = exp(-k_ * l_);
 	
-	switch(i) {
-		//A
-		case 0 : {
-			switch(j) {
-				case 0 : return 0.25 * (1. + exp1_) + 0.5 * exp2_; //A
-				case 1 : return 0.25 * (1. - exp1_);               //C
-				case 2 : return 0.25 * (1. + exp1_) - 0.5 * exp2_; //G
-				case 3 : return 0.25 * (1. - exp1_);               //T, U
-			}
-		} 
-		//C
-		case 1 : {
-			switch(j) {
-				case 0 : return 0.25 * (1. - exp1_);               //A
-				case 1 : return 0.25 * (1. + exp1_) + 0.5 * exp2_; //C
-				case 2 : return 0.25 * (1. - exp1_);               //G
-				case 3 : return 0.25 * (1. + exp1_) - 0.5 * exp2_; //T, U
-			}
-		}
-		//G
-		case 2 : {
-			switch(j) {
-				case 0 : return 0.25 * (1. + exp1_) - 0.5 * exp2_; //A
-				case 1 : return 0.25 * (1. - exp1_);               //C
-				case 2 : return 0.25 * (1. + exp1_) + 0.5 * exp2_; //G
-				case 3 : return 0.25 * (1. - exp1_);               //T, U
-			}
-		}
-		//T, U
-		case 3 : {
-			switch(j) {
-				case 0 : return 0.25 * (1. - exp1_);               //A
-				case 1 : return 0.25 * (1. + exp1_) - 0.5 * exp2_; //C
-				case 2 : return 0.25 * (1. - exp1_);               //G
-				case 3 : return 0.25 * (1. + exp1_) + 0.5 * exp2_; //T, U
-			}
-		}
-	}
-	return 0;
+  switch(i) {
+    //A
+  case 0 : {
+    switch(j) {
+    case 0 : return 0.25 * (1. + exp1_) + 0.5 * exp2_; //A
+    case 1 : return 0.25 * (1. - exp1_);               //C
+    case 2 : return 0.25 * (1. + exp1_) - 0.5 * exp2_; //G
+    case 3 : return 0.25 * (1. - exp1_);               //T, U
+    }
+  } 
+    //C
+  case 1 : {
+    switch(j) {
+    case 0 : return 0.25 * (1. - exp1_);               //A
+    case 1 : return 0.25 * (1. + exp1_) + 0.5 * exp2_; //C
+    case 2 : return 0.25 * (1. - exp1_);               //G
+    case 3 : return 0.25 * (1. + exp1_) - 0.5 * exp2_; //T, U
+    }
+  }
+    //G
+  case 2 : {
+    switch(j) {
+    case 0 : return 0.25 * (1. + exp1_) - 0.5 * exp2_; //A
+    case 1 : return 0.25 * (1. - exp1_);               //C
+    case 2 : return 0.25 * (1. + exp1_) + 0.5 * exp2_; //G
+    case 3 : return 0.25 * (1. - exp1_);               //T, U
+    }
+  }
+    //T, U
+  case 3 : {
+    switch(j) {
+    case 0 : return 0.25 * (1. - exp1_);               //A
+    case 1 : return 0.25 * (1. + exp1_) - 0.5 * exp2_; //C
+    case 2 : return 0.25 * (1. - exp1_);               //G
+    case 3 : return 0.25 * (1. + exp1_) + 0.5 * exp2_; //T, U
+    }
+  }
+  }
+  return 0;
 }
 
 /******************************************************************************/
 
-double K80::dPij_dt(int i, int j, double d) const
+double K80::dPij_dt(size_t i, size_t j, double d) const
 {
   l_ = rate_ * r_ * d;
-	exp1_ = exp(-l_);
-	exp2_ = exp(-k_ * l_);
-
-	switch(i) {
-		//A
-		case 0 : {
-			switch(j) {
-                        case 0 : return rate_ * r_/4. * (- exp1_ - 2. * k_ * exp2_); //A
-                        case 1 : return rate_ * r_/4. * (  exp1_);                   //C
-                        case 2 : return rate_ * r_/4. * (- exp1_ + 2. * k_ * exp2_); //G
-                        case 3 : return rate_ * r_/4. * (  exp1_);                   //T, U
-			}
-		} 
-		//C
-		case 1 : {
-			switch(j) {
-                        case 0 : return rate_ * r_/4. * (  exp1_);                   //A
-                        case 1 : return rate_ * r_/4. * (- exp1_ - 2. * k_ * exp2_); //C
-                        case 2 : return rate_ * r_/4. * (  exp1_);                   //G
-                        case 3 : return rate_ * r_/4. * (- exp1_ + 2. * k_ * exp2_); //T, U
-			}
-		}
-		//G
-		case 2 : {
-			switch(j) {
-                        case 0 : return rate_ * r_/4. * (- exp1_ + 2. * k_ * exp2_); //A
-                        case 1 : return rate_ * r_/4. * (  exp1_);                   //C
-                        case 2 : return rate_ * r_/4. * (- exp1_ - 2. * k_ * exp2_); //G
-                        case 3 : return rate_ * r_/4. * (  exp1_);                   //T, U
-			}
-		}
-		//T, U
-		case 3 : {
-			switch(j) {
-                        case 0 : return rate_ * r_/4. * (  exp1_);                   //A
-                        case 1 : return rate_ * r_/4. * (- exp1_ + 2. * k_ * exp2_); //C
-                        case 2 : return rate_ * r_/4. * (  exp1_);                   //G
-                        case 3 : return rate_ * r_/4. * (- exp1_ - 2. * k_ * exp2_); //T, U
-			}
-		}
-	}
-	return 0;
+  exp1_ = exp(-l_);
+  exp2_ = exp(-k_ * l_);
+
+  switch(i) {
+    //A
+  case 0 : {
+    switch(j) {
+    case 0 : return rate_ * r_/4. * (- exp1_ - 2. * k_ * exp2_); //A
+    case 1 : return rate_ * r_/4. * (  exp1_);                   //C
+    case 2 : return rate_ * r_/4. * (- exp1_ + 2. * k_ * exp2_); //G
+    case 3 : return rate_ * r_/4. * (  exp1_);                   //T, U
+    }
+  } 
+    //C
+  case 1 : {
+    switch(j) {
+    case 0 : return rate_ * r_/4. * (  exp1_);                   //A
+    case 1 : return rate_ * r_/4. * (- exp1_ - 2. * k_ * exp2_); //C
+    case 2 : return rate_ * r_/4. * (  exp1_);                   //G
+    case 3 : return rate_ * r_/4. * (- exp1_ + 2. * k_ * exp2_); //T, U
+    }
+  }
+    //G
+  case 2 : {
+    switch(j) {
+    case 0 : return rate_ * r_/4. * (- exp1_ + 2. * k_ * exp2_); //A
+    case 1 : return rate_ * r_/4. * (  exp1_);                   //C
+    case 2 : return rate_ * r_/4. * (- exp1_ - 2. * k_ * exp2_); //G
+    case 3 : return rate_ * r_/4. * (  exp1_);                   //T, U
+    }
+  }
+    //T, U
+  case 3 : {
+    switch(j) {
+    case 0 : return rate_ * r_/4. * (  exp1_);                   //A
+    case 1 : return rate_ * r_/4. * (- exp1_ + 2. * k_ * exp2_); //C
+    case 2 : return rate_ * r_/4. * (  exp1_);                   //G
+    case 3 : return rate_ * r_/4. * (- exp1_ - 2. * k_ * exp2_); //T, U
+    }
+  }
+  }
+  return 0;
 }
 
 /******************************************************************************/
 
-double K80::d2Pij_dt2(int i, int j, double d) const
+double K80::d2Pij_dt2(size_t i, size_t j, double d) const
 {
-	double k_2 = k_ * k_;
-	double r_2 = rate_ * rate_ * r_ * r_;
-	l_ = rate_ * r_ * d;
-	exp1_ = exp(-l_);
-	exp2_ = exp(-k_ * l_);
-
-	switch(i) {
-		//A
-		case 0 : {
-			switch(j) {
-				case 0 : return r_2/4. * (  exp1_ + 2. * k_2 * exp2_); //A
-				case 1 : return r_2/4. * (- exp1_);                    //C
-				case 2 : return r_2/4. * (  exp1_ - 2. * k_2 * exp2_); //G
-				case 3 : return r_2/4. * (- exp1_);                    //T, U
-			}
-		} 
-		//C
-		case 1 : {
-			switch(j) {
-				case 0 : return r_2/4. * (- exp1_);                    //A
-				case 1 : return r_2/4. * (  exp1_ + 2. * k_2 * exp2_); //C
-				case 2 : return r_2/4. * (- exp1_);                    //G
-				case 3 : return r_2/4. * (  exp1_ - 2. * k_2 * exp2_); //T, U
-			}
-		}
-		//G
-		case 2 : {
-			switch(j) {
-				case 0 : return r_2/4. * (  exp1_ - 2. * k_2 * exp2_); //A
-				case 1 : return r_2/4. * (- exp1_);                    //C
-				case 2 : return r_2/4. * (  exp1_ + 2. * k_2 * exp2_); //G
-				case 3 : return r_2/4. * (- exp1_);                    //T, U
-			}
-		}
-		//T, U
-		case 3 : {
-			switch(j) {
-				case 0 : return r_2/4. * (- exp1_);                    //A
-				case 1 : return r_2/4. * (  exp1_ - 2. * k_2 * exp2_); //C
-				case 2 : return r_2/4. * (- exp1_);                    //G
-				case 3 : return r_2/4. * (  exp1_ + 2. * k_2 * exp2_); //T, U
-			}
-		}
-	}
-	return 0;
+  double k_2 = k_ * k_;
+  double r_2 = rate_ * rate_ * r_ * r_;
+  l_ = rate_ * r_ * d;
+  exp1_ = exp(-l_);
+  exp2_ = exp(-k_ * l_);
+
+  switch(i) {
+    //A
+  case 0 : {
+    switch(j) {
+    case 0 : return r_2/4. * (  exp1_ + 2. * k_2 * exp2_); //A
+    case 1 : return r_2/4. * (- exp1_);                    //C
+    case 2 : return r_2/4. * (  exp1_ - 2. * k_2 * exp2_); //G
+    case 3 : return r_2/4. * (- exp1_);                    //T, U
+    }
+  } 
+    //C
+  case 1 : {
+    switch(j) {
+    case 0 : return r_2/4. * (- exp1_);                    //A
+    case 1 : return r_2/4. * (  exp1_ + 2. * k_2 * exp2_); //C
+    case 2 : return r_2/4. * (- exp1_);                    //G
+    case 3 : return r_2/4. * (  exp1_ - 2. * k_2 * exp2_); //T, U
+    }
+  }
+    //G
+  case 2 : {
+    switch(j) {
+    case 0 : return r_2/4. * (  exp1_ - 2. * k_2 * exp2_); //A
+    case 1 : return r_2/4. * (- exp1_);                    //C
+    case 2 : return r_2/4. * (  exp1_ + 2. * k_2 * exp2_); //G
+    case 3 : return r_2/4. * (- exp1_);                    //T, U
+    }
+  }
+    //T, U
+  case 3 : {
+    switch(j) {
+    case 0 : return r_2/4. * (- exp1_);                    //A
+    case 1 : return r_2/4. * (  exp1_ - 2. * k_2 * exp2_); //C
+    case 2 : return r_2/4. * (- exp1_);                    //G
+    case 3 : return r_2/4. * (  exp1_ + 2. * k_2 * exp2_); //T, U
+    }
+  }
+  }
+  return 0;
 }
 
 /******************************************************************************/
@@ -294,100 +293,100 @@ double K80::d2Pij_dt2(int i, int j, double d) const
 const Matrix<double> & K80::getPij_t(double d) const
 {
   l_ = rate_ * r_ * d;
-	exp1_ = exp(-l_);
-	exp2_ = exp(-k_ * l_);
-
-	//A
-	p_(0, 0) = 0.25 * (1. + exp1_) + 0.5 * exp2_; //A
-	p_(0, 1) = 0.25 * (1. - exp1_);               //C
-	p_(0, 2) = 0.25 * (1. + exp1_) - 0.5 * exp2_; //G
-	p_(0, 3) = 0.25 * (1. - exp1_);               //T, U
-
-	//C
-	p_(1, 0) = 0.25 * (1. - exp1_);               //A
-	p_(1, 1) = 0.25 * (1. + exp1_) + 0.5 * exp2_; //C
-	p_(1, 2) = 0.25 * (1. - exp1_);               //G
-	p_(1, 3) = 0.25 * (1. + exp1_) - 0.5 * exp2_; //T, U
-
-	//G
-	p_(2, 0) = 0.25 * (1. + exp1_) - 0.5 * exp2_; //A
-	p_(2, 1) = 0.25 * (1. - exp1_);               //C
-	p_(2, 2) = 0.25 * (1. + exp1_) + 0.5 * exp2_; //G
-	p_(2, 3) = 0.25 * (1. - exp1_);               //T, U
-
-	//T, U
-	p_(3, 0) = 0.25 * (1. - exp1_);               //A
-	p_(3, 1) = 0.25 * (1. + exp1_) - 0.5 * exp2_; //C
-	p_(3, 2) = 0.25 * (1. - exp1_);               //G
-	p_(3, 3) = 0.25 * (1. + exp1_) + 0.5 * exp2_; //T, U
-
-	return p_;
+  exp1_ = exp(-l_);
+  exp2_ = exp(-k_ * l_);
+
+  //A
+  p_(0, 0) = 0.25 * (1. + exp1_) + 0.5 * exp2_; //A
+  p_(0, 1) = 0.25 * (1. - exp1_);               //C
+  p_(0, 2) = 0.25 * (1. + exp1_) - 0.5 * exp2_; //G
+  p_(0, 3) = 0.25 * (1. - exp1_);               //T, U
+
+  //C
+  p_(1, 0) = 0.25 * (1. - exp1_);               //A
+  p_(1, 1) = 0.25 * (1. + exp1_) + 0.5 * exp2_; //C
+  p_(1, 2) = 0.25 * (1. - exp1_);               //G
+  p_(1, 3) = 0.25 * (1. + exp1_) - 0.5 * exp2_; //T, U
+
+  //G
+  p_(2, 0) = 0.25 * (1. + exp1_) - 0.5 * exp2_; //A
+  p_(2, 1) = 0.25 * (1. - exp1_);               //C
+  p_(2, 2) = 0.25 * (1. + exp1_) + 0.5 * exp2_; //G
+  p_(2, 3) = 0.25 * (1. - exp1_);               //T, U
+
+  //T, U
+  p_(3, 0) = 0.25 * (1. - exp1_);               //A
+  p_(3, 1) = 0.25 * (1. + exp1_) - 0.5 * exp2_; //C
+  p_(3, 2) = 0.25 * (1. - exp1_);               //G
+  p_(3, 3) = 0.25 * (1. + exp1_) + 0.5 * exp2_; //T, U
+
+  return p_;
 }
 
 const Matrix<double> & K80::getdPij_dt(double d) const
 {
   l_ = rate_ * r_ * d;
-	exp1_ = exp(-l_);
-	exp2_ = exp(-k_ * l_);
-
-	p_(0, 0) = rate_ * r_/4. * (- exp1_ - 2. * k_ * exp2_); //A
-	p_(0, 1) = rate_ * r_/4. * (  exp1_);                   //C
-	p_(0, 2) = rate_ * r_/4. * (- exp1_ + 2. * k_ * exp2_); //G
-	p_(0, 3) = rate_ * r_/4. * (  exp1_);                   //T, U
-
-	//C
-	p_(1, 0) = rate_ * r_/4. * (  exp1_);                   //A
-	p_(1, 1) = rate_ * r_/4. * (- exp1_ - 2. * k_ * exp2_); //C
-	p_(1, 2) = rate_ * r_/4. * (  exp1_);                   //G
-	p_(1, 3) = rate_ * r_/4. * (- exp1_ + 2. * k_ * exp2_); //T, U
-
-	//G
-	p_(2, 0) = rate_ * r_/4. * (- exp1_ + 2. * k_ * exp2_); //A
-	p_(2, 1) = rate_ * r_/4. * (  exp1_);                   //C
-	p_(2, 2) = rate_ * r_/4. * (- exp1_ - 2. * k_ * exp2_); //G
-	p_(2, 3) = rate_ * r_/4. * (  exp1_);                   //T, U
-
-	//T, U
-	p_(3, 0) = rate_ * r_/4. * (  exp1_);                   //A
-	p_(3, 1) = rate_ * r_/4. * (- exp1_ + 2. * k_ * exp2_); //C
-	p_(3, 2) = rate_ * r_/4. * (  exp1_);                   //G
-	p_(3, 3) = rate_ * r_/4. * (- exp1_ - 2. * k_ * exp2_); //T, U
-
-	return p_;
+  exp1_ = exp(-l_);
+  exp2_ = exp(-k_ * l_);
+
+  p_(0, 0) = rate_ * r_/4. * (- exp1_ - 2. * k_ * exp2_); //A
+  p_(0, 1) = rate_ * r_/4. * (  exp1_);                   //C
+  p_(0, 2) = rate_ * r_/4. * (- exp1_ + 2. * k_ * exp2_); //G
+  p_(0, 3) = rate_ * r_/4. * (  exp1_);                   //T, U
+
+  //C
+  p_(1, 0) = rate_ * r_/4. * (  exp1_);                   //A
+  p_(1, 1) = rate_ * r_/4. * (- exp1_ - 2. * k_ * exp2_); //C
+  p_(1, 2) = rate_ * r_/4. * (  exp1_);                   //G
+  p_(1, 3) = rate_ * r_/4. * (- exp1_ + 2. * k_ * exp2_); //T, U
+
+  //G
+  p_(2, 0) = rate_ * r_/4. * (- exp1_ + 2. * k_ * exp2_); //A
+  p_(2, 1) = rate_ * r_/4. * (  exp1_);                   //C
+  p_(2, 2) = rate_ * r_/4. * (- exp1_ - 2. * k_ * exp2_); //G
+  p_(2, 3) = rate_ * r_/4. * (  exp1_);                   //T, U
+
+  //T, U
+  p_(3, 0) = rate_ * r_/4. * (  exp1_);                   //A
+  p_(3, 1) = rate_ * r_/4. * (- exp1_ + 2. * k_ * exp2_); //C
+  p_(3, 2) = rate_ * r_/4. * (  exp1_);                   //G
+  p_(3, 3) = rate_ * r_/4. * (- exp1_ - 2. * k_ * exp2_); //T, U
+
+  return p_;
 }
 
 const Matrix<double> & K80::getd2Pij_dt2(double d) const
 {
-	double k_2 = k_ * k_;
-	double r_2 = rate_ * rate_ * r_ * r_;
-	l_ = rate_ * r_ * d;
-	exp1_ = exp(-l_);
-	exp2_ = exp(-k_ * l_);
-
-	p_(0, 0) = r_2/4. * (  exp1_ + 2. * k_2 * exp2_); //A
-	p_(0, 1) = r_2/4. * (- exp1_);                    //C
-	p_(0, 2) = r_2/4. * (  exp1_ - 2. * k_2 * exp2_); //G
-	p_(0, 3) = r_2/4. * (- exp1_);                    //T, U
-
-	//C
-	p_(1, 0) = r_2/4. * (- exp1_);                    //A
-	p_(1, 1) = r_2/4. * (  exp1_ + 2. * k_2 * exp2_); //C
-	p_(1, 2) = r_2/4. * (- exp1_);                    //G
-	p_(1, 3) = r_2/4. * (  exp1_ - 2. * k_2 * exp2_); //T, U
-
-	//G
-	p_(2, 0) = r_2/4. * (  exp1_ - 2. * k_2 * exp2_); //A
-	p_(2, 1) = r_2/4. * (- exp1_);                    //C
-	p_(2, 2) = r_2/4. * (  exp1_ + 2. * k_2 * exp2_); //G
-	p_(2, 3) = r_2/4. * (- exp1_);                    //T, U
-
-	//T, U
-	p_(3, 0) = r_2/4. * (- exp1_);                    //A
-	p_(3, 1) = r_2/4. * (  exp1_ - 2. * k_2 * exp2_); //C
-	p_(3, 2) = r_2/4. * (- exp1_);                    //G
-	p_(3, 3) = r_2/4. * (  exp1_ + 2. * k_2 * exp2_); //T, U
-
-	return p_;
+  double k_2 = k_ * k_;
+  double r_2 = rate_ * rate_ * r_ * r_;
+  l_ = rate_ * r_ * d;
+  exp1_ = exp(-l_);
+  exp2_ = exp(-k_ * l_);
+
+  p_(0, 0) = r_2/4. * (  exp1_ + 2. * k_2 * exp2_); //A
+  p_(0, 1) = r_2/4. * (- exp1_);                    //C
+  p_(0, 2) = r_2/4. * (  exp1_ - 2. * k_2 * exp2_); //G
+  p_(0, 3) = r_2/4. * (- exp1_);                    //T, U
+
+  //C
+  p_(1, 0) = r_2/4. * (- exp1_);                    //A
+  p_(1, 1) = r_2/4. * (  exp1_ + 2. * k_2 * exp2_); //C
+  p_(1, 2) = r_2/4. * (- exp1_);                    //G
+  p_(1, 3) = r_2/4. * (  exp1_ - 2. * k_2 * exp2_); //T, U
+
+  //G
+  p_(2, 0) = r_2/4. * (  exp1_ - 2. * k_2 * exp2_); //A
+  p_(2, 1) = r_2/4. * (- exp1_);                    //C
+  p_(2, 2) = r_2/4. * (  exp1_ + 2. * k_2 * exp2_); //G
+  p_(2, 3) = r_2/4. * (- exp1_);                    //T, U
+
+  //T, U
+  p_(3, 0) = r_2/4. * (- exp1_);                    //A
+  p_(3, 1) = r_2/4. * (  exp1_ - 2. * k_2 * exp2_); //C
+  p_(3, 2) = r_2/4. * (- exp1_);                    //G
+  p_(3, 3) = r_2/4. * (  exp1_ + 2. * k_2 * exp2_); //T, U
+
+  return p_;
 }
 
 /******************************************************************************/
diff --git a/src/Bpp/Phyl/Model/Nucleotide/K80.h b/src/Bpp/Phyl/Model/Nucleotide/K80.h
index 6e6a96a..a3ce6f0 100755
--- a/src/Bpp/Phyl/Model/Nucleotide/K80.h
+++ b/src/Bpp/Phyl/Model/Nucleotide/K80.h
@@ -5,7 +5,7 @@
 //
 
 /*
-  Copyright or © or Copr. CNRS, (November 16, 2004)
+  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.
@@ -44,7 +44,7 @@
 #include "NucleotideSubstitutionModel.h"
 #include "../AbstractSubstitutionModel.h"
 
-// From SeqLib:
+// From bpp-seq:
 #include <Bpp/Seq/Alphabet/NucleicAlphabet.h>
 
 namespace bpp
@@ -169,12 +169,12 @@ namespace bpp
     clone() const { return new K80(*this); }
 
   public:
-    double Pij_t    (int i, int j, double d) const;
-    double dPij_dt  (int i, int j, double d) const;
-    double d2Pij_dt2(int i, int j, double d) const;
-    const Matrix<double> & getPij_t    (double d) const;
-    const Matrix<double> & getdPij_dt  (double d) const;
-    const Matrix<double> & getd2Pij_dt2(double d) const;
+    double Pij_t    (size_t i, size_t j, double d) const;
+    double dPij_dt  (size_t i, size_t j, double d) const;
+    double d2Pij_dt2(size_t i, size_t j, double d) const;
+    const Matrix<double>& getPij_t    (double d) const;
+    const Matrix<double>& getdPij_dt  (double d) const;
+    const Matrix<double>& getd2Pij_dt2(double d) const;
 
     std::string getName() const { return "K80"; }
 	   
@@ -183,9 +183,10 @@ namespace bpp
      *
      * Consider using the HKY85 model for instance if you want to set frequencies as parameters.
      *
-     * @param data Useless parameter.
+     * @param data Unused parameter.
+     * @param pseudoCount Unused parameter.
      */
-    void setFreqFromData(const SequenceContainer & data) {}
+    void setFreqFromData(const SequenceContainer& data, double pseudoCount = 0) {}
 	
   protected:
     void updateMatrices();
diff --git a/src/Bpp/Phyl/Model/Nucleotide/L95.cpp b/src/Bpp/Phyl/Model/Nucleotide/L95.cpp
index b1f71f7..cd8e53f 100755
--- a/src/Bpp/Phyl/Model/Nucleotide/L95.cpp
+++ b/src/Bpp/Phyl/Model/Nucleotide/L95.cpp
@@ -5,7 +5,7 @@
 //
 
 /*
-Copyright or © or Copr. Bio++ Development Tools, (November 16, 2004)
+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.
@@ -57,7 +57,7 @@ L95::L95(
 	const NucleicAlphabet* alphabet,
 	double alpha, double beta, double gamma, double kappa, double theta):
     AbstractParameterAliasable("L95."),
-    AbstractSubstitutionModel(alphabet, "L95."), alpha_(alpha), beta_(beta), gamma_(gamma), kappa_(kappa), theta_(theta)
+    AbstractSubstitutionModel(alphabet, new CanonicalStateMap(alphabet, false), "L95."), alpha_(alpha), beta_(beta), gamma_(gamma), kappa_(kappa), theta_(theta)
 {
 
   addParameter_(new Parameter("L95.alpha", alpha, &Parameter::PROP_CONSTRAINT_IN));
diff --git a/src/Bpp/Phyl/Model/Nucleotide/L95.h b/src/Bpp/Phyl/Model/Nucleotide/L95.h
index 510313d..1a598e3 100755
--- a/src/Bpp/Phyl/Model/Nucleotide/L95.h
+++ b/src/Bpp/Phyl/Model/Nucleotide/L95.h
@@ -5,7 +5,7 @@
 //
 
 /*
-Copyright or © or Copr. CNRS, (November 16, 2004)
+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.
@@ -45,7 +45,7 @@ knowledge of the CeCILL license and that you accept its terms.
 
 #include <Bpp/Numeric/Constraints.h>
 
-// From SeqLib:
+// From bpp-seq:
 #include <Bpp/Seq/Alphabet/NucleicAlphabet.h>
 
 namespace bpp
diff --git a/src/Bpp/Phyl/Model/Nucleotide/NucleotideSubstitutionModel.h b/src/Bpp/Phyl/Model/Nucleotide/NucleotideSubstitutionModel.h
index 0862fa8..897ed67 100755
--- a/src/Bpp/Phyl/Model/Nucleotide/NucleotideSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/Nucleotide/NucleotideSubstitutionModel.h
@@ -5,36 +5,36 @@
 //
 
 /*
-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.
+  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 _NUCLEICSUBSTITUTIONMODEL_H_
@@ -51,11 +51,11 @@ namespace bpp
 /**
  * @brief Specialisation interface for nucleotide substitution model.
  */
-class NucleotideSubstitutionModel :
-  public virtual SubstitutionModel
-{
-	public:
-		virtual ~NucleotideSubstitutionModel() {}
+  class NucleotideSubstitutionModel :
+    public virtual SubstitutionModel
+  {
+  public:
+    virtual ~NucleotideSubstitutionModel() {}
 
 #ifndef NO_VIRTUAL_COV
     NucleotideSubstitutionModel*
@@ -67,7 +67,7 @@ class NucleotideSubstitutionModel :
   public:
     virtual size_t getNumberOfStates() const { return 4; }
 
-};
+  };
 
 } //end of namespace bpp.
 
diff --git a/src/Bpp/Phyl/Model/Nucleotide/RN95.cpp b/src/Bpp/Phyl/Model/Nucleotide/RN95.cpp
index a9cf5d6..c96b6bc 100644
--- a/src/Bpp/Phyl/Model/Nucleotide/RN95.cpp
+++ b/src/Bpp/Phyl/Model/Nucleotide/RN95.cpp
@@ -63,7 +63,7 @@ RN95::RN95(
   double lambda,
   double sigma) :
   AbstractParameterAliasable("RN95."),
-  AbstractSubstitutionModel(alphabet, "RN95."),
+  AbstractSubstitutionModel(alphabet, new CanonicalStateMap(alphabet, false), "RN95."),
   alpha_(),
   beta_(),
   gamma_(),
@@ -222,35 +222,37 @@ void RN95::updateMatrices()
 
   // Need formula
 
-  try
+  if (enableEigenDecomposition())
   {
-    MatrixTools::inv(rightEigenVectors_, leftEigenVectors_);
-    isNonSingular_ = true;
-    isDiagonalizable_ = true;
-    for (size_t i = 0; i < size_ && isDiagonalizable_; i++)
+    try
     {
-      if (abs(iEigenValues_[i]) > NumConstants::TINY())
-        isDiagonalizable_ = false;
+      MatrixTools::inv(rightEigenVectors_, leftEigenVectors_);
+      isNonSingular_ = true;
+      isDiagonalizable_ = true;
+      for (size_t i = 0; i < size_ && isDiagonalizable_; i++)
+      {
+        if (abs(iEigenValues_[i]) > NumConstants::TINY())
+          isDiagonalizable_ = false;
+      }
     }
+    catch (ZeroDivisionException& e)
+    {
+      ApplicationTools::displayMessage("Singularity during diagonalization of RN95. Taylor series used instead.");
+      
+      isNonSingular_ = false;
+      isDiagonalizable_ = false;
+      MatrixTools::Taylor(generator_, 30, vPowGen_);
+    }
+    
+    // and the exchangeability_
+    for (unsigned int i = 0; i < size_; i++)
+      for (unsigned int j = 0; j < size_; j++)
+        exchangeability_(i,j) = generator_(i,j) / freq_[j];
   }
-  catch (ZeroDivisionException& e)
-  {
-    ApplicationTools::displayMessage("Singularity during  diagonalization. Taylor series used instead.");
-
-    isNonSingular_ = false;
-    isDiagonalizable_ = false;
-    MatrixTools::Taylor(generator_, 30, vPowGen_);
-  }
-
-  // and the exchangeability_
-  for (unsigned int i = 0; i < size_; i++)
-    for (unsigned int j = 0; j < size_; j++)
-      exchangeability_(i,j) = generator_(i,j) / freq_[j];
-
 }
 
 /******************************************************************************/
-double RN95::Pij_t(int i, int j, double d) const
+double RN95::Pij_t(size_t i, size_t j, double d) const
 {
   l_ = rate_ * r_ * d;
   exp1_ = exp(-c1_ * l_);
@@ -306,7 +308,7 @@ double RN95::Pij_t(int i, int j, double d) const
 }
 
 /******************************************************************************/
-double RN95::dPij_dt(int i, int j, double d) const
+double RN95::dPij_dt(size_t i, size_t j, double d) const
 {
   l_ = rate_ * r_ * d;
   exp1_ = -c1_* rate_* r_* exp(-c1_ * l_);
@@ -362,7 +364,7 @@ double RN95::dPij_dt(int i, int j, double d) const
 }
 
 /******************************************************************************/
-double RN95::d2Pij_dt2(int i, int j, double d) const
+double RN95::d2Pij_dt2(size_t i, size_t j, double d) const
 {
   l_ = rate_ * r_ * d;
   exp1_ = c1_ * rate_ * r_ * c1_ * rate_ * r_ * exp(-c1_ * l_);
diff --git a/src/Bpp/Phyl/Model/Nucleotide/RN95.h b/src/Bpp/Phyl/Model/Nucleotide/RN95.h
index 62c95fc..52601e3 100644
--- a/src/Bpp/Phyl/Model/Nucleotide/RN95.h
+++ b/src/Bpp/Phyl/Model/Nucleotide/RN95.h
@@ -163,9 +163,9 @@ public:
   clone() const { return new RN95(*this); }
 
 public:
-  double Pij_t    (int i, int j, double d) const;
-  double dPij_dt  (int i, int j, double d) const;
-  double d2Pij_dt2(int i, int j, double d) const;
+  double Pij_t    (size_t i, size_t j, double d) const;
+  double dPij_dt  (size_t i, size_t j, double d) const;
+  double d2Pij_dt2(size_t i, size_t j, double d) const;
   const Matrix<double>& getPij_t    (double d) const;
   const Matrix<double>& getdPij_dt  (double d) const;
   const Matrix<double>& getd2Pij_dt2(double d) const;
diff --git a/src/Bpp/Phyl/Model/Nucleotide/RN95s.cpp b/src/Bpp/Phyl/Model/Nucleotide/RN95s.cpp
index 16a2298..61ac2a5 100644
--- a/src/Bpp/Phyl/Model/Nucleotide/RN95s.cpp
+++ b/src/Bpp/Phyl/Model/Nucleotide/RN95s.cpp
@@ -58,7 +58,7 @@ RN95s::RN95s(const NucleicAlphabet* alphabet,
              double gamma,
              double delta) :
   AbstractParameterAliasable("RN95s."),
-  AbstractSubstitutionModel(alphabet, "RN95s."),
+  AbstractSubstitutionModel(alphabet, new CanonicalStateMap(alphabet, false), "RN95s."),
   alpha_(),
   beta_(),
   gamma_(),
@@ -178,35 +178,37 @@ void RN95s::updateMatrices()
 
 // Need formula
 
-  try
+  if (enableEigenDecomposition())
   {
-    MatrixTools::inv(rightEigenVectors_, leftEigenVectors_);
-    isNonSingular_ = true;
-    isDiagonalizable_ = true;
-    for (unsigned int i = 0; i < size_ && isDiagonalizable_; i++)
+    try
     {
-      if (abs(iEigenValues_[i]) > NumConstants::TINY())
-        isDiagonalizable_ = false;
+      MatrixTools::inv(rightEigenVectors_, leftEigenVectors_);
+      isNonSingular_ = true;
+      isDiagonalizable_ = true;
+      for (unsigned int i = 0; i < size_ && isDiagonalizable_; i++)
+      {
+        if (abs(iEigenValues_[i]) > NumConstants::TINY())
+          isDiagonalizable_ = false;
+      }
     }
+    catch (ZeroDivisionException& e)
+    {
+      ApplicationTools::displayMessage("Singularity during  diagonalization. Taylor series used instead.");
+      
+      isNonSingular_ = false;
+      isDiagonalizable_ = false;
+      MatrixTools::Taylor(generator_, 30, vPowGen_);
+    }
+    
+    // and the exchangeability_
+    for (size_t i = 0; i < size_; i++)
+      for (size_t j = 0; j < size_; j++)
+        exchangeability_(i,j) = generator_(i,j) / freq_[j];
   }
-  catch (ZeroDivisionException& e)
-  {
-    ApplicationTools::displayMessage("Singularity during  diagonalization. Taylor series used instead.");
-
-    isNonSingular_ = false;
-    isDiagonalizable_ = false;
-    MatrixTools::Taylor(generator_, 30, vPowGen_);
-  }
-
-  // and the exchangeability_
-  for (size_t i = 0; i < size_; i++)
-    for (size_t j = 0; j < size_; j++)
-      exchangeability_(i,j) = generator_(i,j) / freq_[j];
-
 }
 
 /******************************************************************************/
-double RN95s::Pij_t(int i, int j, double d) const
+double RN95s::Pij_t(size_t i, size_t j, double d) const
 {
   l_ = rate_ * r_ * d;
   exp1_ = exp(-l_);
@@ -261,7 +263,7 @@ double RN95s::Pij_t(int i, int j, double d) const
 }
 
 /******************************************************************************/
-double RN95s::dPij_dt(int i, int j, double d) const
+double RN95s::dPij_dt(size_t i, size_t j, double d) const
 {
   l_ = rate_ * r_ * d;
   exp1_ = -1.* rate_* r_* exp(-1. * l_);
@@ -316,7 +318,7 @@ double RN95s::dPij_dt(int i, int j, double d) const
 }
 
 /******************************************************************************/
-double RN95s::d2Pij_dt2(int i, int j, double d) const
+double RN95s::d2Pij_dt2(size_t i, size_t j, double d) const
 {
   l_ = rate_ * r_ * d;
   exp1_ = 1. * rate_ * r_ * 1.* rate_* r_* exp(-1. * l_);
diff --git a/src/Bpp/Phyl/Model/Nucleotide/RN95s.h b/src/Bpp/Phyl/Model/Nucleotide/RN95s.h
index 68d44f7..149ac36 100644
--- a/src/Bpp/Phyl/Model/Nucleotide/RN95s.h
+++ b/src/Bpp/Phyl/Model/Nucleotide/RN95s.h
@@ -138,9 +138,9 @@ public:
   clone() const { return new RN95s(*this); }
 
 public:
-  double Pij_t    (int i, int j, double d) const;
-  double dPij_dt  (int i, int j, double d) const;
-  double d2Pij_dt2(int i, int j, double d) const;
+  double Pij_t    (size_t i, size_t j, double d) const;
+  double dPij_dt  (size_t i, size_t j, double d) const;
+  double d2Pij_dt2(size_t i, size_t j, double d) const;
   const Matrix<double>& getPij_t    (double d) const;
   const Matrix<double>& getdPij_dt  (double d) const;
   const Matrix<double>& getd2Pij_dt2(double d) const;
diff --git a/src/Bpp/Phyl/Model/Nucleotide/SSR.cpp b/src/Bpp/Phyl/Model/Nucleotide/SSR.cpp
index 555355d..ef57ad9 100755
--- a/src/Bpp/Phyl/Model/Nucleotide/SSR.cpp
+++ b/src/Bpp/Phyl/Model/Nucleotide/SSR.cpp
@@ -5,36 +5,36 @@
 //
 
 /*
-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.
+  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 "SSR.h"
@@ -53,22 +53,21 @@ using namespace std;
 /******************************************************************************/
  
 SSR::SSR(
-	const NucleicAlphabet* alpha,
-	double beta,
-	double gamma,
-	double delta,
-	double theta):
+  const NucleicAlphabet* alpha,
+  double beta,
+  double gamma,
+  double delta,
+  double theta):
   AbstractParameterAliasable("SSR."),
-  AbstractSubstitutionModel(alpha, "SSR."),
-  AbstractReversibleSubstitutionModel(alpha, "SSR."),
-  beta_(beta), gamma_(gamma), delta_(delta_), theta_(theta),
+  AbstractReversibleSubstitutionModel(alpha, new CanonicalStateMap(alpha, false), "SSR."),
+  beta_(beta), gamma_(gamma), delta_(delta), theta_(theta),
   piA_((1. - theta) / 2.), piC_(theta / 2.), piG_(theta / 2.), piT_((1. - theta) / 2.)
 {
-	addParameter_(new Parameter("SSR.beta" , beta , &Parameter::R_PLUS_STAR));
-	addParameter_(new Parameter("SSR.gamma", gamma, &Parameter::R_PLUS_STAR));
-	addParameter_(new Parameter("SSR.delta", delta, &Parameter::R_PLUS_STAR));
-	addParameter_(new Parameter("SSR.theta" , theta , &Parameter::PROP_CONSTRAINT_EX));
-	updateMatrices();
+  addParameter_(new Parameter("SSR.beta" , beta , &Parameter::R_PLUS_STAR));
+  addParameter_(new Parameter("SSR.gamma", gamma, &Parameter::R_PLUS_STAR));
+  addParameter_(new Parameter("SSR.delta", delta, &Parameter::R_PLUS_STAR));
+  addParameter_(new Parameter("SSR.theta" , theta , &Parameter::PROP_CONSTRAINT_EX));
+  updateMatrices();
 }
 
 /******************************************************************************/
diff --git a/src/Bpp/Phyl/Model/Nucleotide/SSR.h b/src/Bpp/Phyl/Model/Nucleotide/SSR.h
index b565a3e..78cd14d 100755
--- a/src/Bpp/Phyl/Model/Nucleotide/SSR.h
+++ b/src/Bpp/Phyl/Model/Nucleotide/SSR.h
@@ -5,36 +5,36 @@
 //
 
 /*
-Copyright or © or Copr. Bio++ Development Team, (November 16, 2004)
+  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 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". 
+  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. 
+  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. 
+  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 fact that you are presently reading this means that you have had
+  knowledge of the CeCILL license and that you accept its terms.
 */
 
 #ifndef _SSR_H_
@@ -95,39 +95,39 @@ namespace bpp
  * - Hobolth A, Christensen O Fm Mailund T, Schierup M H (2007), PLoS_ Genetics_ 3(2) e7.
  * - Yap VB, Speed TP (1995), Journal_ Of Molecular Evolution_ 58(1) 12-18
  */
-class SSR:
-  public virtual NucleotideSubstitutionModel,
-  public AbstractReversibleSubstitutionModel
-{
-private:
-  double beta_, gamma_, delta_, theta_, piA_, piC_, piG_, piT_;
+  class SSR:
+    public virtual NucleotideSubstitutionModel,
+    public AbstractReversibleSubstitutionModel
+  {
+  private:
+    double beta_, gamma_, delta_, theta_, piA_, piC_, piG_, piT_;
   
-public:
-  SSR( const NucleicAlphabet* alpha,
-      double beta = 1.,
-      double gamma = 1.,
-      double delta = 1.,
-      double theta = 0.5);
+  public:
+    SSR( const NucleicAlphabet* alpha,
+         double beta = 1.,
+         double gamma = 1.,
+         double delta = 1.,
+         double theta = 0.5);
   
-  virtual ~SSR() {}
+    virtual ~SSR() {}
   
 #ifndef NO_VIRTUAL_COV
-  SSR*
+    SSR*
 #else
-  Clonable*
+    Clonable*
 #endif
-  clone() const { return new SSR(*this); }
+    clone() const { return new SSR(*this); }
   
-public:
-  std::string getName() const { return "Strand Symmetric Reversible"; }
+  public:
+    std::string getName() const { return "Strand Symmetric Reversible"; }
   
-  void updateMatrices();
+    void updateMatrices();
   
-  /**
-   * @brief This method is redefined to actualize the corresponding parameters theta too.
-   */
-  void setFreq(std::map<int, double>&);
-};
+    /**
+     * @brief This method is redefined to actualize the corresponding parameters theta too.
+     */
+    void setFreq(std::map<int, double>&);
+  };
 
 } //end of namespace bpp.
 
diff --git a/src/Bpp/Phyl/Model/Nucleotide/T92.cpp b/src/Bpp/Phyl/Model/Nucleotide/T92.cpp
index 0a7eceb..f3a8cd0 100644
--- a/src/Bpp/Phyl/Model/Nucleotide/T92.cpp
+++ b/src/Bpp/Phyl/Model/Nucleotide/T92.cpp
@@ -56,8 +56,7 @@ using namespace std;
 
 T92::T92(const NucleicAlphabet* alpha, double kappa, double theta) :
   AbstractParameterAliasable("T92."),
-  AbstractSubstitutionModel(alpha, "T92."),
-  AbstractReversibleSubstitutionModel(alpha, "T92."),
+  AbstractReversibleSubstitutionModel(alpha, new CanonicalStateMap(alpha, false), "T92."),
   kappa_(kappa),
   theta_(theta),
   k_(),
@@ -188,7 +187,7 @@ void T92::updateMatrices()
 
 /******************************************************************************/
 
-double T92::Pij_t(int i, int j, double d) const
+double T92::Pij_t(size_t i, size_t j, double d) const
 {
   l_ = rate_ * r_ * d;
   exp1_ = exp(-l_);
@@ -242,7 +241,7 @@ double T92::Pij_t(int i, int j, double d) const
 
 /******************************************************************************/
 
-double T92::dPij_dt(int i, int j, double d) const
+double T92::dPij_dt(size_t i, size_t j, double d) const
 {
   l_ = rate_ * r_ * d;
   exp1_ = exp(-l_);
@@ -296,7 +295,7 @@ double T92::dPij_dt(int i, int j, double d) const
 
 /******************************************************************************/
 
-double T92::d2Pij_dt2(int i, int j, double d) const
+double T92::d2Pij_dt2(size_t i, size_t j, double d) const
 {
   double k2_ = k_ * k_;
   l_ = rate_ * r_ * d;
diff --git a/src/Bpp/Phyl/Model/Nucleotide/T92.h b/src/Bpp/Phyl/Model/Nucleotide/T92.h
index 39068b2..191dc1d 100644
--- a/src/Bpp/Phyl/Model/Nucleotide/T92.h
+++ b/src/Bpp/Phyl/Model/Nucleotide/T92.h
@@ -178,9 +178,9 @@ public:
   clone() const { return new T92(*this); }
 
 public:
-  double Pij_t    (int i, int j, double d) const;
-  double dPij_dt  (int i, int j, double d) const;
-  double d2Pij_dt2(int i, int j, double d) const;
+  double Pij_t    (size_t i, size_t j, double d) const;
+  double dPij_dt  (size_t i, size_t j, double d) const;
+  double d2Pij_dt2(size_t i, size_t j, double d) const;
   const Matrix<double>& getPij_t(double d) const;
   const Matrix<double>& getdPij_dt(double d) const;
   const Matrix<double>& getd2Pij_dt2(double d) const;
diff --git a/src/Bpp/Phyl/Model/Nucleotide/TN93.cpp b/src/Bpp/Phyl/Model/Nucleotide/TN93.cpp
index 83f5179..7878d97 100755
--- a/src/Bpp/Phyl/Model/Nucleotide/TN93.cpp
+++ b/src/Bpp/Phyl/Model/Nucleotide/TN93.cpp
@@ -5,7 +5,7 @@
 //
 
 /*
-Copyright or © or Copr. Bio++ Developement Team, (November 16, 2004)
+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.
@@ -43,7 +43,7 @@ knowledge of the CeCILL license and that you accept its terms.
 #include <Bpp/Numeric/Matrix/MatrixTools.h>
 #include <Bpp/Numeric/Matrix/EigenValue.h>
 
-// From SeqLib:
+// From bpp-seq:
 #include <Bpp/Seq/Container/SequenceContainerTools.h>
 
 // From the STL:
@@ -64,8 +64,7 @@ TN93::TN93(
 	double piG,
 	double piT):
   AbstractParameterAliasable("TN93."),
-  AbstractSubstitutionModel(alpha, "TN93."),
-  AbstractReversibleSubstitutionModel(alpha, "TN93."),
+  AbstractReversibleSubstitutionModel(alpha, new CanonicalStateMap(alpha, false), "TN93."),
   kappa1_(kappa1), kappa2_(kappa2), 
   piA_(piA), piC_(piC), piG_(piG), piT_(piT), piY_(), piR_(),
   r_(), k1_(), k2_(),
@@ -164,7 +163,7 @@ void TN93::updateMatrices()
 	
 /******************************************************************************/
 
-double TN93::Pij_t(int i, int j, double d) const
+double TN93::Pij_t(size_t i, size_t j, double d) const
 {
   l_ = rate_ * r_ * d;
 	exp1_ = exp(-l_);
@@ -215,7 +214,7 @@ double TN93::Pij_t(int i, int j, double d) const
 
 /******************************************************************************/
 
-double TN93::dPij_dt(int i, int j, double d) const
+double TN93::dPij_dt(size_t i, size_t j, double d) const
 {
   l_ = rate_ * r_ * d;
 	exp1_ = exp(-l_);
@@ -266,7 +265,7 @@ double TN93::dPij_dt(int i, int j, double d) const
 
 /******************************************************************************/
 
-double TN93::d2Pij_dt2(int i, int j, double d) const
+double TN93::d2Pij_dt2(size_t i, size_t j, double d) const
 {
   double r_2 = rate_ * rate_ * r_ * r_;
   l_ = rate_ * r_ * d;
diff --git a/src/Bpp/Phyl/Model/Nucleotide/TN93.h b/src/Bpp/Phyl/Model/Nucleotide/TN93.h
index 0f31570..f20ede1 100755
--- a/src/Bpp/Phyl/Model/Nucleotide/TN93.h
+++ b/src/Bpp/Phyl/Model/Nucleotide/TN93.h
@@ -5,7 +5,7 @@
 //
 
 /*
-Copyright or © or Copr. CNRS, (November 16, 2004)
+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.
@@ -45,7 +45,7 @@ knowledge of the CeCILL license and that you accept its terms.
 
 #include <Bpp/Numeric/Constraints.h>
 
-// From SeqLib:
+// From bpp-seq:
 #include <Bpp/Seq/Alphabet/NucleicAlphabet.h>
 #include <Bpp/Seq/Container/SequenceContainer.h>
 
@@ -157,9 +157,9 @@ class TN93 :
 
   public:
 
-		double Pij_t    (int i, int j, double d) const;
-		double dPij_dt  (int i, int j, double d) const;
-		double d2Pij_dt2(int i, int j, double d) const;
+		double Pij_t    (size_t i, size_t j, double d) const;
+		double dPij_dt  (size_t i, size_t j, double d) const;
+		double d2Pij_dt2(size_t i, size_t j, double d) const;
 		const Matrix<double>& getPij_t    (double d) const;
 		const Matrix<double>& getdPij_dt  (double d) const;
 		const Matrix<double>& getd2Pij_dt2(double d) const;
diff --git a/src/Bpp/Phyl/Model/Nucleotide/YpR.cpp b/src/Bpp/Phyl/Model/Nucleotide/YpR.cpp
index 7ec134d..cc3a961 100644
--- a/src/Bpp/Phyl/Model/Nucleotide/YpR.cpp
+++ b/src/Bpp/Phyl/Model/Nucleotide/YpR.cpp
@@ -53,29 +53,29 @@ using namespace bpp;
 
 YpR::YpR(const RNY* alph, SubstitutionModel* const pm, const std::string& prefix) :
   AbstractParameterAliasable(prefix),
-  AbstractSubstitutionModel(alph,prefix),
-  _pmodel(pm->clone()),
+  AbstractSubstitutionModel(alph, new CanonicalStateMap(alph, false), prefix),
+  pmodel_(pm->clone()),
   _nestedPrefix(pm->getNamespace())
 {
-  _pmodel->setNamespace(prefix + _nestedPrefix);
-  _pmodel->enableEigenDecomposition(0);
-  addParameters_(_pmodel->getParameters());
+  pmodel_->setNamespace(prefix + _nestedPrefix);
+  pmodel_->enableEigenDecomposition(0);
+  addParameters_(pmodel_->getParameters());
 }
 
 YpR::YpR(const YpR& ypr, const std::string& prefix) :
   AbstractParameterAliasable(ypr),
   AbstractSubstitutionModel(ypr),
-  _pmodel(ypr._pmodel->clone()),
+  pmodel_(ypr.pmodel_->clone()),
   _nestedPrefix(ypr.getNestedPrefix())
 
 {
-  _pmodel->setNamespace(prefix + _nestedPrefix);
+  pmodel_->setNamespace(prefix + _nestedPrefix);
 }
 
 YpR::YpR(const YpR& ypr) :
   AbstractParameterAliasable(ypr),
   AbstractSubstitutionModel(ypr),
-  _pmodel(ypr._pmodel->clone()),
+  pmodel_(ypr.pmodel_->clone()),
   _nestedPrefix(ypr.getNestedPrefix())
 {}
 
@@ -90,75 +90,75 @@ void YpR::updateMatrices(double CgT, double cGA,
                          double CaT, double cAG,
                          double TaC, double tAC)
 {
-  //  check_model(_pmodel);
+  //  check_model(pmodel_);
 
   // Generator:
-  const Alphabet* alph = _pmodel->getAlphabet();
-  std::vector<int> l(4);
+  const Alphabet* alph = pmodel_->getAlphabet();
+  std::vector<size_t> l(4);
 
-  l[0] = alph->charToInt("A");
-  l[1] = alph->charToInt("G");
-  l[2] = alph->charToInt("C");
-  l[3] = alph->charToInt("T");
+  l[0] = alph->getStateIndex("A");
+  l[1] = alph->getStateIndex("G");
+  l[2] = alph->getStateIndex("C");
+  l[3] = alph->getStateIndex("T");
 
-  unsigned int i,j,i1,i2,i3,j1,j2,j3;
+  unsigned int i, j, i1, i2, i3, j1, j2, j3;
 
   std::vector<double> a(4);  // a[A], a[G], a[C], a[T]
   std::vector<double> b(4);  // b[A], b[G], b[C], b[T]
 
   for (i = 0; i < 2; i++)
   {
-    a[i] = _pmodel->Qij(l[1 - i],l[i]);
-    b[i] = _pmodel->Qij(l[3 - i],l[i]);
-    a[i + 2] = _pmodel->Qij(l[3 - i],l[i + 2]);
-    b[i + 2] = _pmodel->Qij(l[1 - i],l[i + 2]);
+    a[i] = pmodel_->Qij(l[1 - i], l[i]);
+    b[i] = pmodel_->Qij(l[3 - i], l[i]);
+    a[i + 2] = pmodel_->Qij(l[3 - i], l[i + 2]);
+    b[i + 2] = pmodel_->Qij(l[1 - i], l[i + 2]);
   }
 
   // M_1
-  RowMatrix<double> M1(3,3);
-
-  M1(0,0) = 0;
-  M1(0,1) = b[2];
-  M1(0,2) = b[3];
-  M1(1,0) = b[0] + b[1];
-  M1(1,1) = 0;
-  M1(1,2) = a[3];
-  M1(2,0) = b[0] + b[1];
-  M1(2,1) = a[2];
-  M1(2,2) = 0;
+  RowMatrix<double> M1(3, 3);
+
+  M1(0, 0) = 0;
+  M1(0, 1) = b[2];
+  M1(0, 2) = b[3];
+  M1(1, 0) = b[0] + b[1];
+  M1(1, 1) = 0;
+  M1(1, 2) = a[3];
+  M1(2, 0) = b[0] + b[1];
+  M1(2, 1) = a[2];
+  M1(2, 2) = 0;
 
   // M_2
-  RowMatrix<double> M2(4,4);
-
-  M2(0,0) = 0;
-  M2(0,1) = a[1];
-  M2(0,2) = b[2];
-  M2(0,3) = b[3];
-  M2(1,0) = a[0];
-  M2(1,1) = 0;
-  M2(1,2) = b[2];
-  M2(1,3) = b[3];
-  M2(2,0) = b[0];
-  M2(2,1) = b[1];
-  M2(2,2) = 0;
-  M2(2,3) = a[3];
-  M2(3,0) = b[0];
-  M2(3,1) = b[1];
-  M2(3,2) = a[2];
-  M2(3,3) = 0;
+  RowMatrix<double> M2(4, 4);
+
+  M2(0, 0) = 0;
+  M2(0, 1) = a[1];
+  M2(0, 2) = b[2];
+  M2(0, 3) = b[3];
+  M2(1, 0) = a[0];
+  M2(1, 1) = 0;
+  M2(1, 2) = b[2];
+  M2(1, 3) = b[3];
+  M2(2, 0) = b[0];
+  M2(2, 1) = b[1];
+  M2(2, 2) = 0;
+  M2(2, 3) = a[3];
+  M2(3, 0) = b[0];
+  M2(3, 1) = b[1];
+  M2(3, 2) = a[2];
+  M2(3, 3) = 0;
 
   // M_3
-  RowMatrix<double> M3(3,3);
+  RowMatrix<double> M3(3, 3);
 
-  M3(0,0) = 0;
-  M3(0,1) = a[1];
-  M3(0,2) = b[2] + b[3];
-  M3(1,0) = a[0];
-  M3(1,1) = 0;
-  M3(1,2) = b[2] + b[3];
-  M3(2,0) = b[0];
-  M3(2,1) = b[1];
-  M3(2,2) = 0;
+  M3(0, 0) = 0;
+  M3(0, 1) = a[1];
+  M3(0, 2) = b[2] + b[3];
+  M3(1, 0) = a[0];
+  M3(1, 1) = 0;
+  M3(1, 2) = b[2] + b[3];
+  M3(2, 0) = b[0];
+  M3(2, 1) = b[1];
+  M3(2, 2) = 0;
 
 
   for (i1 = 0; i1 < 3; i1++)
@@ -176,13 +176,13 @@ void YpR::updateMatrices(double CgT, double cGA,
             {
               j = 12 * j1 + 3 * j2 + j3;
               if ((i1 == j1) && (i2 == j2))
-                generator_(i,j) = M3(i3,j3);
+                generator_(i, j) = M3(i3, j3);
               else if ((i1 == j1) && (i3 == j3))
-                generator_(i,j) = M2(i2,j2);
+                generator_(i, j) = M2(i2, j2);
               else if ((i2 == j2) && (i3 == j3))
-                generator_(i,j) = M1(i1,j1);
+                generator_(i, j) = M1(i1, j1);
               else
-                generator_(i,j) = 0;
+                generator_(i, j) = 0;
             }
           }
         }
@@ -194,29 +194,29 @@ void YpR::updateMatrices(double CgT, double cGA,
 
   for (i3 = 0; i3 < 3; i3++)
   {
-    generator_(15 + i3,12 + i3) += cGA * a[0]; // CG -> CA
-    generator_(12 * i3 + 7,12 * i3 + 6) += cGA * a[0];
+    generator_(15 + i3, 12 + i3) += cGA * a[0]; // CG -> CA
+    generator_(12 * i3 + 7, 12 * i3 + 6) += cGA * a[0];
 
-    generator_(15 + i3,27 + i3) += CgT * a[3]; // CG -> TG
-    generator_(12 * i3 + 7,12 * i3 + 10) += CgT * a[3];
+    generator_(15 + i3, 27 + i3) += CgT * a[3]; // CG -> TG
+    generator_(12 * i3 + 7, 12 * i3 + 10) += CgT * a[3];
 
-    generator_(27 + i3,24 + i3) += tGA * a[0]; // TG -> TA
-    generator_(12 * i3 + 10,12 * i3 + 9) += tGA * a[0];
+    generator_(27 + i3, 24 + i3) += tGA * a[0]; // TG -> TA
+    generator_(12 * i3 + 10, 12 * i3 + 9) += tGA * a[0];
 
-    generator_(27 + i3,15 + i3) += TgC * a[2]; // TG -> CG
-    generator_(12 * i3 + 10,12 * i3 + 7) += TgC * a[2];
+    generator_(27 + i3, 15 + i3) += TgC * a[2]; // TG -> CG
+    generator_(12 * i3 + 10, 12 * i3 + 7) += TgC * a[2];
 
-    generator_(12 + i3,24 + i3) += CaT * a[3]; // CA -> TA
-    generator_(12 * i3 + 6,12 * i3 + 9) += CaT * a[3];
+    generator_(12 + i3, 24 + i3) += CaT * a[3]; // CA -> TA
+    generator_(12 * i3 + 6, 12 * i3 + 9) += CaT * a[3];
 
-    generator_(12 + i3,15 + i3) += cAG * a[1]; // CA -> CG
-    generator_(12 * i3 + 6,12 * i3 + 7) += cAG * a[1];
+    generator_(12 + i3, 15 + i3) += cAG * a[1]; // CA -> CG
+    generator_(12 * i3 + 6, 12 * i3 + 7) += cAG * a[1];
 
-    generator_(24 + i3,27 + i3) += tAC * a[1]; // TA -> TG
-    generator_(12 * i3 + 9,12 * i3 + 10) += tAC * a[1];
+    generator_(24 + i3, 27 + i3) += tAC * a[1]; // TA -> TG
+    generator_(12 * i3 + 9, 12 * i3 + 10) += tAC * a[1];
 
-    generator_(24 + i3,12 + i3) += TaC * a[2]; // TA -> CA
-    generator_(12 * i3 + 9,12 * i3 + 6) += TaC * a[2];
+    generator_(24 + i3, 12 + i3) += TaC * a[2]; // TA -> CA
+    generator_(12 * i3 + 9, 12 * i3 + 6) += TaC * a[2];
   }
 
   double x;
@@ -227,9 +227,9 @@ void YpR::updateMatrices(double CgT, double cGA,
     for (j = 0; j < 36; j++)
     {
       if (j != i)
-        x += generator_(i,j);
+        x += generator_(i, j);
     }
-    generator_(i,i) = -x;
+    generator_(i, i) = -x;
   }
 
   // calcul spectral
@@ -240,62 +240,75 @@ void YpR::updateMatrices(double CgT, double cGA,
 
   rightEigenVectors_ = ev.getV();
 
-   try {
-     MatrixTools::inv(rightEigenVectors_,leftEigenVectors_);
-
-     isNonSingular_=true;
-     isDiagonalizable_=true;
-     for (i=0; i<size_; i++)
-       if (abs(iEigenValues_[i])> NumConstants::TINY()){
-         isDiagonalizable_=false;
-       }
-
-     // frequence stationnaire
-    
-     x = 0;
-     j = 0;
-     while (j < 36){
-       if (abs(eigenValues_[j]) < NumConstants::SMALL() &&
-           abs(iEigenValues_[j]) < NumConstants::SMALL()) {
-         eigenValues_[j]=0; //to avoid approximation problems in the future
-         for (i = 0; i < 36; i++)
-           {
-             freq_[i] = leftEigenVectors_(j,i);
-             x += freq_[i];
-           }
-         break;
-       }
-       j++;
-     }
-     for (i = 0; i < 36; i++)
-       freq_[i] /= x;
-   }
-   catch (ZeroDivisionException& e){
-     ApplicationTools::displayMessage("Singularity during  diagonalization. Taylor series used instead.");
-     isNonSingular_=false;
-     isDiagonalizable_=false;
-
-     if (vPowGen_.size()==0)
-       vPowGen_.resize(30);
-
-     double min=generator_(0,0);
-     for (i = 1; i < 36; i++)
-       if (min>generator_(i,i))
-         min=generator_(i,i);
-     
-     MatrixTools::scale(generator_,-1/min);
-     
-     MatrixTools::getId(36,tmpMat_);    // to compute the equilibrium frequency  (Q+Id)^256
-     
-     MatrixTools::add(tmpMat_,generator_);
-     MatrixTools::pow(tmpMat_,256,vPowGen_[0]);
-     
-     for (i=0;i<36;i++)
-       freq_[i]=vPowGen_[0](0,i);
-     
-     MatrixTools::getId(36,vPowGen_[0]);
-   }
-  
+  try
+  {
+    MatrixTools::inv(rightEigenVectors_, leftEigenVectors_);
+
+    isNonSingular_ = true;
+    isDiagonalizable_ = true;
+    for (i = 0; i < size_; i++)
+    {
+      if (abs(iEigenValues_[i]) > NumConstants::TINY())
+      {
+        isDiagonalizable_ = false;
+      }
+    }
+
+    // frequence stationnaire
+
+    x = 0;
+    j = 0;
+    while (j < 36)
+    {
+      if (abs(eigenValues_[j]) < NumConstants::SMALL() &&
+          abs(iEigenValues_[j]) < NumConstants::SMALL())
+      {
+        eigenValues_[j] = 0; // to avoid approximation problems in the future
+        for (i = 0; i < 36; i++)
+        {
+          freq_[i] = leftEigenVectors_(j, i);
+          x += freq_[i];
+        }
+        break;
+      }
+      j++;
+    }
+    for (i = 0; i < 36; i++)
+    {
+      freq_[i] /= x;
+    }
+  }
+  catch (ZeroDivisionException& e)
+  {
+    ApplicationTools::displayMessage("Singularity during  diagonalization. Taylor series used instead.");
+    isNonSingular_ = false;
+    isDiagonalizable_ = false;
+
+    if (vPowGen_.size() == 0)
+      vPowGen_.resize(30);
+
+    double min = generator_(0, 0);
+    for (i = 1; i < 36; i++)
+    {
+      if (min > generator_(i, i))
+        min = generator_(i, i);
+    }
+
+    MatrixTools::scale(generator_, -1 / min);
+
+    MatrixTools::getId(36, tmpMat_);    // to compute the equilibrium frequency  (Q+Id)^256
+
+    MatrixTools::add(tmpMat_, generator_);
+    MatrixTools::pow(tmpMat_, 256, vPowGen_[0]);
+
+    for (i = 0; i < 36; i++)
+    {
+      freq_[i] = vPowGen_[0](0, i);
+    }
+
+    MatrixTools::getId(36, vPowGen_[0]);
+  }
+
   // mise a l'echelle
 
   x = 0;
@@ -311,28 +324,32 @@ void YpR::updateMatrices(double CgT, double cGA,
           if (j2 != i2)
           {
             j = 12 * i1 + 3 * j2 + i3;
-            x += freq_[i] * generator_(i,j);
+            x += freq_[i] * generator_(i, j);
           }
         }
       }
     }
   }
 
-  MatrixTools::scale(generator_,1 / x);
+  MatrixTools::scale(generator_, 1 / x);
 
   if (!isNonSingular_)
-    MatrixTools::Taylor(generator_,30,vPowGen_);
+    MatrixTools::Taylor(generator_, 30, vPowGen_);
 
-  for (i = 0; i < 36; i++){
+  for (i = 0; i < 36; i++)
+  {
     eigenValues_[i] /= x;
     iEigenValues_[i] /= x;
   }
 
   // and the exchangeability_
-  for ( i = 0; i < size_; i++)
-    for ( j = 0; j < size_; j++)
-      exchangeability_(i,j) = generator_(i,j) / freq_[j];
-
+  for (i = 0; i < size_; i++)
+  {
+    for (j = 0; j < size_; j++)
+    {
+      exchangeability_(i, j) = generator_(i, j) / freq_[j];
+    }
+  }
 }
 
 void YpR::check_model(SubstitutionModel* const pm) const
@@ -345,34 +362,32 @@ throw (Exception)
   if (alph->getAlphabetType() != "DNA alphabet")
     throw Exception("Need a DNA model");
 
-  std::vector<int> l(4);
+  std::vector<size_t> l(4);
 
-  l[0] = alph->charToInt("A");
-  l[1] = alph->charToInt("G");
-  l[2] = alph->charToInt("C");
-  l[3] = alph->charToInt("T");
+  l[0] = alph->getStateIndex("A");
+  l[1] = alph->getStateIndex("G");
+  l[2] = alph->getStateIndex("C");
+  l[3] = alph->getStateIndex("T");
 
   // Check that the model is good for YpR
 
-  int i;
-
-  for (i = 0; i < 2; i++)
+  for (size_t i = 0; i < 2; ++i)
   {
-    if (pm->Qij(l[2],l[i]) != pm->Qij(l[3],l[i]))
+    if (pm->Qij(l[2], l[i]) != pm->Qij(l[3], l[i]))
       throw Exception("Not R/Y Model " + pm->getName());
   }
-  for (i = 2; i < 4; i++)
+  for (size_t i = 2; i < 4; ++i)
   {
-    if (pm->Qij(l[0],l[i]) != pm->Qij(l[1],l[i]))
+    if (pm->Qij(l[0], l[i]) != pm->Qij(l[1], l[i]))
       throw Exception("Not R/Y Model " + pm->getName());
   }
 }
 
 void YpR::setNamespace(const std::string& prefix)
 {
-   AbstractSubstitutionModel::setNamespace(prefix);
+  AbstractSubstitutionModel::setNamespace(prefix);
   // We also need to update the namespace of the nested model:
-  _pmodel->setNamespace(prefix + _nestedPrefix);
+  pmodel_->setNamespace(prefix + _nestedPrefix);
 }
 
 // ///////////////////////////////////////////////
@@ -384,7 +399,8 @@ void YpR::setNamespace(const std::string& prefix)
 YpR_Sym::YpR_Sym(const RNY* alph,
                  SubstitutionModel* const pm,
                  double CgT, double TgC,
-                 double CaT, double TaC) : AbstractParameterAliasable("YpR_Sym."), YpR(alph, pm,"YpR_Sym.")
+                 double CaT, double TaC) : AbstractParameterAliasable("YpR_Sym."),
+  YpR(alph, pm, "YpR_Sym.")
 {
   addParameter_(new Parameter("YpR_Sym.rCgT", CgT, &Parameter::R_PLUS));
   addParameter_(new Parameter("YpR_Sym.rTgC", TgC, &Parameter::R_PLUS));
@@ -396,15 +412,16 @@ YpR_Sym::YpR_Sym(const RNY* alph,
 
 void YpR_Sym::updateMatrices()
 {
-   double rCgT = getParameterValue("rCgT");
-   double rTgC = getParameterValue("rTgC");
-   double rCaT = getParameterValue("rCaT");
-   double rTaC = getParameterValue("rTaC");
+  double rCgT = getParameterValue("rCgT");
+  double rTgC = getParameterValue("rTgC");
+  double rCaT = getParameterValue("rCaT");
+  double rTaC = getParameterValue("rTaC");
 
-   YpR::updateMatrices(rCgT, rCgT, rTgC, rTgC, rCaT, rCaT, rTaC, rTaC);
+  YpR::updateMatrices(rCgT, rCgT, rTgC, rTgC, rCaT, rCaT, rTaC, rTaC);
 }
 
-YpR_Sym::YpR_Sym(const YpR_Sym& ypr) : AbstractParameterAliasable(ypr), YpR(ypr,"YpR_Sym.")
+YpR_Sym::YpR_Sym(const YpR_Sym& ypr) : AbstractParameterAliasable(ypr),
+  YpR(ypr, "YpR_Sym.")
 {}
 
 /******************************************************************************/
@@ -425,7 +442,8 @@ YpR_Gen::YpR_Gen(const RNY* alph,
                  double CgT, double cGA,
                  double TgC, double tGA,
                  double CaT, double cAG,
-                 double TaC, double tAG) : AbstractParameterAliasable("YpR_Gen."), YpR(alph, pm,"YpR_Gen.")
+                 double TaC, double tAG) : AbstractParameterAliasable("YpR_Gen."),
+  YpR(alph, pm, "YpR_Gen.")
 {
   addParameter_(new Parameter("YpR_Gen.rCgT", CgT, &Parameter::R_PLUS));
   addParameter_(new Parameter("YpR_Gen.rcGA", cGA, &Parameter::R_PLUS));
@@ -441,19 +459,20 @@ YpR_Gen::YpR_Gen(const RNY* alph,
 
 void YpR_Gen::updateMatrices()
 {
-   double rCgT = getParameterValue("rCgT");
-   double rcGA = getParameterValue("rcGA");
-   double rTgC = getParameterValue("rTgC");
-   double rtGA = getParameterValue("rtGA");
-   double rCaT = getParameterValue("rCaT");
-   double rcAG = getParameterValue("rcAG");
-   double rTaC = getParameterValue("rTaC");
-   double rtAG = getParameterValue("rtAG");
-
-   YpR::updateMatrices(rCgT, rcGA, rTgC, rtGA, rCaT, rcAG, rTaC, rtAG);
+  double rCgT = getParameterValue("rCgT");
+  double rcGA = getParameterValue("rcGA");
+  double rTgC = getParameterValue("rTgC");
+  double rtGA = getParameterValue("rtGA");
+  double rCaT = getParameterValue("rCaT");
+  double rcAG = getParameterValue("rcAG");
+  double rTaC = getParameterValue("rTaC");
+  double rtAG = getParameterValue("rtAG");
+
+  YpR::updateMatrices(rCgT, rcGA, rTgC, rtGA, rCaT, rcAG, rTaC, rtAG);
 }
 
-YpR_Gen::YpR_Gen(const YpR_Gen& ypr) : AbstractParameterAliasable(ypr), YpR(ypr,"YpR_Gen.")
+YpR_Gen::YpR_Gen(const YpR_Gen& ypr) : AbstractParameterAliasable(ypr),
+  YpR(ypr, "YpR_Gen.")
 {
   updateMatrices();
 }
@@ -464,5 +483,3 @@ std::string YpR_Gen::getName() const
 {
   return "YpR_Gen";
 }
-
-
diff --git a/src/Bpp/Phyl/Model/Nucleotide/YpR.h b/src/Bpp/Phyl/Model/Nucleotide/YpR.h
index 3e39ab6..e575a1a 100644
--- a/src/Bpp/Phyl/Model/Nucleotide/YpR.h
+++ b/src/Bpp/Phyl/Model/Nucleotide/YpR.h
@@ -124,7 +124,7 @@ class YpR :
   public AbstractSubstitutionModel
 {
 protected:
-  SubstitutionModel*  _pmodel;
+  SubstitutionModel* pmodel_;
 
   // Check that the model is good for YpR
   void check_model(SubstitutionModel* const) const
@@ -149,16 +149,16 @@ protected:
     AbstractParameterAliasable::operator=(ypr);
     AbstractSubstitutionModel::operator=(ypr);
     _nestedPrefix = ypr._nestedPrefix;
-    _pmodel = ypr._pmodel->clone();
+    pmodel_ = ypr.pmodel_->clone();
     return *this;
   }
 
 public:
   virtual ~YpR()
   {
-    if (_pmodel)
-      delete _pmodel;
-    _pmodel = 0;
+    if (pmodel_)
+      delete pmodel_;
+    pmodel_ = 0;
   }
 
 protected:
@@ -173,7 +173,7 @@ protected:
 public:
   //  virtual std::string getName() const;
 
-  const SubstitutionModel* getNestedModel() const {return _pmodel;}
+  const SubstitutionModel* getNestedModel() const {return pmodel_;}
   
   size_t getNumberOfStates() const { return 36; }
 
@@ -184,7 +184,7 @@ public:
   void fireParameterChanged(const ParameterList& parameters)
   {
     AbstractSubstitutionModel::fireParameterChanged(parameters);
-   _pmodel->matchParametersValues(parameters);
+   pmodel_->matchParametersValues(parameters);
    updateMatrices();
   }
 };
diff --git a/src/Bpp/Phyl/Model/Nucleotide/gBGC.cpp b/src/Bpp/Phyl/Model/Nucleotide/gBGC.cpp
index 2eca8c9..aae385e 100644
--- a/src/Bpp/Phyl/Model/Nucleotide/gBGC.cpp
+++ b/src/Bpp/Phyl/Model/Nucleotide/gBGC.cpp
@@ -5,36 +5,36 @@
 //
 
 /*
-   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.
- */
+  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 "gBGC.h"
 
@@ -51,15 +51,15 @@ using namespace bpp;
 
 gBGC::gBGC(const NucleicAlphabet* alph, NucleotideSubstitutionModel* const pm, double gamma) :
   AbstractParameterAliasable("gBGC."),
-  AbstractSubstitutionModel(alph,"gBGC."),
-  pmodel_(pm->clone()),
+  AbstractSubstitutionModel(alph, new CanonicalStateMap(alph, false), "gBGC."),
+  model_(pm),
   nestedPrefix_(pm->getNamespace()),
   gamma_(gamma)
 {
-  pmodel_->setNamespace("gBGC."+nestedPrefix_);
-  pmodel_->enableEigenDecomposition(0);
-  addParameters_(pmodel_->getParameters());
-  addParameter_(new Parameter("gBGC.gamma", gamma_,new IntervalConstraint(-999, 10, true, true), true));
+  model_->setNamespace("gBGC."+nestedPrefix_);
+  model_->enableEigenDecomposition(0);
+  addParameters_(model_->getParameters());
+  addParameter_(new Parameter("gBGC.gamma", gamma_, new IntervalConstraint(-999, 10, true, true), true));
 
   updateMatrices();
 }
@@ -67,7 +67,7 @@ gBGC::gBGC(const NucleicAlphabet* alph, NucleotideSubstitutionModel* const pm, d
 gBGC::gBGC(const gBGC& gbgc) :
   AbstractParameterAliasable(gbgc),
   AbstractSubstitutionModel(gbgc),
-  pmodel_(gbgc.pmodel_->clone()),
+  model_(gbgc.model_->clone()),
   nestedPrefix_(gbgc.nestedPrefix_),
   gamma_(gbgc.gamma_)
 {
@@ -77,7 +77,7 @@ gBGC& gBGC::operator=(const gBGC& gbgc)
 {
   AbstractParameterAliasable::operator=(gbgc);
   AbstractSubstitutionModel::operator=(gbgc);
-  pmodel_ = gbgc.pmodel_->clone();
+  model_ = auto_ptr<NucleotideSubstitutionModel>(gbgc.model_.get());
   nestedPrefix_ = gbgc.nestedPrefix_;
   gamma_=gbgc.gamma_;
   return *this;
@@ -85,8 +85,8 @@ gBGC& gBGC::operator=(const gBGC& gbgc)
 
 void gBGC::fireParameterChanged(const ParameterList& parameters)
 {
-  pmodel_->matchParametersValues(parameters);
-  AbstractSubstitutionModel::matchParametersValues(parameters);
+  AbstractSubstitutionModel::fireParameterChanged(parameters);
+  model_->matchParametersValues(parameters);
   updateMatrices();
 }
 
@@ -96,70 +96,145 @@ void gBGC::updateMatrices()
   unsigned int i,j;
   // Generator:
   double eg=exp(gamma_);
+  
   for ( i = 0; i < 4; i++)
     for ( j = 0; j < 4; j++)
-      generator_(i,j)=pmodel_->Qij(i,j);
+      generator_(i,j)=model_->Qij(i,j);
 
   generator_(0,1) *= eg;
   generator_(0,2) *= eg;
   generator_(3,1) *= eg;
   generator_(3,2) *= eg;
+  generator_(1,0) /= eg;
+  generator_(2,0) /= eg;
+  generator_(1,3) /= eg;
+  generator_(2,3) /= eg;
 
   generator_(0,0) -= (generator_(0,1)+generator_(0,2))*(1-1/eg);
   generator_(3,3) -= (generator_(3,1)+generator_(3,2))*(1-1/eg);
 
-  // calcul spectral
+  if (enableEigenDecomposition())
+  {
+    // calcul spectral
 
-  EigenValue<double> ev(generator_);
-  eigenValues_ = ev.getRealEigenValues();
+    EigenValue<double> ev(generator_);
+    eigenValues_ = ev.getRealEigenValues();
+    iEigenValues_ = ev.getImagEigenValues();
   
-  rightEigenVectors_ = ev.getV();
-  MatrixTools::inv(rightEigenVectors_,leftEigenVectors_);
-
-  iEigenValues_ = ev.getImagEigenValues();
-
-  // frequence stationnaire
-  double x = 0;
-  j = 0;
-  while (j < 4){
-    if (abs(eigenValues_[j]) < 0.000001 && abs(iEigenValues_[j]) < 0.000001) {
-      eigenValues_[j]=0; //to avoid approximation problems in the future
-      iEigenValues_[j]=0; //to avoid approximation problems in the future
-      for (i = 0; i < 4; i++)
+    rightEigenVectors_ = ev.getV();
+    try
+    {
+      MatrixTools::inv(rightEigenVectors_, leftEigenVectors_);
+      isNonSingular_ = true;
+      isDiagonalizable_ = true;
+      
+      for (i = 0; i < 4 && isDiagonalizable_; i++)
+      {
+        if (abs(iEigenValues_[i]) > NumConstants::TINY())
+          isDiagonalizable_ = false;
+      }
+
+      // frequence stationnaire
+
+      if (isDiagonalizable_)
+      {
+        size_t nulleigen = 0;
+        double val;
+        isNonSingular_ = false;
+        
+        while (nulleigen < 4){
+          if (abs(eigenValues_[nulleigen]) < 0.000001 && abs(iEigenValues_[nulleigen]) < 0.000001) {
+            val = rightEigenVectors_(0, nulleigen);
+            i=1;
+            while (i < 4)
+            {
+              if (abs(rightEigenVectors_(i, nulleigen) - val) > NumConstants::SMALL())
+                break;
+              i++;
+            }
+            
+            if (i < 4)
+              nulleigen++;
+            else
+            {
+              isNonSingular_ = true;
+              break;
+            }
+          }
+          else
+            nulleigen++;
+        }
+
+        if (isNonSingular_)
         {
-          freq_[i] = leftEigenVectors_(j,i);
-          x += freq_[i];
+          eigenValues_[nulleigen] = 0; // to avoid approximation errors on long long branches
+          iEigenValues_[nulleigen] = 0; // to avoid approximation errors on long long branches
+          
+          for (i = 0; i < 4; i++)
+            freq_[i] = leftEigenVectors_(nulleigen, i);
+          
+          val = 0;
+          for (i = 0; i < 4; i++)
+            val += freq_[i];
+          
+          for (i = 0; i < 4; i++)
+            freq_[i] /= val;
         }
-      break;
+        else
+        {
+          ApplicationTools::displayMessage("Unable to find eigenvector for eigenvalue 1 in gBGC. Taylor series used instead.");
+          isDiagonalizable_ = false;
+        }
+      }
+    }
+    catch (ZeroDivisionException& e)
+    {
+      ApplicationTools::displayMessage("Singularity during diagonalization of gBGC in gBGC. Taylor series used instead.");
+      isNonSingular_ = false;
+      isDiagonalizable_ = false;
     }
-    j++;
-  }
 
-  for (i = 0; i < 4; i++)
-    freq_[i] /= x;
+    if (!isNonSingular_)
+    {
+      double min = generator_(0, 0);
+      for (i = 1; i < 4; i++)
+      {
+        if (min > generator_(i, i))
+          min = generator_(i, i);
+      }
 
-  // mise a l'echelle
+      MatrixTools::scale(generator_, -1 / min);
 
-  x = 0;
-  for (i = 0; i < 4; i++)
-    x += freq_[i] * generator_(i,i);
+      if (vPowGen_.size() == 0)
+        vPowGen_.resize(30);
 
-  MatrixTools::scale(generator_,-1 / x);
+      MatrixTools::getId(4, tmpMat_);    // to compute the equilibrium frequency  (Q+Id)^256
+      MatrixTools::add(tmpMat_, generator_);
+      MatrixTools::pow(tmpMat_, 4, vPowGen_[0]);
 
-  for (i = 0; i < 4; i++)
-    eigenValues_[i] /= -x;
-  
-  isDiagonalizable_=true;
-  for (i = 0; i < size_ && isDiagonalizable_; i++)
-    if (abs(iEigenValues_[i])> NumConstants::SMALL()){
-      isDiagonalizable_=false;
-      break;
+      for (i = 0; i < 4; i++)
+        freq_[i] = vPowGen_[0](0, i);
+
+      MatrixTools::getId(4, vPowGen_[0]);
+    }
+
+    // mise a l'echelle
+
+    double x = 0;
+    for (i = 0; i < 4; i++)
+      x += freq_[i] * generator_(i,i);
+
+    MatrixTools::scale(generator_,-1 / x);
+    for (i = 0; i < 4; i++)
+    {
+      eigenValues_[i] /= -x;
+      iEigenValues_[i] /= -x;
     }
 
-  // and the exchangeability_
-  for ( i = 0; i < size_; i++)
-    for ( j = 0; j < size_; j++)
-      exchangeability_(i,j) = generator_(i,j) / freq_[j];
+    if (!isNonSingular_)
+      MatrixTools::Taylor(generator_, 30, vPowGen_);
+
+  }
 
 }
 
@@ -167,12 +242,12 @@ void gBGC::setNamespace(const std::string& prefix)
 {
   AbstractSubstitutionModel::setNamespace(prefix);
   // We also need to update the namespace of the nested model:
-  pmodel_->setNamespace(prefix + nestedPrefix_);
+  model_->setNamespace(prefix + nestedPrefix_);
 }
 
 
 std::string gBGC::getName() const
 {
-  return "gBGC(model=" + pmodel_->getName()+")";
+  return "gBGC";
 }
 
diff --git a/src/Bpp/Phyl/Model/Nucleotide/gBGC.h b/src/Bpp/Phyl/Model/Nucleotide/gBGC.h
index d8448b4..e9ce717 100644
--- a/src/Bpp/Phyl/Model/Nucleotide/gBGC.h
+++ b/src/Bpp/Phyl/Model/Nucleotide/gBGC.h
@@ -5,37 +5,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.
- */
+  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 _GBGC_H_
 #define _GBGC_H_
@@ -72,58 +72,55 @@ namespace bpp
  *
  */
 
-class gBGC :
+  class gBGC :
     public virtual NucleotideSubstitutionModel,
     public AbstractSubstitutionModel
-{
-private:
-  NucleotideSubstitutionModel*  pmodel_;
-  std::string nestedPrefix_;
-
-  /*
-   * @brief the value of the bias.
-   *
-   */
+  {
+  private:
+    std::auto_ptr<NucleotideSubstitutionModel>  model_;
+    std::string nestedPrefix_;
+
+    /*
+     * @brief the value of the bias.
+     *
+     */
   
-  double gamma_;
+    double gamma_;
   
-public:
-  /*
-   * @brief Build a new YpR substitution model, with no dependency
-   *   parameters
-   */
+  public:
+    /*
+     * @brief Build a new gBGC substitution model.
+     *
+     */
 
-  gBGC(const NucleicAlphabet*, NucleotideSubstitutionModel* const, double gamma=0);
+    gBGC(const NucleicAlphabet*, NucleotideSubstitutionModel* const, double gamma=0);
 
-  gBGC(const gBGC&);
+    gBGC(const gBGC&);
 
-  gBGC& operator=(const gBGC& gbgc);
+    gBGC& operator=(const gBGC& gbgc);
 
 #ifndef NOVIRTUAL_COV_
-  gBGC*
+    gBGC*
 #else
-  Clonable*
+    Clonable*
 #endif
-  clone() const { return new gBGC(*this); }
+    clone() const { return new gBGC(*this); }
 
-  ~gBGC()
-  {
-    if (pmodel_)
-      delete pmodel_;
-    pmodel_ = 0;
-  }
+    ~gBGC()  {}
 
-public:
-  std::string getName() const;
+  public:
+    std::string getName() const;
 
-  size_t getNumberOfStates() const { return pmodel_->getNumberOfStates(); }
+    size_t getNumberOfStates() const { return model_->getNumberOfStates(); }
 
-  void fireParameterChanged(const ParameterList&);
+    void fireParameterChanged(const ParameterList&);
 
-  void updateMatrices();
+    const SubstitutionModel* getNestedModel() const {return model_.get();}
+    
+    void updateMatrices();
 
-  void setNamespace(const std::string&);
-};
+    void setNamespace(const std::string&);
+  };
 }
 
 #endif // _GBGC_H
diff --git a/src/Bpp/Phyl/Model/Protein/Coala.cpp b/src/Bpp/Phyl/Model/Protein/Coala.cpp
index a44b77b..4c85536 100644
--- a/src/Bpp/Phyl/Model/Protein/Coala.cpp
+++ b/src/Bpp/Phyl/Model/Protein/Coala.cpp
@@ -1,223 +1,189 @@
-//
-// File: Coala.cpp
-// Created by: Mathieu Groussin
-// Created on: Sun Mar 13 12:00:00 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 "Coala.h"
-
-#include <Bpp/Io/FileTools.h>
-#include <Bpp/Text/TextTools.h>
-#include <Bpp/Text/StringTokenizer.h>
-#include <Bpp/App/ApplicationTools.h>
-#include <Bpp/Numeric/VectorTools.h>
-#include <Bpp/Numeric/Matrix/MatrixTools.h>
-#include <Bpp/Numeric/Stat/Mva/CorrespondenceAnalysis.h>
-
-#include <Bpp/Seq/SequenceTools.h>
-
-using namespace bpp;
-
-// From the STL:
-#include <iostream>
-#include <fstream>
-#include <string>
-
-using namespace std;
-
-
-/******************************************************************************/
-
-Coala::Coala(
-  const ProteicAlphabet* alpha,
-  unsigned int nbAxes,
-  string exch,
-  string file) :
-  AbstractParameterAliasable("Coala."),
-  AbstractSubstitutionModel(alpha, "Coala."),
-  ProteinSubstitutionModel(),
-  AbstractReversibleSubstitutionModel(alpha, "Coala."),
-  CoalaCore(nbAxes, exch),
-  init_(true),
-  nbrOfAxes_(nbAxes),
-  exch_(exch),
-  file_(file)
-{
-  setNamespace(getName() + ".");
-
-  // Setting the exchangeability matrix
-  if (exch == "JC69")
-  {
-    for (unsigned int i = 0; i < 20; i++)
-    {
-      for (unsigned int j = 0; j < 20; j++)
-      {
-        generator_(i, j) = (i == j) ? -1. : 1. / 19.;
-        exchangeability_(i, j) = generator_(i, j) * 20.;
-      }
-    }
-  }
-  else if (exch == "DSO78")
-  {
-#include "__DSO78ExchangeabilityCode"
-  }
-  else if (exch == "JTT92")
-  {
-#include "__JTT92ExchangeabilityCode"
-  }
-  else if (exch == "WAG01")
-  {
-#include "__WAG01ExchangeabilityCode"
-  }
-  else if (exch == "LG08")
-  {
-#include "__LG08ExchangeabilityCode"
-  }
-  else if (exch == "Empirical")
-  {
-    readFromFile(file_);
-  }
-  else
-  {
-    throw Exception("Model '" + exch + "' unknown.");
-  }
-  updateMatrices();
-}
-
-/******************************************************************************/
-
-void Coala::readFromFile(string& file)
-{
-  ifstream in(file.c_str(), ios::in);
-  // Read exchangeability matrix:
-  for (unsigned int i = 1; i < 20; i++)
-  {
-    string line = FileTools::getNextLine(in);
-    StringTokenizer st(line);
-    for (unsigned int j = 0; j < i; j++)
-    {
-      double s = TextTools::toDouble(st.nextToken());
-      exchangeability_(i, j) = exchangeability_(j, i) = s;
-    }
-  }
-
-  // Now build diagonal of the exchangeability matrix:
-  for (unsigned int i = 0; i < 20; i++)
-  {
-    double sum = 0;
-    for (unsigned int j = 0; j < 20; j++)
-    {
-      if (j != i)
-        sum += exchangeability_(i, j);
-    }
-    exchangeability_(i, i) = -sum;
-  }
-
-  // Closing stream:
-  in.close();
-}
-
-
-/******************************************************************************/
-void Coala::computeEquilibriumFrequencies()
-{
-  // Computes the equilibrium frequencies from a set of coordinates along the principal axes of the COA.
-  if (init_)
-    init_ = false;
-  else
-  {
-    // We get the coordinates:
-    vector<double> coord;
-    for (unsigned int i = 0; i < nbrOfAxes_; i++)
-    {
-      coord.push_back(getParameter("AxPos" + TextTools::toString(i)).getValue());
-    }
-
-    // Now, frequencies are computed from the vector of coordinates and the transpose of the principal axes matrix (P_):
-    vector<double> tmpFreqs;
-    tmpFreqs = prodMatrixVector(P_, coord);
-    for (unsigned int i = 0; i < tmpFreqs.size(); i++)
-    {
-      tmpFreqs[i] = (tmpFreqs[i] + 1) * colWeights_[i];
-    }
-    freq_ = tmpFreqs;
-
-    // Frequencies are not allowed to be lower than 10^-3 or higher than 0.5:
-    bool norm = false;
-    for (unsigned int i = 0; i < 20; i++)
-    {
-      if (freq_[i] < 0.001)
-      {
-        norm = true;
-        freq_[i] = 0.001;
-      }
-      if (freq_[i] > 0.2)
-      {
-        norm = true;
-        freq_[i] = 0.2;
-      }
-    }
-    if (norm == true)
-    {
-      double s = VectorTools::sum(freq_);
-      for (int i = 0; i < 20; i++)
-      {
-        freq_[i] = freq_[i] / s;
-      }
-    }
-  }
-}
-
-/******************************************************************************/
-
-void Coala::updateMatrices()
-{
-  computeEquilibriumFrequencies();
-  AbstractReversibleSubstitutionModel::updateMatrices();
-}
-
-/******************************************************************************/
-
-void Coala::setFreqFromData(const SequenceContainer& data, bool param)
-{
-  // Compute the COA from the observed frequencies, add the axis position parameters and update the Markov matrix
-  ParameterList pList = computeCOA(data, param);
-  addParameters_(pList);
-  updateMatrices();
-}
-
-/******************************************************************************/
+//
+// File: Coala.cpp
+// Created by: Mathieu Groussin
+// Created on: Sun Mar 13 12:00:00 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 "Coala.h"
+
+#include <Bpp/Io/FileTools.h>
+#include <Bpp/Text/TextTools.h>
+#include <Bpp/Text/StringTokenizer.h>
+#include <Bpp/App/ApplicationTools.h>
+#include <Bpp/Numeric/VectorTools.h>
+#include <Bpp/Numeric/Matrix/MatrixTools.h>
+#include <Bpp/Numeric/Stat/Mva/CorrespondenceAnalysis.h>
+
+#include <Bpp/Seq/SequenceTools.h>
+
+using namespace bpp;
+
+// From the STL:
+#include <iostream>
+#include <fstream>
+#include <string>
+
+using namespace std;
+
+
+/******************************************************************************/
+
+Coala::Coala(
+  const ProteicAlphabet* alpha,
+  const ProteinSubstitutionModel& model,  
+  unsigned int nbAxes,
+  bool param) :
+  AbstractParameterAliasable("Coala."),
+  ProteinSubstitutionModel(),
+  AbstractReversibleSubstitutionModel(alpha, new CanonicalStateMap(alpha, false), "Coala."),
+  CoalaCore(nbAxes, model.getName()),
+  init_(true),
+  nbrOfAxes_(nbAxes),
+  exch_(model.getName()),
+  file_(),
+  param_(param)
+{
+  setNamespace(getName() + ".");
+
+  // Setting the exchangeability matrix
+  exchangeability_ = model.getExchangeabilityMatrix();
+  updateMatrices();
+}
+
+/******************************************************************************/
+
+void Coala::readFromFile(string& file)
+{
+  ifstream in(file.c_str(), ios::in);
+  // Read exchangeability matrix:
+  for (unsigned int i = 1; i < 20; i++)
+  {
+    string line = FileTools::getNextLine(in);
+    StringTokenizer st(line);
+    for (unsigned int j = 0; j < i; j++)
+    {
+      double s = TextTools::toDouble(st.nextToken());
+      exchangeability_(i, j) = exchangeability_(j, i) = s;
+    }
+  }
+
+  // Now build diagonal of the exchangeability matrix:
+  for (unsigned int i = 0; i < 20; i++)
+  {
+    double sum = 0;
+    for (unsigned int j = 0; j < 20; j++)
+    {
+      if (j != i)
+        sum += exchangeability_(i, j);
+    }
+    exchangeability_(i, i) = -sum;
+  }
+
+  // Closing stream:
+  in.close();
+}
+
+
+/******************************************************************************/
+void Coala::computeEquilibriumFrequencies()
+{
+  // Computes the equilibrium frequencies from a set of coordinates along the principal axes of the COA.
+  if (init_)
+    init_ = false;
+  else
+  {
+    // We get the coordinates:
+    vector<double> coord;
+    for (unsigned int i = 0; i < nbrOfAxes_; i++)
+    {
+      coord.push_back(getParameter("AxPos" + TextTools::toString(i)).getValue());
+    }
+
+    // Now, frequencies are computed from the vector of coordinates and the transpose of the principal axes matrix (P_):
+    vector<double> tmpFreqs;
+    tmpFreqs = prodMatrixVector(P_, coord);
+    for (unsigned int i = 0; i < tmpFreqs.size(); i++)
+    {
+      tmpFreqs[i] = (tmpFreqs[i] + 1) * colWeights_[i];
+    }
+    freq_ = tmpFreqs;
+
+    // Frequencies are not allowed to be lower than 10^-3 or higher than 0.5:
+    bool norm = false;
+    for (unsigned int i = 0; i < 20; i++)
+    {
+      if (freq_[i] < 0.001)
+      {
+        norm = true;
+        freq_[i] = 0.001;
+      }
+      if (freq_[i] > 0.2)
+      {
+        norm = true;
+        freq_[i] = 0.2;
+      }
+    }
+    if (norm == true)
+    {
+      double s = VectorTools::sum(freq_);
+      for (size_t i = 0; i < 20; i++)
+      {
+        freq_[i] = freq_[i] / s;
+      }
+    }
+  }
+}
+
+/******************************************************************************/
+
+void Coala::updateMatrices()
+{
+  computeEquilibriumFrequencies();
+  AbstractReversibleSubstitutionModel::updateMatrices();
+}
+
+/******************************************************************************/
+
+void Coala::setFreqFromData(const SequenceContainer& data, double pseudoCount)
+{
+  // Compute the COA from the observed frequencies, add the axis position parameters and update the Markov matrix
+  ParameterList pList = computeCOA(data, param_);
+  addParameters_(pList);
+  updateMatrices();
+}
+
+/******************************************************************************/
diff --git a/src/Bpp/Phyl/Model/Protein/Coala.h b/src/Bpp/Phyl/Model/Protein/Coala.h
index 4ed61d7..06b722f 100644
--- a/src/Bpp/Phyl/Model/Protein/Coala.h
+++ b/src/Bpp/Phyl/Model/Protein/Coala.h
@@ -1,113 +1,111 @@
-//
-// File: Coala.h
-// Created by: Bastien Boussau
-// Created on: Tue May 18 15:23:20 2010
-// Modified by: Mathieu Groussin
-// Modified on: Sun Mar 13 12:00:00 2011
-//
-
-/*
-   Copyright or � or Copr. CNRS, (November 16, 2004)
-   PCA
-   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 _COALA_H_
-#define _COALA_H_
-
-#include "ProteinSubstitutionModel.h"
-#include "../AbstractSubstitutionModel.h"
-#include "CoalaCore.h"
-
-// From SeqLib:
-#include <Bpp/Seq/Alphabet/ProteicAlphabet.h>
-
-using namespace std;
-
-
-namespace bpp
-{
-/**
- * @brief The Coala branch-heterogeneous amino-acid substitution model.
- *
- * This branch-heterogeneous model allows each branch to have its own set of amino acid equilibrium frequencies. It makes use of a Correspondence Analysis to reduce the number of parameters to be
- * optimized through Maximum Likelihood, focusing on most of the compositional variation observed in the data. The same COA is used for all branches.
- * An empirical exchangeability matrix is used, common to all branches. The choice of this matrix is up to the user. A user-defined empirical matrix can also be employed.
- * The model may also be used as a branch-homogeneous but non-stationary model, where the same estimated equilibrium frequencies are used for all branches, but different equilibrium frequencies
- * (that are optimized) are used on the root. Finally, the model may be employed as a branch-homogeneous and stationary model, where the frequencies at the root are similar to the ones on branches.
- *
- * @author Mathieu Groussin
- * @param alpha The alphabet (Protein)
- * @param nbAxes The number of principal axes of the COA that have to be taken into account to optimize the 20 branch-specific equilibrium frequencies. This number is common to all branches, as
- * well as on the root, where frequencies are optimized with a MVAprotein object (See the ProteinFrequenciesSet class).
- * @param exch The exchangeability matrix. The matrices currently available are DSO78, JTT92, WAG01 or LG08. A user-defined matrix can be specified with the 'file' argument.
- * @param file [optional] Used only to specify the file containing the user-defined exchangeabilities, written in PAML format.
- */
-
-class Coala :
-  public ProteinSubstitutionModel,
-  public AbstractReversibleSubstitutionModel,
-  public CoalaCore
-{
-protected:
-  bool init_;
-  unsigned int nbrOfAxes_;
-  string exch_;
-  string file_;
-
-public:
-  Coala(const ProteicAlphabet* alpha,
-        unsigned int nbAxes = 0,
-        const string exch = "LG08",
-        string file = "");
-
-  virtual ~Coala() {}
-
-#ifndef NO_VIRTUAL_COV
-  Coala*
-#else
-  Clonable*
-#endif
-  clone() const { return new Coala(*this); }
-
-public:
-  string getName() const {return "Coala"; }
-  string getExch() const {return exch_; }
-  void setFreqFromData(const SequenceContainer& data, bool param = true);
-  string getEmpiricalMatrixFile() const {return file_; }
-
-protected:
-  void readFromFile(string& file);
-  void computeEquilibriumFrequencies();
-  void updateMatrices();
-};
-} // end of namespace bpp.
-#endif  // _COALA_H_
+//
+// File: Coala.h
+// Created by: Bastien Boussau
+// Created on: Tue May 18 15:23:20 2010
+// Modified by: Mathieu Groussin
+// Modified on: Sun Mar 13 12:00:00 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.
+ */
+
+
+#ifndef _COALA_H_
+#define _COALA_H_
+
+#include "ProteinSubstitutionModel.h"
+#include "../AbstractSubstitutionModel.h"
+#include "CoalaCore.h"
+
+// From bpp-seq:
+#include <Bpp/Seq/Alphabet/ProteicAlphabet.h>
+
+namespace bpp
+{
+/**
+ * @brief The Coala branch-heterogeneous amino-acid substitution model.
+ *
+ * This branch-heterogeneous model allows each branch to have its own set of amino acid equilibrium frequencies. It makes use of a Correspondence Analysis to reduce the number of parameters to be
+ * optimized through Maximum Likelihood, focusing on most of the compositional variation observed in the data. The same COA is used for all branches.
+ * An empirical exchangeability matrix is used, common to all branches. The choice of this matrix is up to the user. A user-defined empirical matrix can also be employed.
+ * The model may also be used as a branch-homogeneous but non-stationary model, where the same estimated equilibrium frequencies are used for all branches, but different equilibrium frequencies
+ * (that are optimized) are used on the root. Finally, the model may be employed as a branch-homogeneous and stationary model, where the frequencies at the root are similar to the ones on branches.
+ *
+ * @author Mathieu Groussin
+ * @param alpha The alphabet (Protein)
+ * @param nbAxes The number of principal axes of the COA that have to be taken into account to optimize the 20 branch-specific equilibrium frequencies. This number is common to all branches, as
+ * well as on the root, where frequencies are optimized with a MVAprotein object (See the ProteinFrequenciesSet class).
+ * @param exch The exchangeability matrix. The matrices currently available are DSO78, JTT92, WAG01 or LG08. A user-defined matrix can be specified with the 'file' argument.
+ * @param file [optional] Used only to specify the file containing the user-defined exchangeabilities, written in PAML format.
+ */
+
+class Coala :
+  public ProteinSubstitutionModel,
+  public AbstractReversibleSubstitutionModel,
+  public CoalaCore
+{
+protected:
+  bool init_;
+  unsigned int nbrOfAxes_;
+  std::string exch_;
+  std::string file_;
+  bool param_;
+
+public:
+  Coala(const ProteicAlphabet* alpha,
+        const ProteinSubstitutionModel& model,
+        unsigned int nbAxes = 0,
+        bool param = true);
+
+  virtual ~Coala() {}
+
+#ifndef NO_VIRTUAL_COV
+  Coala*
+#else
+  Clonable*
+#endif
+  clone() const { return new Coala(*this); }
+
+public:
+  std::string getName() const {return "Coala"; }
+  std::string getExch() const {return exch_; }
+  void setFreqFromData(const SequenceContainer& data, double pseudoCount = 0);
+  std::string getEmpiricalMatrixFile() const { return file_; }
+
+protected:
+  void readFromFile(std::string& file);
+  void computeEquilibriumFrequencies();
+  void updateMatrices();
+};
+} // end of namespace bpp.
+#endif  // _COALA_H_
diff --git a/src/Bpp/Phyl/Model/Protein/CoalaCore.cpp b/src/Bpp/Phyl/Model/Protein/CoalaCore.cpp
index dd06dff..3c08904 100644
--- a/src/Bpp/Phyl/Model/Protein/CoalaCore.cpp
+++ b/src/Bpp/Phyl/Model/Protein/CoalaCore.cpp
@@ -82,18 +82,18 @@ ParameterList CoalaCore::computeCOA(const SequenceContainer& data, bool param)
   vector<string> names = data.getSequencesNames();
   vector< map<int, double> > freqs(names.size()); // One map per sequence
   // Each map is filled with the corresponding frequencies, which are then normalized.
-  for (size_t i = 0; i < names.size(); i++)
+  for (size_t i = 0; i < names.size(); ++i)
   {
     Sequence* seq = new BasicSequence(data.getSequence(names[i]));
     SymbolListTools::changeGapsToUnknownCharacters(*seq);
     SequenceTools::getFrequencies(*seq, freqs.at(i));
     // Unknown characters are now ignored:
     double t = 0;
-    for (unsigned int k = 0; k < 20; k++)
+    for (int k = 0; k < 20; ++k)
     {
       t += freqs.at(i)[k];
     }
-    for (unsigned int k = 0; k < 20; k++)
+    for (int k = 0; k < 20; k++)
     {
       freqs.at(i)[k] /= t;
     }
@@ -105,11 +105,11 @@ ParameterList CoalaCore::computeCOA(const SequenceContainer& data, bool param)
   for (size_t i = 0; i < freqs.size(); i++)
   {
     bool normalize = false;
-    for (int j = 0; j < 20; j++)
+    for (size_t j = 0; j < 20; j++)
     {
-      if (freqs[i].find(j) != freqs[i].end())
+      map<int, double>::iterator it = freqs[i].find(static_cast<int>(j));
+      if (it != freqs[i].end())
       {
-        map<int, double>::iterator it = freqs[i].find(j);
         freqMatrix(i, j) = (*it).second;
       }
       else
@@ -121,11 +121,11 @@ ParameterList CoalaCore::computeCOA(const SequenceContainer& data, bool param)
     if (normalize)
     {
       double sum = 0;
-      for (unsigned int k = 0; k < 20; k++)
+      for (size_t k = 0; k < 20; k++)
       {
         sum += freqMatrix(i, k);
       }
-      for (unsigned int l = 0; l < 20; l++)
+      for (size_t l = 0; l < 20; l++)
       {
         freqMatrix(i, l) = freqMatrix(i, l) / sum;
       }
@@ -162,9 +162,9 @@ ParameterList CoalaCore::computeCOA(const SequenceContainer& data, bool param)
       double sd = VectorTools::sd<double, double>(rCoords);
       IntervalConstraint* constraint = new IntervalConstraint(minCoord - sd, maxCoord + sd, true, true);
       if (paramValues_.find("AxPos" + TextTools::toString(i)) != paramValues_.end())
-        pList.addParameter(Parameter("COaLA.AxPos" + TextTools::toString(i), TextTools::toDouble(paramValues_["AxPos" + TextTools::toString(i)].substr(0, 8)), constraint));
+        pList.addParameter(Parameter("Coala.AxPos" + TextTools::toString(i), TextTools::toDouble(paramValues_["AxPos" + TextTools::toString(i)].substr(0, 8)), constraint));
       else
-        pList.addParameter(Parameter("COaLA.AxPos" + TextTools::toString(i), 0., constraint));
+        pList.addParameter(Parameter("Coala.AxPos" + TextTools::toString(i), 0., constraint));
     }
   }
   return pList;
diff --git a/src/Bpp/Phyl/Model/Protein/CoalaCore.h b/src/Bpp/Phyl/Model/Protein/CoalaCore.h
index c573660..98c7308 100644
--- a/src/Bpp/Phyl/Model/Protein/CoalaCore.h
+++ b/src/Bpp/Phyl/Model/Protein/CoalaCore.h
@@ -50,8 +50,6 @@
 #include <Bpp/Seq/Container/SequenceContainer.h>
 
 
-using namespace std;
-
 namespace bpp
 {
 /**
@@ -65,20 +63,19 @@ namespace bpp
  * well as on the root, where frequencies are optimized with a MVAprotein object (See the ProteinFrequenciesSet class).
  * @param exch The exchangeability matrix. The matrices currently available are DSO78, JTT92, WAG01 or LG08. A user-defined matrix can be specified with the 'file' argument.
  */
-
 class CoalaCore
 {
 protected:
   bool init_;
   size_t nbrOfAxes_;
-  string exch_;
+  std::string exch_;
   RowMatrix<double> P_;
   RowMatrix<double> R_;
-  vector<double> colWeights_;
-  map<string, string> paramValues_;
+  std::vector<double> colWeights_;
+  std::map<std::string, std::string> paramValues_;
 
 public:
-  CoalaCore(size_t nbAxes = 0, const string& exch = "LG08");
+  CoalaCore(size_t nbAxes = 0, const std::string& exch = "LG08");
 
   virtual ~CoalaCore() {}
 
@@ -88,13 +85,13 @@ public:
   size_t getNbrOfAxes() const { return nbrOfAxes_; }
   const RowMatrix<double>& getTppalAxesMatrix() const { return P_; }
   const RowMatrix<double>& getRowCoordinates() const { return R_; }
-  const vector<double>& getColumnWeights() const { return colWeights_; }
-  void setParamValues(const map<string, string>& valuesSettings) { paramValues_ = valuesSettings; }
+  const std::vector<double>& getColumnWeights() const { return colWeights_; }
+  void setParamValues(const std::map<std::string, std::string>& valuesSettings) { paramValues_ = valuesSettings; }
 
 protected:
   ParameterList computeCOA(const SequenceContainer& data, bool param = true);
   
-  vector<double> prodMatrixVector(RowMatrix<double>& P, vector<double>& V);
+  std::vector<double> prodMatrixVector(RowMatrix<double>& P, std::vector<double>& V);
 };
 
 } // end of namespace bpp.
diff --git a/src/Bpp/Phyl/Model/Protein/DSO78.cpp b/src/Bpp/Phyl/Model/Protein/DSO78.cpp
index 9cbb0d8..94678ab 100755
--- a/src/Bpp/Phyl/Model/Protein/DSO78.cpp
+++ b/src/Bpp/Phyl/Model/Protein/DSO78.cpp
@@ -39,17 +39,20 @@ knowledge of the CeCILL license and that you accept its terms.
 
 #include "DSO78.h"
 
-//From SeqLib:
+//From bpp-seq:
 #include <Bpp/Seq/Container/SequenceContainerTools.h>
 
 using namespace bpp;
 
+#include <map>
+
+using namespace std;
+
 /******************************************************************************/
 
 DSO78::DSO78(const ProteicAlphabet* alpha) :
   AbstractParameterAliasable("DSO78."),
-  AbstractSubstitutionModel(alpha, "DSO78."),
-  AbstractReversibleSubstitutionModel(alpha, "DSO78."),
+  AbstractReversibleSubstitutionModel(alpha, new CanonicalStateMap(alpha, false), "DSO78."),
   freqSet_(0)
 {
   #include "__DSO78ExchangeabilityCode"
@@ -60,28 +63,30 @@ DSO78::DSO78(const ProteicAlphabet* alpha) :
 
 DSO78::DSO78(const ProteicAlphabet* alpha, ProteinFrequenciesSet* freqSet, bool initFreqs) :
   AbstractParameterAliasable("DSO78+F."),
-  AbstractSubstitutionModel(alpha, "DSO78+F."),
-  AbstractReversibleSubstitutionModel(alpha, "DSO78+F."),
+  AbstractReversibleSubstitutionModel(alpha, new CanonicalStateMap(alpha, false), "DSO78+F."),
   freqSet_(freqSet)
 {
   #include "__DSO78ExchangeabilityCode"
   #include "__DSO78FrequenciesCode"
+  freqSet_->setNamespace("DSO78+F."+freqSet_->getNamespace());
   if (initFreqs) freqSet_->setFrequencies(freq_);
   else freq_ = freqSet_->getFrequencies();
-  freqSet_->setNamespace("DSO78+F."+freqSet_->getNamespace());
   addParameters_(freqSet_->getParameters());
   updateMatrices();  
 }
 
 /******************************************************************************/
 
-void DSO78::setFreqFromData(const SequenceContainer& data)
+void DSO78::setFreqFromData(const SequenceContainer& data, double pseudoCount)
 {
-  std::map<int, double> freqs;
-  SequenceContainerTools::getFrequencies(data, freqs);
+  map<int, int> counts;
+  SequenceContainerTools::getCounts(data, counts);
   double t = 0;
-  for (size_t i = 0; i < size_; i++) t += freqs[static_cast<int>(i)];
-  for (size_t i = 0; i < size_; i++) freq_[i] = freqs[static_cast<int>(i)] / t;
+  for (int i = 0; i < static_cast<int>(size_); i++)
+  {
+    t += (counts[i] + pseudoCount);
+  }
+  for (size_t i = 0; i < size_; ++i) freq_[i] = (static_cast<double>(counts[static_cast<int>(i)]) + pseudoCount) / t;
   freqSet_->setFrequencies(freq_);
   //Update parameters and re-compute generator and eigen values:
   matchParametersValues(freqSet_->getParameters());
diff --git a/src/Bpp/Phyl/Model/Protein/DSO78.h b/src/Bpp/Phyl/Model/Protein/DSO78.h
index 8d26bd6..229a6b9 100755
--- a/src/Bpp/Phyl/Model/Protein/DSO78.h
+++ b/src/Bpp/Phyl/Model/Protein/DSO78.h
@@ -5,7 +5,7 @@
 //
 
 /*
-  Copyright or © or Copr. CNRS, (November 16, 2004)
+  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.
@@ -90,7 +90,7 @@ namespace bpp
 
     DSO78(const DSO78& model) :
       AbstractParameterAliasable(model),
-      AbstractSubstitutionModel(model),
+      //AbstractSubstitutionModel(model),
       AbstractReversibleSubstitutionModel(model),
       freqSet_(dynamic_cast<ProteinFrequenciesSet *>(model.freqSet_->clone()))
     {}
@@ -140,7 +140,7 @@ namespace bpp
 
     const FrequenciesSet* getFrequenciesSet() const { return freqSet_; }
 
-    void setFreqFromData(const SequenceContainer& data);
+    void setFreqFromData(const SequenceContainer& data, double pseudoCount = 0);
 
   };
 
diff --git a/src/Bpp/Phyl/Model/Protein/JCprot.cpp b/src/Bpp/Phyl/Model/Protein/JCprot.cpp
index 5c25c2f..45ab877 100755
--- a/src/Bpp/Phyl/Model/Protein/JCprot.cpp
+++ b/src/Bpp/Phyl/Model/Protein/JCprot.cpp
@@ -39,12 +39,13 @@ knowledge of the CeCILL license and that you accept its terms.
 
 #include "JCprot.h"
 
-//From SeqLib:
+//From bpp-seq:
 #include <Bpp/Seq/Container/SequenceContainerTools.h>
 
 using namespace bpp;
 
 #include <cmath>
+#include <map>
 
 using namespace std;
 
@@ -52,8 +53,7 @@ using namespace std;
 
 JCprot::JCprot(const ProteicAlphabet* alpha) :
   AbstractParameterAliasable("JC69."),
-  AbstractSubstitutionModel(alpha, "JC69."),
-  AbstractReversibleSubstitutionModel(alpha, "JC69."),
+  AbstractReversibleSubstitutionModel(alpha, new CanonicalStateMap(alpha, false), "JC69."),
   exp_(), p_(size_, size_), freqSet_(0)
 {
   freqSet_ = new FixedProteinFrequenciesSet(alpha, freq_);
@@ -62,13 +62,12 @@ JCprot::JCprot(const ProteicAlphabet* alpha) :
 
 JCprot::JCprot(const ProteicAlphabet* alpha, ProteinFrequenciesSet* freqSet, bool initFreqs) :
   AbstractParameterAliasable("JC69+F."),
-  AbstractSubstitutionModel(alpha, "JC69+F."),
-  AbstractReversibleSubstitutionModel(alpha, "JC69+F."),
+  AbstractReversibleSubstitutionModel(alpha, new CanonicalStateMap(alpha, false), "JC69+F."),
   exp_(), p_(size_, size_), freqSet_(freqSet)
 {
+  freqSet_->setNamespace("JC69+F."+freqSet_->getNamespace());
   if (initFreqs) freqSet_->setFrequencies(freq_);
   else freq_ = freqSet_->getFrequencies();
-  freqSet_->setNamespace("JC69+F."+freqSet_->getNamespace());
   addParameters_(freqSet_->getParameters());
   updateMatrices();  
 }
@@ -113,7 +112,7 @@ void JCprot::updateMatrices()
 	
 /******************************************************************************/
 
-double JCprot::Pij_t(int i, int j, double d) const
+double JCprot::Pij_t(size_t i, size_t j, double d) const
 {
   if(i == j) return 1./20. + 19./20. * exp(-  rate_ * 20./19. * d);
   else       return 1./20. -  1./20. * exp(-  rate_ * 20./19. * d);
@@ -121,7 +120,7 @@ double JCprot::Pij_t(int i, int j, double d) const
 
 /******************************************************************************/
 
-double JCprot::dPij_dt(int i, int j, double d) const
+double JCprot::dPij_dt(size_t i, size_t j, double d) const
 {
   if(i == j) return -  rate_ *        exp(-  rate_ * 20./19. * d);
   else       return  rate_ * 1./19. * exp(-  rate_ * 20./19. * d);
@@ -129,7 +128,7 @@ double JCprot::dPij_dt(int i, int j, double d) const
 
 /******************************************************************************/
 
-double JCprot::d2Pij_dt2(int i, int j, double d) const
+double JCprot::d2Pij_dt2(size_t i, size_t j, double d) const
 {
   if(i == j) return    rate_ *  rate_ * 20./19.  * exp(-  rate_ * 20./19. * d);
   else       return -  rate_ *  rate_ * 20./361. * exp(-  rate_ * 20./19. * d);
@@ -178,13 +177,16 @@ const Matrix<double>& JCprot::getd2Pij_dt2(double d) const
 
 /******************************************************************************/
 
-void JCprot::setFreqFromData(const SequenceContainer& data)
+void JCprot::setFreqFromData(const SequenceContainer& data, double pseudoCount)
 {
-  std::map<int, double> freqs;
-  SequenceContainerTools::getFrequencies(data, freqs);
+  map<int, int> counts;
+  SequenceContainerTools::getCounts(data, counts);
   double t = 0;
-  for (unsigned int i = 0; i < size_; i++) t += freqs[i];
-  for (unsigned int i = 0; i < size_; i++) freq_[i] = freqs[i] / t;
+  for (int i = 0; i < static_cast<int>(size_); i++)
+  {
+    t += (counts[i] + pseudoCount);
+  }
+  for (size_t i = 0; i < size_; ++i) freq_[i] = (static_cast<double>(counts[static_cast<int>(i)]) + pseudoCount) / t;
   freqSet_->setFrequencies(freq_);
   //Update parameters and re-compute generator and eigen values:
   matchParametersValues(freqSet_->getParameters());
diff --git a/src/Bpp/Phyl/Model/Protein/JCprot.h b/src/Bpp/Phyl/Model/Protein/JCprot.h
index 05967f9..aeb45cf 100755
--- a/src/Bpp/Phyl/Model/Protein/JCprot.h
+++ b/src/Bpp/Phyl/Model/Protein/JCprot.h
@@ -5,7 +5,7 @@
 //
 
 /*
-  Copyright or © or Copr. CNRS, (November 16, 2004)
+  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.
@@ -160,7 +160,7 @@ namespace bpp
 
     JCprot(const JCprot& model) :
       AbstractParameterAliasable(model),
-      AbstractSubstitutionModel(model),
+      //AbstractSubstitutionModel(model),
       AbstractReversibleSubstitutionModel(model),
       exp_(model.exp_),
       p_(model.p_),
@@ -189,9 +189,9 @@ namespace bpp
     clone() const { return new JCprot(*this); }
 
   public:
-    double Pij_t    (int i, int j, double d) const;
-    double dPij_dt  (int i, int j, double d) const;
-    double d2Pij_dt2(int i, int j, double d) const;
+    double Pij_t    (size_t i, size_t j, double d) const;
+    double dPij_dt  (size_t i, size_t j, double d) const;
+    double d2Pij_dt2(size_t i, size_t j, double d) const;
     const Matrix<double>& getPij_t    (double d) const;
     const Matrix<double>& getdPij_dt  (double d) const;
     const Matrix<double>& getd2Pij_dt2(double d) const;
@@ -221,7 +221,7 @@ namespace bpp
 
     const FrequenciesSet* getFrequenciesSet() const { return freqSet_; }
 
-    void setFreqFromData(const SequenceContainer& data);
+    void setFreqFromData(const SequenceContainer& data, double pseudoCount = 0);
 
   protected:
     /**
diff --git a/src/Bpp/Phyl/Model/Protein/JTT92.cpp b/src/Bpp/Phyl/Model/Protein/JTT92.cpp
index 8513689..a2ab2a5 100755
--- a/src/Bpp/Phyl/Model/Protein/JTT92.cpp
+++ b/src/Bpp/Phyl/Model/Protein/JTT92.cpp
@@ -39,18 +39,20 @@ knowledge of the CeCILL license and that you accept its terms.
 
 #include "JTT92.h"
 
-//From SeqLib:
+//From bpp-seq:
 #include <Bpp/Seq/Container/SequenceContainerTools.h>
 
 using namespace bpp;
+
+#include <map>
+
 using namespace std;
 
 /******************************************************************************/
 
 JTT92::JTT92(const ProteicAlphabet* alpha) :
   AbstractParameterAliasable("JTT92."),
-  AbstractSubstitutionModel(alpha, "JTT92."),
-  AbstractReversibleSubstitutionModel(alpha, "JTT92."),
+  AbstractReversibleSubstitutionModel(alpha, new CanonicalStateMap(alpha, false), "JTT92."),
   freqSet_(0)
 {
   #include "__JTT92ExchangeabilityCode"
@@ -61,28 +63,30 @@ JTT92::JTT92(const ProteicAlphabet* alpha) :
 
 JTT92::JTT92(const ProteicAlphabet* alpha, ProteinFrequenciesSet* freqSet, bool initFreqs) :
   AbstractParameterAliasable("JTT92+F."),
-  AbstractSubstitutionModel(alpha, "JTT92+F."),
-  AbstractReversibleSubstitutionModel(alpha, "JTT92+F."),
+  AbstractReversibleSubstitutionModel(alpha, new CanonicalStateMap(alpha, false), "JTT92+F."),
   freqSet_(freqSet)
 {
   #include "__JTT92ExchangeabilityCode"
   #include "__JTT92FrequenciesCode"
+  freqSet_->setNamespace("JTT92+F."+freqSet_->getNamespace());
   if (initFreqs) freqSet_->setFrequencies(freq_);
   else freq_ = freqSet_->getFrequencies();
-  freqSet_->setNamespace("JTT92+F."+freqSet_->getNamespace());
   addParameters_(freqSet_->getParameters());
   updateMatrices();  
 }
 
 /******************************************************************************/
 
-void JTT92::setFreqFromData(const SequenceContainer& data)
+void JTT92::setFreqFromData(const SequenceContainer& data, double pseudoCount)
 {
-  std::map<int, double> freqs;
-  SequenceContainerTools::getFrequencies(data, freqs);
+  map<int, int> counts;
+  SequenceContainerTools::getCounts(data, counts);
   double t = 0;
-  for (unsigned int i = 0; i < size_; i++) t += freqs[i];
-  for (unsigned int i = 0; i < size_; i++) freq_[i] = freqs[i] / t;
+  for (int i = 0; i < static_cast<int>(size_); i++)
+  {
+    t += (counts[i] + pseudoCount);
+  }
+  for (size_t i = 0; i < size_; ++i) freq_[i] = (static_cast<double>(counts[static_cast<int>(i)]) + pseudoCount) / t;
   freqSet_->setFrequencies(freq_);
   //Update parameters and re-compute generator and eigen values:
   matchParametersValues(freqSet_->getParameters());
diff --git a/src/Bpp/Phyl/Model/Protein/JTT92.h b/src/Bpp/Phyl/Model/Protein/JTT92.h
index 545757f..a673f81 100755
--- a/src/Bpp/Phyl/Model/Protein/JTT92.h
+++ b/src/Bpp/Phyl/Model/Protein/JTT92.h
@@ -44,7 +44,7 @@ knowledge of the CeCILL license and that you accept its terms.
 #include "../AbstractSubstitutionModel.h"
 #include "../FrequenciesSet/ProteinFrequenciesSet.h"
 
-// From SeqLib:
+// From bpp-seq:
 #include <Bpp/Seq/Alphabet/ProteicAlphabet.h>
 
 namespace bpp
@@ -90,7 +90,7 @@ class JTT92 :
 
     JTT92(const JTT92& model) :
       AbstractParameterAliasable(model),
-      AbstractSubstitutionModel(model),
+      //AbstractSubstitutionModel(model),
       AbstractReversibleSubstitutionModel(model),
       freqSet_(dynamic_cast<ProteinFrequenciesSet *>(model.freqSet_->clone()))
     {}
@@ -140,7 +140,7 @@ class JTT92 :
 
     const FrequenciesSet* getFrequenciesSet() const { return freqSet_; }
 
-    void setFreqFromData(const SequenceContainer& data);
+    void setFreqFromData(const SequenceContainer& data, double pseudoCount = 0);
 
 };
 
diff --git a/src/Bpp/Phyl/Model/Protein/LG08.cpp b/src/Bpp/Phyl/Model/Protein/LG08.cpp
index 7e01925..a27602c 100644
--- a/src/Bpp/Phyl/Model/Protein/LG08.cpp
+++ b/src/Bpp/Phyl/Model/Protein/LG08.cpp
@@ -39,18 +39,20 @@ knowledge of the CeCILL license and that you accept its terms.
 
 #include "LG08.h"
 
-//From SeqLib:
+//From bpp-seq:
 #include <Bpp/Seq/Container/SequenceContainerTools.h>
 
 using namespace bpp;
+
+#include <map>
+
 using namespace std;
 
 /******************************************************************************/
 
 LG08::LG08(const ProteicAlphabet* alpha) :
   AbstractParameterAliasable("LG08."),
-  AbstractSubstitutionModel(alpha, "LG08."),
-  AbstractReversibleSubstitutionModel(alpha, "LG08."),
+  AbstractReversibleSubstitutionModel(alpha, new CanonicalStateMap(alpha, false), "LG08."),
   freqSet_(0)
 {
   #include "__LG08ExchangeabilityCode"
@@ -61,28 +63,30 @@ LG08::LG08(const ProteicAlphabet* alpha) :
 
 LG08::LG08(const ProteicAlphabet* alpha, ProteinFrequenciesSet* freqSet, bool initFreqs) :
   AbstractParameterAliasable("LG08+F."),
-  AbstractSubstitutionModel(alpha, "LG08+F."),
-  AbstractReversibleSubstitutionModel(alpha, "LG08+F."),
+  AbstractReversibleSubstitutionModel(alpha, new CanonicalStateMap(alpha, false), "LG08+F."),
   freqSet_(freqSet)
 {
   #include "__LG08ExchangeabilityCode"
   #include "__LG08FrequenciesCode"
+  freqSet_->setNamespace("LG08+F."+freqSet_->getNamespace());
   if (initFreqs) freqSet_->setFrequencies(freq_);
   else freq_ = freqSet_->getFrequencies();
-  freqSet_->setNamespace("LG08+F."+freqSet_->getNamespace());
   addParameters_(freqSet_->getParameters());
   updateMatrices();  
 }
 
 /******************************************************************************/
 
-void LG08::setFreqFromData(const SequenceContainer& data)
+void LG08::setFreqFromData(const SequenceContainer& data, double pseudoCount)
 {
-  std::map<int, double> freqs;
-  SequenceContainerTools::getFrequencies(data, freqs);
+  map<int, int> counts;
+  SequenceContainerTools::getCounts(data, counts);
   double t = 0;
-  for (unsigned int i = 0; i < size_; i++) t += freqs[i];
-  for (unsigned int i = 0; i < size_; i++) freq_[i] = freqs[i] / t;
+  for (int i = 0; i < static_cast<int>(size_); i++)
+  {
+    t += (counts[i] + pseudoCount);
+  }
+  for (size_t i = 0; i < size_; ++i) freq_[i] = (static_cast<double>(counts[static_cast<int>(i)]) + pseudoCount) / t;
   freqSet_->setFrequencies(freq_);
   //Update parameters and re-compute generator and eigen values:
   matchParametersValues(freqSet_->getParameters());
diff --git a/src/Bpp/Phyl/Model/Protein/LG08.h b/src/Bpp/Phyl/Model/Protein/LG08.h
index 6708ade..bacad8b 100644
--- a/src/Bpp/Phyl/Model/Protein/LG08.h
+++ b/src/Bpp/Phyl/Model/Protein/LG08.h
@@ -88,7 +88,7 @@ namespace bpp
 
     LG08(const LG08& model) :
       AbstractParameterAliasable(model),
-      AbstractSubstitutionModel(model),
+      //AbstractSubstitutionModel(model),
       AbstractReversibleSubstitutionModel(model),
       freqSet_(dynamic_cast<ProteinFrequenciesSet*>(model.freqSet_->clone()))
     {}
@@ -138,7 +138,7 @@ namespace bpp
 
     const FrequenciesSet* getFrequenciesSet() const { return freqSet_; }
 
-    void setFreqFromData(const SequenceContainer& data);
+    void setFreqFromData(const SequenceContainer& data, double pseudoCount = 0);
 
   };
 
diff --git a/src/Bpp/Phyl/Model/Protein/LG10_EX_EHO.cpp b/src/Bpp/Phyl/Model/Protein/LG10_EX_EHO.cpp
new file mode 100644
index 0000000..bb3e2f4
--- /dev/null
+++ b/src/Bpp/Phyl/Model/Protein/LG10_EX_EHO.cpp
@@ -0,0 +1,119 @@
+//
+// File: LG10_EX_EHO.cpp
+// Created by:  Mathieu Groussin
+// Created on: jeudi 21 octobre 2010, à 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.
+ */
+
+#include "LG10_EX_EHO.h"
+#include "../FrequenciesSet/ProteinFrequenciesSet.h"
+
+#include <Bpp/Numeric/Prob/SimpleDiscreteDistribution.h>
+
+using namespace bpp;
+
+using namespace std;
+
+/******************************************************************************/
+
+LG10_EX_EHO::LG10_EX_EHO(const ProteicAlphabet* alpha) : 
+  AbstractBiblioMixedSubstitutionModel("LG10_EX_EHO."),
+  pmixmodel_(0)
+{
+  // build the submodel
+	
+  vector<SubstitutionModel*> vpSM;
+  vpSM.push_back(new LG10_EX_EHO::EmbeddedModel(alpha,"BUR_EXT"));
+  vpSM.push_back(new LG10_EX_EHO::EmbeddedModel(alpha,"BUR_HEL"));
+  vpSM.push_back(new LG10_EX_EHO::EmbeddedModel(alpha,"BUR_OTH"));
+  vpSM.push_back(new LG10_EX_EHO::EmbeddedModel(alpha,"EXP_EXT"));
+  vpSM.push_back(new LG10_EX_EHO::EmbeddedModel(alpha,"EXP_HEL"));
+  vpSM.push_back(new LG10_EX_EHO::EmbeddedModel(alpha,"EXP_OTH"));		
+
+  Vdouble vrate, vproba;
+	
+  for (unsigned int i=0;i<vpSM.size();i++)
+  {
+    vproba.push_back((dynamic_cast<LG10_EX_EHO::EmbeddedModel*> (vpSM[i]))->getProportion());
+    vrate.push_back(vpSM[i]->getRate());
+  }
+	
+  pmixmodel_.reset(new MixtureOfSubstitutionModels(alpha, vpSM, vproba, vrate));
+	
+  string name,st;
+  ParameterList pl=pmixmodel_->getParameters();
+  for (unsigned int i=0;i<pl.size();i++)
+  {
+    name=pl[i].getName();
+    lParPmodel_.addParameter(Parameter(pl[i]));
+    st=pmixmodel_->getParameterNameWithoutNamespace(name);
+    mapParNamesFromPmodel_[name]=st;
+    addParameter_(new Parameter("LG10_EX_EHO."+st,
+                            pmixmodel_->getParameterValue(st),
+                            pmixmodel_->getParameter(st).hasConstraint()? pmixmodel_->getParameter(st).getConstraint()->clone():0,true));
+  }
+	
+  updateMatrices();	
+}
+
+LG10_EX_EHO::LG10_EX_EHO(const LG10_EX_EHO& mod2) : AbstractBiblioMixedSubstitutionModel(mod2),
+pmixmodel_(new MixtureOfSubstitutionModels(*mod2.pmixmodel_))
+{}
+
+LG10_EX_EHO& LG10_EX_EHO::operator=(const LG10_EX_EHO& mod2)
+{
+  AbstractBiblioMixedSubstitutionModel::operator=(mod2);
+  
+  pmixmodel_.reset(new MixtureOfSubstitutionModels(*mod2.pmixmodel_));	
+	
+  return *this;
+}
+
+LG10_EX_EHO::~LG10_EX_EHO()
+{}
+
+/**************** sub model classes *///////////
+
+LG10_EX_EHO::EmbeddedModel::EmbeddedModel(const ProteicAlphabet* alpha, string name) :
+  AbstractParameterAliasable(name),
+  AbstractReversibleSubstitutionModel(alpha, new CanonicalStateMap(alpha, false), name), 
+  proportion_(1), 
+  name_(name)
+{
+#include "__LG10_EX_EHOExchangeabilityCode"
+#include "__LG10_EX_EHOFrequenciesCode"
+#include "__LG10_EX_EHORatesProps"
+  updateMatrices();
+}
+
diff --git a/src/Bpp/Phyl/Model/Protein/LG10_EX_EHO.h b/src/Bpp/Phyl/Model/Protein/LG10_EX_EHO.h
new file mode 100644
index 0000000..5d9526b
--- /dev/null
+++ b/src/Bpp/Phyl/Model/Protein/LG10_EX_EHO.h
@@ -0,0 +1,131 @@
+//
+// File: LG10_EX_EHO.h
+// Created by: Mathieu Groussin
+// Created on: Thursday 28 Mar 2013
+//
+
+/*
+ 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 _LG10_EX_EHO_H_
+#define _LG10_EX_EHO_H_
+
+#include "../MixtureOfSubstitutionModels.h"
+#include "ProteinSubstitutionModel.h"
+#include "../AbstractSubstitutionModel.h"
+#include "../AbstractBiblioMixedSubstitutionModel.h"
+
+using namespace std;
+
+namespace bpp
+{
+/**
+ * @brief The Le and Gascuel (2010) EX_EHO substitution model for proteins.
+ * @author Mathieu Groussin
+ *
+ * This model is a mixture of six models. It combines two previously published models, EX2 and EHO.
+ * Sites are classified as: exposed & extended, buried & extended, exposed & alpha-helix
+ * buried & alpha-helix, exposed & other, or buried & other.
+ * The submodels are called BUR_EXT, BUR_HEL, BUR_OTH, EXP_EXT, EXP_HEL and EXP_OTH.
+ * 
+ * The model includes 10 parameters :
+ *
+ * - relrate1 to relrate5 are the relative rates of the submodels;
+ * - relproba1 to relproba5 are the relative proportions of the submodels;
+ *
+ * Important: See the relation between these parameters and the
+ * rates and probabilities of the models in the description of
+ * MixtureOfSubstitutionModels class.
+ *
+ * Reference:
+ *
+ * Le S.Q., Gascuel O. (2010) Syst. Biol. 59(3):277–287
+ */
+
+class LG10_EX_EHO :
+  public AbstractBiblioMixedSubstitutionModel
+{
+public:
+  class EmbeddedModel :
+    public virtual ProteinSubstitutionModel,
+    public AbstractReversibleSubstitutionModel
+  {
+private:
+    double proportion_;
+    string name_;
+
+public:
+    EmbeddedModel(const ProteicAlphabet* alpha, string name);
+    ~EmbeddedModel(){}
+    EmbeddedModel* clone() const { return new EmbeddedModel(*this); }
+    string getName() const { return name_;}
+    double getProportion() const { return proportion_;}
+  };
+
+private:
+  std::auto_ptr<MixtureOfSubstitutionModels> pmixmodel_;
+
+public:
+  /**
+   * @brief Build a EX_EHO model, with original equilibrium frequencies, probabilities and rates.
+   *
+   * @param alpha A proteic alphabet.
+   *
+   */
+
+  LG10_EX_EHO(const ProteicAlphabet* alpha);
+
+  ~LG10_EX_EHO();
+
+  LG10_EX_EHO* clone() const { return new LG10_EX_EHO(*this); }
+
+  LG10_EX_EHO(const LG10_EX_EHO&);
+
+  LG10_EX_EHO& operator=(const LG10_EX_EHO&);
+
+  const SubstitutionModel& getModel() const { return *pmixmodel_.get(); }
+
+  const MixedSubstitutionModel& getMixedModel() const { return *pmixmodel_.get(); }
+  
+  std::string getName() const { return "LG10_EX_EHO"; }
+
+private:
+  SubstitutionModel& getModel() { return *pmixmodel_.get(); }
+  
+  MixedSubstitutionModel& getMixedModel() { return *pmixmodel_.get(); }
+  
+};
+} // end of namespace bpp.
+
+#endif  // _LG10_EX_EHO_H_
+
diff --git a/src/Bpp/Phyl/Model/Protein/LGL08_CAT.cpp b/src/Bpp/Phyl/Model/Protein/LGL08_CAT.cpp
index ac9dbba..04e125c 100644
--- a/src/Bpp/Phyl/Model/Protein/LGL08_CAT.cpp
+++ b/src/Bpp/Phyl/Model/Protein/LGL08_CAT.cpp
@@ -102,8 +102,7 @@ LGL08_CAT::~LGL08_CAT() {}
 
 LGL08_CAT::EmbeddedModel::EmbeddedModel(const ProteicAlphabet* alpha, string name, unsigned int nbCat) :
   AbstractParameterAliasable(name),
-  AbstractSubstitutionModel(alpha, name),
-  AbstractReversibleSubstitutionModel(alpha, name),
+  AbstractReversibleSubstitutionModel(alpha, new CanonicalStateMap(alpha, false), name),
   proportion_(1),
   name_(name)
 {
diff --git a/src/Bpp/Phyl/Model/Protein/LLG08_EHO.cpp b/src/Bpp/Phyl/Model/Protein/LLG08_EHO.cpp
index 7ddae3d..ae4327c 100644
--- a/src/Bpp/Phyl/Model/Protein/LLG08_EHO.cpp
+++ b/src/Bpp/Phyl/Model/Protein/LLG08_EHO.cpp
@@ -102,8 +102,7 @@ LLG08_EHO::~LLG08_EHO() {}
 
 LLG08_EHO::EmbeddedModel::EmbeddedModel(const ProteicAlphabet* alpha, string name) :
   AbstractParameterAliasable(name),
-  AbstractSubstitutionModel(alpha, name),
-  AbstractReversibleSubstitutionModel(alpha, name),
+  AbstractReversibleSubstitutionModel(alpha, new CanonicalStateMap(alpha, false), name),
   proportion_(1),
   name_(name)
 {
diff --git a/src/Bpp/Phyl/Model/Protein/LLG08_EX2.cpp b/src/Bpp/Phyl/Model/Protein/LLG08_EX2.cpp
index e50520c..6820f93 100644
--- a/src/Bpp/Phyl/Model/Protein/LLG08_EX2.cpp
+++ b/src/Bpp/Phyl/Model/Protein/LLG08_EX2.cpp
@@ -102,8 +102,7 @@ LLG08_EX2::~LLG08_EX2() {}
 
 LLG08_EX2::EmbeddedModel::EmbeddedModel(const ProteicAlphabet* alpha, string name) :
   AbstractParameterAliasable(name),
-  AbstractSubstitutionModel(alpha, name),
-  AbstractReversibleSubstitutionModel(alpha, name),
+  AbstractReversibleSubstitutionModel(alpha, new CanonicalStateMap(alpha, false), name),
   proportion_(1),
   name_(name)
 {
diff --git a/src/Bpp/Phyl/Model/Protein/LLG08_EX3.cpp b/src/Bpp/Phyl/Model/Protein/LLG08_EX3.cpp
index efc7ee7..31c7e49 100644
--- a/src/Bpp/Phyl/Model/Protein/LLG08_EX3.cpp
+++ b/src/Bpp/Phyl/Model/Protein/LLG08_EX3.cpp
@@ -103,8 +103,7 @@ LLG08_EX3::~LLG08_EX3() {}
 
 LLG08_EX3::EmbeddedModel::EmbeddedModel(const ProteicAlphabet* alpha, string name) :
   AbstractParameterAliasable(name),
-  AbstractSubstitutionModel(alpha, name),
-  AbstractReversibleSubstitutionModel(alpha, name),
+  AbstractReversibleSubstitutionModel(alpha, new CanonicalStateMap(alpha, false), name),
   proportion_(1),
   name_(name)
 {
diff --git a/src/Bpp/Phyl/Model/Protein/LLG08_UL2.cpp b/src/Bpp/Phyl/Model/Protein/LLG08_UL2.cpp
index 482963c..4b40dc6 100644
--- a/src/Bpp/Phyl/Model/Protein/LLG08_UL2.cpp
+++ b/src/Bpp/Phyl/Model/Protein/LLG08_UL2.cpp
@@ -102,8 +102,7 @@ LLG08_UL2::~LLG08_UL2() {}
 
 LLG08_UL2::EmbeddedModel::EmbeddedModel(const ProteicAlphabet* alpha, string name) :
   AbstractParameterAliasable(name),
-  AbstractSubstitutionModel(alpha, name),
-  AbstractReversibleSubstitutionModel(alpha, name),
+  AbstractReversibleSubstitutionModel(alpha, new CanonicalStateMap(alpha, false), name),
   proportion_(1),
   name_(name)
 {
diff --git a/src/Bpp/Phyl/Model/Protein/LLG08_UL3.cpp b/src/Bpp/Phyl/Model/Protein/LLG08_UL3.cpp
index 13f005e..2bb1fad 100644
--- a/src/Bpp/Phyl/Model/Protein/LLG08_UL3.cpp
+++ b/src/Bpp/Phyl/Model/Protein/LLG08_UL3.cpp
@@ -103,8 +103,7 @@ LLG08_UL3::~LLG08_UL3() {}
 
 LLG08_UL3::EmbeddedModel::EmbeddedModel(const ProteicAlphabet* alpha, string name) :
   AbstractParameterAliasable(name),
-  AbstractSubstitutionModel(alpha, name),
-  AbstractReversibleSubstitutionModel(alpha, name),
+  AbstractReversibleSubstitutionModel(alpha, new CanonicalStateMap(alpha, false), name),
   proportion_(1),
   name_(name)
 {
diff --git a/src/Bpp/Phyl/Model/Protein/UserProteinSubstitutionModel.cpp b/src/Bpp/Phyl/Model/Protein/UserProteinSubstitutionModel.cpp
index 6ae12e1..0a44552 100755
--- a/src/Bpp/Phyl/Model/Protein/UserProteinSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/Protein/UserProteinSubstitutionModel.cpp
@@ -62,8 +62,7 @@ using namespace std;
 UserProteinSubstitutionModel::UserProteinSubstitutionModel(
     const ProteicAlphabet* alpha, const std::string& path, const std::string& prefix) : 
   AbstractParameterAliasable(prefix),
-  AbstractSubstitutionModel(alpha, prefix),
-  AbstractReversibleSubstitutionModel(alpha, prefix),
+  AbstractReversibleSubstitutionModel(alpha, new CanonicalStateMap(alpha, false), prefix),
   path_(path),
   freqSet_(0)
 {
@@ -77,15 +76,14 @@ UserProteinSubstitutionModel::UserProteinSubstitutionModel(
     ProteinFrequenciesSet* freqSet, const std::string& prefix,
     bool initFreqs) : 
   AbstractParameterAliasable(prefix),
-  AbstractSubstitutionModel(alpha, prefix),
-  AbstractReversibleSubstitutionModel(alpha, prefix),
+  AbstractReversibleSubstitutionModel(alpha, new CanonicalStateMap(alpha, false), prefix),
   path_(path),
   freqSet_(freqSet)
 {
   readFromFile();
+  freqSet_->setNamespace(prefix+freqSet_->getNamespace());
   if (initFreqs) freqSet->setFrequencies(freq_);
   else freq_ = freqSet_->getFrequencies();
-  freqSet_->setNamespace(prefix+freqSet_->getNamespace());
   addParameters_(freqSet_->getParameters());
   updateMatrices();  
 }
@@ -151,15 +149,18 @@ void UserProteinSubstitutionModel::readFromFile()
 
 /******************************************************************************/
 
-void UserProteinSubstitutionModel::setFreqFromData(const SequenceContainer& data)
+void UserProteinSubstitutionModel::setFreqFromData(const SequenceContainer& data, double pseudoCount)
 {
-  std::map<int, double> freqs;
-  SequenceContainerTools::getFrequencies(data, freqs);
+  map<int, int> counts;
+  SequenceContainerTools::getCounts(data, counts);
   double t = 0;
-  for (unsigned int i = 0; i < size_; i++) t += freqs[i];
-  for (unsigned int i = 0; i < size_; i++) freq_[i] = freqs[i] / t;
+  for (int i = 0; i < static_cast<int>(size_); i++)
+  {
+    t += (counts[i] + pseudoCount);
+  }
+  for (size_t i = 0; i < size_; ++i) freq_[i] = (static_cast<double>(counts[static_cast<int>(i)]) + pseudoCount) / t;
   freqSet_->setFrequencies(freq_);
-  //Update parametrers and re-compute generator and eigen values:
+  //Update parameters and re-compute generator and eigen values:
   matchParametersValues(freqSet_->getParameters());
 }
 
diff --git a/src/Bpp/Phyl/Model/Protein/UserProteinSubstitutionModel.h b/src/Bpp/Phyl/Model/Protein/UserProteinSubstitutionModel.h
index c9316f4..5154d29 100755
--- a/src/Bpp/Phyl/Model/Protein/UserProteinSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/Protein/UserProteinSubstitutionModel.h
@@ -102,7 +102,7 @@ namespace bpp
 
     UserProteinSubstitutionModel(const UserProteinSubstitutionModel& model) :
       AbstractParameterAliasable(model),
-      AbstractSubstitutionModel(model),
+      //AbstractSubstitutionModel(model),
       AbstractReversibleSubstitutionModel(model),
       path_(model.path_),
       freqSet_(dynamic_cast<ProteinFrequenciesSet*>(model.freqSet_->clone()))
@@ -148,7 +148,7 @@ namespace bpp
 
     const FrequenciesSet* getFrequenciesSet() const { return freqSet_; }
 
-    void setFreqFromData(const SequenceContainer& data);
+    void setFreqFromData(const SequenceContainer& data, double pseudoCount = 0);
 
   protected:
     void readFromFile();
diff --git a/src/Bpp/Phyl/Model/Protein/WAG01.cpp b/src/Bpp/Phyl/Model/Protein/WAG01.cpp
index ef148d7..5f80f51 100644
--- a/src/Bpp/Phyl/Model/Protein/WAG01.cpp
+++ b/src/Bpp/Phyl/Model/Protein/WAG01.cpp
@@ -49,8 +49,7 @@ using namespace std;
 
 WAG01::WAG01(const ProteicAlphabet* alpha) :
   AbstractParameterAliasable("WAG01."),
-  AbstractSubstitutionModel(alpha, "WAG01."),
-  AbstractReversibleSubstitutionModel(alpha, "WAG01."),
+  AbstractReversibleSubstitutionModel(alpha, new CanonicalStateMap(alpha, false), "WAG01."),
   freqSet_(0)
 {
   #include "__WAG01ExchangeabilityCode"
@@ -61,28 +60,30 @@ WAG01::WAG01(const ProteicAlphabet* alpha) :
 
 WAG01::WAG01(const ProteicAlphabet* alpha, ProteinFrequenciesSet* freqSet, bool initFreqs) :
   AbstractParameterAliasable("WAG01+F."),
-  AbstractSubstitutionModel(alpha, "WAG01+F."),
-  AbstractReversibleSubstitutionModel(alpha, "WAG01+F."),
+  AbstractReversibleSubstitutionModel(alpha, new CanonicalStateMap(alpha, false), "WAG01+F."),
   freqSet_(freqSet)
 {
   #include "__WAG01ExchangeabilityCode"
   #include "__WAG01FrequenciesCode"
+  freqSet_->setNamespace("WAG01+F."+freqSet_->getNamespace());
   if (initFreqs) freqSet_->setFrequencies(freq_);
   else freq_ = freqSet_->getFrequencies();
-  freqSet_->setNamespace("WAG01+F."+freqSet_->getNamespace());
   addParameters_(freqSet_->getParameters());
   updateMatrices();  
 }
 
 /******************************************************************************/
 
-void WAG01::setFreqFromData(const SequenceContainer& data)
+void WAG01::setFreqFromData(const SequenceContainer& data, double pseudoCount)
 {
-  std::map<int, double> freqs;
-  SequenceContainerTools::getFrequencies(data, freqs);
+  map<int, int> counts;
+  SequenceContainerTools::getCounts(data, counts);
   double t = 0;
-  for (size_t i = 0; i < size_; i++) t += freqs[static_cast<int>(i)];
-  for (size_t i = 0; i < size_; i++) freq_[i] = freqs[static_cast<int>(i)] / t;
+  for (int i = 0; i < static_cast<int>(size_); i++)
+  {
+    t += (counts[i] + pseudoCount);
+  }
+  for (size_t i = 0; i < size_; ++i) freq_[i] = (static_cast<double>(counts[static_cast<int>(i)]) + pseudoCount) / t;
   freqSet_->setFrequencies(freq_);
   //Update parameters and re-compute generator and eigen values:
   matchParametersValues(freqSet_->getParameters());
diff --git a/src/Bpp/Phyl/Model/Protein/WAG01.h b/src/Bpp/Phyl/Model/Protein/WAG01.h
index 2f6ba6d..a1bbba0 100644
--- a/src/Bpp/Phyl/Model/Protein/WAG01.h
+++ b/src/Bpp/Phyl/Model/Protein/WAG01.h
@@ -95,7 +95,7 @@ namespace bpp
 
     WAG01(const WAG01& model) :
       AbstractParameterAliasable(model),
-      AbstractSubstitutionModel(model),
+      //AbstractSubstitutionModel(model),
       AbstractReversibleSubstitutionModel(model),
       freqSet_(dynamic_cast<ProteinFrequenciesSet *>(model.freqSet_->clone()))
     {}
@@ -145,7 +145,7 @@ namespace bpp
 
     const FrequenciesSet* getFrequenciesSet() const { return freqSet_; }
 
-    void setFreqFromData(const SequenceContainer& data);
+    void setFreqFromData(const SequenceContainer& data, double pseudoCount = 0);
 
   };
 
diff --git a/src/Bpp/Phyl/Model/Protein/__LG10_EX_EHOExchangeabilityCode b/src/Bpp/Phyl/Model/Protein/__LG10_EX_EHOExchangeabilityCode
new file mode 100644
index 0000000..e4b2875
--- /dev/null
+++ b/src/Bpp/Phyl/Model/Protein/__LG10_EX_EHOExchangeabilityCode
@@ -0,0 +1,2423 @@
+if (getName()=="BUR_EXT" || getName()=="BUR_EXT+F"){
+exchangeability_(1,0) = 0.228492;
+exchangeability_(0,1) = 0.228492;
+exchangeability_(2,0) = 0.165543;
+exchangeability_(0,2) = 0.165543;
+exchangeability_(2,1) = 0.916344;
+exchangeability_(1,2) = 0.916344;
+exchangeability_(3,0) = 0.238509;
+exchangeability_(0,3) = 0.238509;
+exchangeability_(3,1) = 0.258514;
+exchangeability_(1,3) = 0.258514;
+exchangeability_(3,2) = 8.49806;
+exchangeability_(2,3) = 8.49806;
+exchangeability_(4,0) = 3.37403;
+exchangeability_(0,4) = 3.37403;
+exchangeability_(4,1) = 1.03743;
+exchangeability_(1,4) = 1.03743;
+exchangeability_(4,2) = 1.6677;
+exchangeability_(2,4) = 1.6677;
+exchangeability_(4,3) = 0.332072;
+exchangeability_(3,4) = 0.332072;
+exchangeability_(5,0) = 0.344742;
+exchangeability_(0,5) = 0.344742;
+exchangeability_(5,1) = 4.97149;
+exchangeability_(1,5) = 4.97149;
+exchangeability_(5,2) = 2.47191;
+exchangeability_(2,5) = 2.47191;
+exchangeability_(5,3) = 0.65495;
+exchangeability_(3,5) = 0.65495;
+exchangeability_(5,4) = 0.130301;
+exchangeability_(4,5) = 0.130301;
+exchangeability_(6,0) = 0.417921;
+exchangeability_(0,6) = 0.417921;
+exchangeability_(6,1) = 1.03923;
+exchangeability_(1,6) = 1.03923;
+exchangeability_(6,2) = 0.875808;
+exchangeability_(2,6) = 0.875808;
+exchangeability_(6,3) = 13.0732;
+exchangeability_(3,6) = 13.0732;
+exchangeability_(6,4) = 0.040759;
+exchangeability_(4,6) = 0.040759;
+exchangeability_(6,5) = 9.83474;
+exchangeability_(5,6) = 9.83474;
+exchangeability_(7,0) = 4.24871;
+exchangeability_(0,7) = 4.24871;
+exchangeability_(7,1) = 0.411876;
+exchangeability_(1,7) = 0.411876;
+exchangeability_(7,2) = 0.58557;
+exchangeability_(2,7) = 0.58557;
+exchangeability_(7,3) = 0.748848;
+exchangeability_(3,7) = 0.748848;
+exchangeability_(7,4) = 0.908311;
+exchangeability_(4,7) = 0.908311;
+exchangeability_(7,5) = 0.221633;
+exchangeability_(5,7) = 0.221633;
+exchangeability_(7,6) = 0.593504;
+exchangeability_(6,7) = 0.593504;
+exchangeability_(8,0) = 0.182762;
+exchangeability_(0,8) = 0.182762;
+exchangeability_(8,1) = 3.87207;
+exchangeability_(1,8) = 3.87207;
+exchangeability_(8,2) = 6.99981;
+exchangeability_(2,8) = 6.99981;
+exchangeability_(8,3) = 1.71947;
+exchangeability_(3,8) = 1.71947;
+exchangeability_(8,4) = 0.493863;
+exchangeability_(4,8) = 0.493863;
+exchangeability_(8,5) = 8.69539;
+exchangeability_(5,8) = 8.69539;
+exchangeability_(8,6) = 0.749303;
+exchangeability_(6,8) = 0.749303;
+exchangeability_(8,7) = 0.137367;
+exchangeability_(7,8) = 0.137367;
+exchangeability_(9,0) = 0.011705;
+exchangeability_(0,9) = 0.011705;
+exchangeability_(9,1) = 0.090751;
+exchangeability_(1,9) = 0.090751;
+exchangeability_(9,2) = 0.149898;
+exchangeability_(2,9) = 0.149898;
+exchangeability_(9,3) = 0.021996;
+exchangeability_(3,9) = 0.021996;
+exchangeability_(9,4) = 0.077693;
+exchangeability_(4,9) = 0.077693;
+exchangeability_(9,5) = 0.043664;
+exchangeability_(5,9) = 0.043664;
+exchangeability_(9,6) = 0.01382;
+exchangeability_(6,9) = 0.01382;
+exchangeability_(9,7) = 0.001527;
+exchangeability_(7,9) = 0.001527;
+exchangeability_(9,8) = 0.073342;
+exchangeability_(8,9) = 0.073342;
+exchangeability_(10,0) = 0.133793;
+exchangeability_(0,10) = 0.133793;
+exchangeability_(10,1) = 0.286232;
+exchangeability_(1,10) = 0.286232;
+exchangeability_(10,2) = 0.065118;
+exchangeability_(2,10) = 0.065118;
+exchangeability_(10,3) = 0.01554;
+exchangeability_(3,10) = 0.01554;
+exchangeability_(10,4) = 0.456304;
+exchangeability_(4,10) = 0.456304;
+exchangeability_(10,5) = 0.546974;
+exchangeability_(5,10) = 0.546974;
+exchangeability_(10,6) = 0.052641;
+exchangeability_(6,10) = 0.052641;
+exchangeability_(10,7) = 0.024196;
+exchangeability_(7,10) = 0.024196;
+exchangeability_(10,8) = 0.22646;
+exchangeability_(8,10) = 0.22646;
+exchangeability_(10,9) = 2.16073;
+exchangeability_(9,10) = 2.16073;
+exchangeability_(11,0) = 0.249141;
+exchangeability_(0,11) = 0.249141;
+exchangeability_(11,1) = 17.7569;
+exchangeability_(1,11) = 17.7569;
+exchangeability_(11,2) = 3.38548;
+exchangeability_(2,11) = 3.38548;
+exchangeability_(11,3) = 0.34378;
+exchangeability_(3,11) = 0.34378;
+exchangeability_(11,4) = 0.093875;
+exchangeability_(4,11) = 0.093875;
+exchangeability_(11,5) = 6.67705;
+exchangeability_(5,11) = 6.67705;
+exchangeability_(11,6) = 2.74502;
+exchangeability_(6,11) = 2.74502;
+exchangeability_(11,7) = 0.295602;
+exchangeability_(7,11) = 0.295602;
+exchangeability_(11,8) = 1.482;
+exchangeability_(8,11) = 1.482;
+exchangeability_(11,9) = 0.100576;
+exchangeability_(9,11) = 0.100576;
+exchangeability_(11,10) = 0.167406;
+exchangeability_(10,11) = 0.167406;
+exchangeability_(12,0) = 0.641194;
+exchangeability_(0,12) = 0.641194;
+exchangeability_(12,1) = 0.342577;
+exchangeability_(1,12) = 0.342577;
+exchangeability_(12,2) = 0.427146;
+exchangeability_(2,12) = 0.427146;
+exchangeability_(12,3) = 0.059345;
+exchangeability_(3,12) = 0.059345;
+exchangeability_(12,4) = 0.867233;
+exchangeability_(4,12) = 0.867233;
+exchangeability_(12,5) = 2.30648;
+exchangeability_(5,12) = 2.30648;
+exchangeability_(12,6) = 0.21826;
+exchangeability_(6,12) = 0.21826;
+exchangeability_(12,7) = 0.058613;
+exchangeability_(7,12) = 0.058613;
+exchangeability_(12,8) = 0.358032;
+exchangeability_(8,12) = 0.358032;
+exchangeability_(12,9) = 2.1879;
+exchangeability_(9,12) = 2.1879;
+exchangeability_(12,10) = 5.15134;
+exchangeability_(10,12) = 5.15134;
+exchangeability_(12,11) = 0.750049;
+exchangeability_(11,12) = 0.750049;
+exchangeability_(13,0) = 0.118366;
+exchangeability_(0,13) = 0.118366;
+exchangeability_(13,1) = 0.068606;
+exchangeability_(1,13) = 0.068606;
+exchangeability_(13,2) = 0.102572;
+exchangeability_(2,13) = 0.102572;
+exchangeability_(13,3) = 0.009357;
+exchangeability_(3,13) = 0.009357;
+exchangeability_(13,4) = 0.633943;
+exchangeability_(4,13) = 0.633943;
+exchangeability_(13,5) = 0.033356;
+exchangeability_(5,13) = 0.033356;
+exchangeability_(13,6) = 0.012944;
+exchangeability_(6,13) = 0.012944;
+exchangeability_(13,7) = 0.024474;
+exchangeability_(7,13) = 0.024474;
+exchangeability_(13,8) = 0.497973;
+exchangeability_(8,13) = 0.497973;
+exchangeability_(13,9) = 0.534407;
+exchangeability_(9,13) = 0.534407;
+exchangeability_(13,10) = 1.58197;
+exchangeability_(10,13) = 1.58197;
+exchangeability_(13,11) = 0.063281;
+exchangeability_(11,13) = 0.063281;
+exchangeability_(13,12) = 1.32924;
+exchangeability_(12,13) = 1.32924;
+exchangeability_(14,0) = 1.56105;
+exchangeability_(0,14) = 1.56105;
+exchangeability_(14,1) = 0.483968;
+exchangeability_(1,14) = 0.483968;
+exchangeability_(14,2) = 0.38517;
+exchangeability_(2,14) = 0.38517;
+exchangeability_(14,3) = 0.261437;
+exchangeability_(3,14) = 0.261437;
+exchangeability_(14,4) = 0.310131;
+exchangeability_(4,14) = 0.310131;
+exchangeability_(14,5) = 0.913924;
+exchangeability_(5,14) = 0.913924;
+exchangeability_(14,6) = 0.355871;
+exchangeability_(6,14) = 0.355871;
+exchangeability_(14,7) = 0.17552;
+exchangeability_(7,14) = 0.17552;
+exchangeability_(14,8) = 0.512823;
+exchangeability_(8,14) = 0.512823;
+exchangeability_(14,9) = 0.019789;
+exchangeability_(9,14) = 0.019789;
+exchangeability_(14,10) = 0.295416;
+exchangeability_(10,14) = 0.295416;
+exchangeability_(14,11) = 0.348527;
+exchangeability_(11,14) = 0.348527;
+exchangeability_(14,12) = 0.104569;
+exchangeability_(12,14) = 0.104569;
+exchangeability_(14,13) = 0.059641;
+exchangeability_(13,14) = 0.059641;
+exchangeability_(15,0) = 5.89181;
+exchangeability_(0,15) = 5.89181;
+exchangeability_(15,1) = 1.32062;
+exchangeability_(1,15) = 1.32062;
+exchangeability_(15,2) = 5.73716;
+exchangeability_(2,15) = 5.73716;
+exchangeability_(15,3) = 1.07401;
+exchangeability_(3,15) = 1.07401;
+exchangeability_(15,4) = 4.70278;
+exchangeability_(4,15) = 4.70278;
+exchangeability_(15,5) = 1.38953;
+exchangeability_(5,15) = 1.38953;
+exchangeability_(15,6) = 0.87848;
+exchangeability_(6,15) = 0.87848;
+exchangeability_(15,7) = 2.17808;
+exchangeability_(7,15) = 2.17808;
+exchangeability_(15,8) = 1.11107;
+exchangeability_(8,15) = 1.11107;
+exchangeability_(15,9) = 0.033343;
+exchangeability_(9,15) = 0.033343;
+exchangeability_(15,10) = 0.094349;
+exchangeability_(10,15) = 0.094349;
+exchangeability_(15,11) = 1.0359;
+exchangeability_(11,15) = 1.0359;
+exchangeability_(15,12) = 0.327901;
+exchangeability_(12,15) = 0.327901;
+exchangeability_(15,13) = 0.292022;
+exchangeability_(13,15) = 0.292022;
+exchangeability_(15,14) = 1.34468;
+exchangeability_(14,15) = 1.34468;
+exchangeability_(16,0) = 2.05988;
+exchangeability_(0,16) = 2.05988;
+exchangeability_(16,1) = 0.976165;
+exchangeability_(1,16) = 0.976165;
+exchangeability_(16,2) = 2.16643;
+exchangeability_(2,16) = 2.16643;
+exchangeability_(16,3) = 0.369522;
+exchangeability_(3,16) = 0.369522;
+exchangeability_(16,4) = 1.95186;
+exchangeability_(4,16) = 1.95186;
+exchangeability_(16,5) = 0.815145;
+exchangeability_(5,16) = 0.815145;
+exchangeability_(16,6) = 0.575774;
+exchangeability_(6,16) = 0.575774;
+exchangeability_(16,7) = 0.060834;
+exchangeability_(7,16) = 0.060834;
+exchangeability_(16,8) = 0.558388;
+exchangeability_(8,16) = 0.558388;
+exchangeability_(16,9) = 0.422299;
+exchangeability_(9,16) = 0.422299;
+exchangeability_(16,10) = 0.153549;
+exchangeability_(10,16) = 0.153549;
+exchangeability_(16,11) = 1.79326;
+exchangeability_(11,16) = 1.79326;
+exchangeability_(16,12) = 1.26813;
+exchangeability_(12,16) = 1.26813;
+exchangeability_(16,13) = 0.085468;
+exchangeability_(13,16) = 0.085468;
+exchangeability_(16,14) = 0.780914;
+exchangeability_(14,16) = 0.780914;
+exchangeability_(16,15) = 9.03131;
+exchangeability_(15,16) = 9.03131;
+exchangeability_(17,0) = 0.081683;
+exchangeability_(0,17) = 0.081683;
+exchangeability_(17,1) = 0.814216;
+exchangeability_(1,17) = 0.814216;
+exchangeability_(17,2) = 0.057557;
+exchangeability_(2,17) = 0.057557;
+exchangeability_(17,3) = 0.055146;
+exchangeability_(3,17) = 0.055146;
+exchangeability_(17,4) = 0.450959;
+exchangeability_(4,17) = 0.450959;
+exchangeability_(17,5) = 0.191881;
+exchangeability_(5,17) = 0.191881;
+exchangeability_(17,6) = 0.10942;
+exchangeability_(6,17) = 0.10942;
+exchangeability_(17,7) = 0.144367;
+exchangeability_(7,17) = 0.144367;
+exchangeability_(17,8) = 0.651978;
+exchangeability_(8,17) = 0.651978;
+exchangeability_(17,9) = 0.068649;
+exchangeability_(9,17) = 0.068649;
+exchangeability_(17,10) = 0.345622;
+exchangeability_(10,17) = 0.345622;
+exchangeability_(17,11) = 0.169527;
+exchangeability_(11,17) = 0.169527;
+exchangeability_(17,12) = 0.387902;
+exchangeability_(12,17) = 0.387902;
+exchangeability_(17,13) = 1.88374;
+exchangeability_(13,17) = 1.88374;
+exchangeability_(17,14) = 0.023466;
+exchangeability_(14,17) = 0.023466;
+exchangeability_(17,15) = 0.309129;
+exchangeability_(15,17) = 0.309129;
+exchangeability_(17,16) = 0.111568;
+exchangeability_(16,17) = 0.111568;
+exchangeability_(18,0) = 0.05265;
+exchangeability_(0,18) = 0.05265;
+exchangeability_(18,1) = 0.248907;
+exchangeability_(1,18) = 0.248907;
+exchangeability_(18,2) = 0.570101;
+exchangeability_(2,18) = 0.570101;
+exchangeability_(18,3) = 0.180267;
+exchangeability_(3,18) = 0.180267;
+exchangeability_(18,4) = 0.70126;
+exchangeability_(4,18) = 0.70126;
+exchangeability_(18,5) = 0.253975;
+exchangeability_(5,18) = 0.253975;
+exchangeability_(18,6) = 0.061388;
+exchangeability_(6,18) = 0.061388;
+exchangeability_(18,7) = 0.025465;
+exchangeability_(7,18) = 0.025465;
+exchangeability_(18,8) = 4.20611;
+exchangeability_(8,18) = 4.20611;
+exchangeability_(18,9) = 0.083799;
+exchangeability_(9,18) = 0.083799;
+exchangeability_(18,10) = 0.1476;
+exchangeability_(10,18) = 0.1476;
+exchangeability_(18,11) = 0.226848;
+exchangeability_(11,18) = 0.226848;
+exchangeability_(18,12) = 0.25472;
+exchangeability_(12,18) = 0.25472;
+exchangeability_(18,13) = 6.54943;
+exchangeability_(13,18) = 6.54943;
+exchangeability_(18,14) = 0.027521;
+exchangeability_(14,18) = 0.027521;
+exchangeability_(18,15) = 0.283138;
+exchangeability_(15,18) = 0.283138;
+exchangeability_(18,16) = 0.141408;
+exchangeability_(16,18) = 0.141408;
+exchangeability_(18,17) = 2.56111;
+exchangeability_(17,18) = 2.56111;
+exchangeability_(19,0) = 1.35534;
+exchangeability_(0,19) = 1.35534;
+exchangeability_(19,1) = 0.137437;
+exchangeability_(1,19) = 0.137437;
+exchangeability_(19,2) = 0.104597;
+exchangeability_(2,19) = 0.104597;
+exchangeability_(19,3) = 0.051387;
+exchangeability_(3,19) = 0.051387;
+exchangeability_(19,4) = 1.20383;
+exchangeability_(4,19) = 1.20383;
+exchangeability_(19,5) = 0.218892;
+exchangeability_(5,19) = 0.218892;
+exchangeability_(19,6) = 0.194527;
+exchangeability_(6,19) = 0.194527;
+exchangeability_(19,7) = 0.031054;
+exchangeability_(7,19) = 0.031054;
+exchangeability_(19,8) = 0.088935;
+exchangeability_(8,19) = 0.088935;
+exchangeability_(19,9) = 4.57747;
+exchangeability_(9,19) = 4.57747;
+exchangeability_(19,10) = 1.00365;
+exchangeability_(10,19) = 1.00365;
+exchangeability_(19,11) = 0.153722;
+exchangeability_(11,19) = 0.153722;
+exchangeability_(19,12) = 0.883283;
+exchangeability_(12,19) = 0.883283;
+exchangeability_(19,13) = 0.242657;
+exchangeability_(13,19) = 0.242657;
+exchangeability_(19,14) = 0.191295;
+exchangeability_(14,19) = 0.191295;
+exchangeability_(19,15) = 0.068785;
+exchangeability_(15,19) = 0.068785;
+exchangeability_(19,16) = 0.990922;
+exchangeability_(16,19) = 0.990922;
+exchangeability_(19,17) = 0.056276;
+exchangeability_(17,19) = 0.056276;
+exchangeability_(19,18) = 0.078264;
+exchangeability_(18,19) = 0.078264;
+exchangeability_(0,0) = -21.3573;
+exchangeability_(1,1) = -35.2618;
+exchangeability_(2,2) = -35.332;
+exchangeability_(3,3) = -27.9654;
+exchangeability_(4,4) = -19.4343;
+exchangeability_(5,5) = -40.716;
+exchangeability_(6,6) = -31.8426;
+exchangeability_(7,7) = -10.8756;
+exchangeability_(8,8) = -32.6171;
+exchangeability_(9,9) = -10.6734;
+exchangeability_(10,10) = -12.9089;
+exchangeability_(11,11) = -37.838;
+exchangeability_(12,12) = -17.9239;
+exchangeability_(13,13) = -14.1234;
+exchangeability_(14,14) = -8.15571;
+exchangeability_(15,15) = -37.1041;
+exchangeability_(16,16) = -24.3128;
+exchangeability_(17,17) = -8.4742;
+exchangeability_(18,18) = -16.654;
+exchangeability_(19,19) = -11.6323;
+}
+
+
+if (getName()=="BUR_HEL" || getName()=="BUR_HEL+F"){
+exchangeability_(1,0) = 0.317211;
+exchangeability_(0,1) = 0.317211;
+exchangeability_(2,0) = 0.209784;
+exchangeability_(0,2) = 0.209784;
+exchangeability_(2,1) = 1.12087;
+exchangeability_(1,2) = 1.12087;
+exchangeability_(3,0) = 0.315205;
+exchangeability_(0,3) = 0.315205;
+exchangeability_(3,1) = 0.30105;
+exchangeability_(1,3) = 0.30105;
+exchangeability_(3,2) = 7.4399;
+exchangeability_(2,3) = 7.4399;
+exchangeability_(4,0) = 2.21445;
+exchangeability_(0,4) = 2.21445;
+exchangeability_(4,1) = 0.884449;
+exchangeability_(1,4) = 0.884449;
+exchangeability_(4,2) = 1.35629;
+exchangeability_(2,4) = 1.35629;
+exchangeability_(4,3) = 0.110768;
+exchangeability_(3,4) = 0.110768;
+exchangeability_(5,0) = 0.465495;
+exchangeability_(0,5) = 0.465495;
+exchangeability_(5,1) = 4.31979;
+exchangeability_(1,5) = 4.31979;
+exchangeability_(5,2) = 2.84319;
+exchangeability_(2,5) = 2.84319;
+exchangeability_(5,3) = 1.08254;
+exchangeability_(3,5) = 1.08254;
+exchangeability_(5,4) = 0.215988;
+exchangeability_(4,5) = 0.215988;
+exchangeability_(6,0) = 0.668735;
+exchangeability_(0,6) = 0.668735;
+exchangeability_(6,1) = 0.901135;
+exchangeability_(1,6) = 0.901135;
+exchangeability_(6,2) = 0.986572;
+exchangeability_(2,6) = 0.986572;
+exchangeability_(6,3) = 11.2452;
+exchangeability_(3,6) = 11.2452;
+exchangeability_(6,4) = 0.009874;
+exchangeability_(4,6) = 0.009874;
+exchangeability_(6,5) = 7.56177;
+exchangeability_(5,6) = 7.56177;
+exchangeability_(7,0) = 3.61416;
+exchangeability_(0,7) = 3.61416;
+exchangeability_(7,1) = 0.568883;
+exchangeability_(1,7) = 0.568883;
+exchangeability_(7,2) = 0.97266;
+exchangeability_(2,7) = 0.97266;
+exchangeability_(7,3) = 1.03612;
+exchangeability_(3,7) = 1.03612;
+exchangeability_(7,4) = 0.894733;
+exchangeability_(4,7) = 0.894733;
+exchangeability_(7,5) = 0.409083;
+exchangeability_(5,7) = 0.409083;
+exchangeability_(7,6) = 0.780808;
+exchangeability_(6,7) = 0.780808;
+exchangeability_(8,0) = 0.249929;
+exchangeability_(0,8) = 0.249929;
+exchangeability_(8,1) = 3.1387;
+exchangeability_(1,8) = 3.1387;
+exchangeability_(8,2) = 7.34494;
+exchangeability_(2,8) = 7.34494;
+exchangeability_(8,3) = 1.74767;
+exchangeability_(3,8) = 1.74767;
+exchangeability_(8,4) = 0.379845;
+exchangeability_(4,8) = 0.379845;
+exchangeability_(8,5) = 9.55976;
+exchangeability_(5,8) = 9.55976;
+exchangeability_(8,6) = 0.842239;
+exchangeability_(6,8) = 0.842239;
+exchangeability_(8,7) = 0.146008;
+exchangeability_(7,8) = 0.146008;
+exchangeability_(9,0) = 0.059633;
+exchangeability_(0,9) = 0.059633;
+exchangeability_(9,1) = 0.10329;
+exchangeability_(1,9) = 0.10329;
+exchangeability_(9,2) = 0.206475;
+exchangeability_(2,9) = 0.206475;
+exchangeability_(9,3) = 0.017492;
+exchangeability_(3,9) = 0.017492;
+exchangeability_(9,4) = 0.286194;
+exchangeability_(4,9) = 0.286194;
+exchangeability_(9,5) = 0.123433;
+exchangeability_(5,9) = 0.123433;
+exchangeability_(9,6) = 0.037593;
+exchangeability_(6,9) = 0.037593;
+exchangeability_(9,7) = 0.01091;
+exchangeability_(7,9) = 0.01091;
+exchangeability_(9,8) = 0.071273;
+exchangeability_(8,9) = 0.071273;
+exchangeability_(10,0) = 0.09623;
+exchangeability_(0,10) = 0.09623;
+exchangeability_(10,1) = 0.285199;
+exchangeability_(1,10) = 0.285199;
+exchangeability_(10,2) = 0.113728;
+exchangeability_(2,10) = 0.113728;
+exchangeability_(10,3) = 0.015874;
+exchangeability_(3,10) = 0.015874;
+exchangeability_(10,4) = 0.439724;
+exchangeability_(4,10) = 0.439724;
+exchangeability_(10,5) = 0.547078;
+exchangeability_(5,10) = 0.547078;
+exchangeability_(10,6) = 0.063675;
+exchangeability_(6,10) = 0.063675;
+exchangeability_(10,7) = 0.021607;
+exchangeability_(7,10) = 0.021607;
+exchangeability_(10,8) = 0.303531;
+exchangeability_(8,10) = 0.303531;
+exchangeability_(10,9) = 2.09735;
+exchangeability_(9,10) = 2.09735;
+exchangeability_(11,0) = 0.380075;
+exchangeability_(0,11) = 0.380075;
+exchangeability_(11,1) = 15.7834;
+exchangeability_(1,11) = 15.7834;
+exchangeability_(11,2) = 2.78011;
+exchangeability_(2,11) = 2.78011;
+exchangeability_(11,3) = 0.569108;
+exchangeability_(3,11) = 0.569108;
+exchangeability_(11,4) = 0.093004;
+exchangeability_(4,11) = 0.093004;
+exchangeability_(11,5) = 6.1799;
+exchangeability_(5,11) = 6.1799;
+exchangeability_(11,6) = 3.20959;
+exchangeability_(6,11) = 3.20959;
+exchangeability_(11,7) = 0.41396;
+exchangeability_(7,11) = 0.41396;
+exchangeability_(11,8) = 1.00208;
+exchangeability_(8,11) = 1.00208;
+exchangeability_(11,9) = 0.185911;
+exchangeability_(9,11) = 0.185911;
+exchangeability_(11,10) = 0.185249;
+exchangeability_(10,11) = 0.185249;
+exchangeability_(12,0) = 0.371379;
+exchangeability_(0,12) = 0.371379;
+exchangeability_(12,1) = 0.411553;
+exchangeability_(1,12) = 0.411553;
+exchangeability_(12,2) = 0.398602;
+exchangeability_(2,12) = 0.398602;
+exchangeability_(12,3) = 0.076761;
+exchangeability_(3,12) = 0.076761;
+exchangeability_(12,4) = 0.727245;
+exchangeability_(4,12) = 0.727245;
+exchangeability_(12,5) = 1.66565;
+exchangeability_(5,12) = 1.66565;
+exchangeability_(12,6) = 0.249045;
+exchangeability_(6,12) = 0.249045;
+exchangeability_(12,7) = 0.068128;
+exchangeability_(7,12) = 0.068128;
+exchangeability_(12,8) = 0.256194;
+exchangeability_(8,12) = 0.256194;
+exchangeability_(12,9) = 2.94031;
+exchangeability_(9,12) = 2.94031;
+exchangeability_(12,10) = 3.64954;
+exchangeability_(10,12) = 3.64954;
+exchangeability_(12,11) = 0.972247;
+exchangeability_(11,12) = 0.972247;
+exchangeability_(13,0) = 0.075616;
+exchangeability_(0,13) = 0.075616;
+exchangeability_(13,1) = 0.043519;
+exchangeability_(1,13) = 0.043519;
+exchangeability_(13,2) = 0.096446;
+exchangeability_(2,13) = 0.096446;
+exchangeability_(13,3) = 0.041118;
+exchangeability_(3,13) = 0.041118;
+exchangeability_(13,4) = 0.636688;
+exchangeability_(4,13) = 0.636688;
+exchangeability_(13,5) = 0.10246;
+exchangeability_(5,13) = 0.10246;
+exchangeability_(13,6) = 0.039991;
+exchangeability_(6,13) = 0.039991;
+exchangeability_(13,7) = 0.041269;
+exchangeability_(7,13) = 0.041269;
+exchangeability_(13,8) = 0.839126;
+exchangeability_(8,13) = 0.839126;
+exchangeability_(13,9) = 0.376556;
+exchangeability_(9,13) = 0.376556;
+exchangeability_(13,10) = 1.55181;
+exchangeability_(10,13) = 1.55181;
+exchangeability_(13,11) = 0.064774;
+exchangeability_(11,13) = 0.064774;
+exchangeability_(13,12) = 1.17396;
+exchangeability_(12,13) = 1.17396;
+exchangeability_(14,0) = 1.10057;
+exchangeability_(0,14) = 1.10057;
+exchangeability_(14,1) = 0.385197;
+exchangeability_(1,14) = 0.385197;
+exchangeability_(14,2) = 0.319458;
+exchangeability_(2,14) = 0.319458;
+exchangeability_(14,3) = 0.353;
+exchangeability_(3,14) = 0.353;
+exchangeability_(14,4) = 0.112549;
+exchangeability_(4,14) = 0.112549;
+exchangeability_(14,5) = 0.805706;
+exchangeability_(5,14) = 0.805706;
+exchangeability_(14,6) = 0.369483;
+exchangeability_(6,14) = 0.369483;
+exchangeability_(14,7) = 0.482895;
+exchangeability_(7,14) = 0.482895;
+exchangeability_(14,8) = 0.520098;
+exchangeability_(8,14) = 0.520098;
+exchangeability_(14,9) = 0.058167;
+exchangeability_(9,14) = 0.058167;
+exchangeability_(14,10) = 0.144341;
+exchangeability_(10,14) = 0.144341;
+exchangeability_(14,11) = 0.361488;
+exchangeability_(11,14) = 0.361488;
+exchangeability_(14,12) = 0.074069;
+exchangeability_(12,14) = 0.074069;
+exchangeability_(14,13) = 0.057968;
+exchangeability_(13,14) = 0.057968;
+exchangeability_(15,0) = 6.83296;
+exchangeability_(0,15) = 6.83296;
+exchangeability_(15,1) = 0.95516;
+exchangeability_(1,15) = 0.95516;
+exchangeability_(15,2) = 5.29663;
+exchangeability_(2,15) = 5.29663;
+exchangeability_(15,3) = 1.26521;
+exchangeability_(3,15) = 1.26521;
+exchangeability_(15,4) = 6.14476;
+exchangeability_(4,15) = 6.14476;
+exchangeability_(15,5) = 1.31518;
+exchangeability_(5,15) = 1.31518;
+exchangeability_(15,6) = 0.902504;
+exchangeability_(6,15) = 0.902504;
+exchangeability_(15,7) = 3.9038;
+exchangeability_(7,15) = 3.9038;
+exchangeability_(15,8) = 0.862633;
+exchangeability_(8,15) = 0.862633;
+exchangeability_(15,9) = 0.072343;
+exchangeability_(9,15) = 0.072343;
+exchangeability_(15,10) = 0.080478;
+exchangeability_(10,15) = 0.080478;
+exchangeability_(15,11) = 0.979654;
+exchangeability_(11,15) = 0.979654;
+exchangeability_(15,12) = 0.330305;
+exchangeability_(12,15) = 0.330305;
+exchangeability_(15,13) = 0.328917;
+exchangeability_(13,15) = 0.328917;
+exchangeability_(15,14) = 1.9249;
+exchangeability_(14,15) = 1.9249;
+exchangeability_(16,0) = 2.22321;
+exchangeability_(0,16) = 2.22321;
+exchangeability_(16,1) = 0.445571;
+exchangeability_(1,16) = 0.445571;
+exchangeability_(16,2) = 2.46183;
+exchangeability_(2,16) = 2.46183;
+exchangeability_(16,3) = 0.299635;
+exchangeability_(3,16) = 0.299635;
+exchangeability_(16,4) = 2.94321;
+exchangeability_(4,16) = 2.94321;
+exchangeability_(16,5) = 0.830637;
+exchangeability_(5,16) = 0.830637;
+exchangeability_(16,6) = 0.621903;
+exchangeability_(6,16) = 0.621903;
+exchangeability_(16,7) = 0.184055;
+exchangeability_(7,16) = 0.184055;
+exchangeability_(16,8) = 0.468356;
+exchangeability_(8,16) = 0.468356;
+exchangeability_(16,9) = 0.911139;
+exchangeability_(9,16) = 0.911139;
+exchangeability_(16,10) = 0.208091;
+exchangeability_(10,16) = 0.208091;
+exchangeability_(16,11) = 1.34326;
+exchangeability_(11,16) = 1.34326;
+exchangeability_(16,12) = 1.51534;
+exchangeability_(12,16) = 1.51534;
+exchangeability_(16,13) = 0.158763;
+exchangeability_(13,16) = 0.158763;
+exchangeability_(16,14) = 0.915879;
+exchangeability_(14,16) = 0.915879;
+exchangeability_(16,15) = 9.29879;
+exchangeability_(15,16) = 9.29879;
+exchangeability_(17,0) = 0.062541;
+exchangeability_(0,17) = 0.062541;
+exchangeability_(17,1) = 0.806724;
+exchangeability_(1,17) = 0.806724;
+exchangeability_(17,2) = 0.110928;
+exchangeability_(2,17) = 0.110928;
+exchangeability_(17,3) = 0.132125;
+exchangeability_(3,17) = 0.132125;
+exchangeability_(17,4) = 0.414525;
+exchangeability_(4,17) = 0.414525;
+exchangeability_(17,5) = 0.388313;
+exchangeability_(5,17) = 0.388313;
+exchangeability_(17,6) = 0.191952;
+exchangeability_(6,17) = 0.191952;
+exchangeability_(17,7) = 0.271274;
+exchangeability_(7,17) = 0.271274;
+exchangeability_(17,8) = 0.909529;
+exchangeability_(8,17) = 0.909529;
+exchangeability_(17,9) = 0.02579;
+exchangeability_(9,17) = 0.02579;
+exchangeability_(17,10) = 0.343842;
+exchangeability_(10,17) = 0.343842;
+exchangeability_(17,11) = 0.099137;
+exchangeability_(11,17) = 0.099137;
+exchangeability_(17,12) = 0.543577;
+exchangeability_(12,17) = 0.543577;
+exchangeability_(17,13) = 2.46715;
+exchangeability_(13,17) = 2.46715;
+exchangeability_(17,14) = 0.044938;
+exchangeability_(14,17) = 0.044938;
+exchangeability_(17,15) = 0.215329;
+exchangeability_(15,17) = 0.215329;
+exchangeability_(17,16) = 0.087955;
+exchangeability_(16,17) = 0.087955;
+exchangeability_(18,0) = 0.082948;
+exchangeability_(0,18) = 0.082948;
+exchangeability_(18,1) = 0.329591;
+exchangeability_(1,18) = 0.329591;
+exchangeability_(18,2) = 0.693402;
+exchangeability_(2,18) = 0.693402;
+exchangeability_(18,3) = 0.286594;
+exchangeability_(3,18) = 0.286594;
+exchangeability_(18,4) = 0.866329;
+exchangeability_(4,18) = 0.866329;
+exchangeability_(18,5) = 0.259566;
+exchangeability_(5,18) = 0.259566;
+exchangeability_(18,6) = 0.167425;
+exchangeability_(6,18) = 0.167425;
+exchangeability_(18,7) = 0.049038;
+exchangeability_(7,18) = 0.049038;
+exchangeability_(18,8) = 6.33205;
+exchangeability_(8,18) = 6.33205;
+exchangeability_(18,9) = 0.093136;
+exchangeability_(9,18) = 0.093136;
+exchangeability_(18,10) = 0.177755;
+exchangeability_(10,18) = 0.177755;
+exchangeability_(18,11) = 0.275998;
+exchangeability_(11,18) = 0.275998;
+exchangeability_(18,12) = 0.261754;
+exchangeability_(12,18) = 0.261754;
+exchangeability_(18,13) = 8.34468;
+exchangeability_(13,18) = 8.34468;
+exchangeability_(18,14) = 0.088981;
+exchangeability_(14,18) = 0.088981;
+exchangeability_(18,15) = 0.335859;
+exchangeability_(15,18) = 0.335859;
+exchangeability_(18,16) = 0.137177;
+exchangeability_(16,18) = 0.137177;
+exchangeability_(18,17) = 3.12502;
+exchangeability_(17,18) = 3.12502;
+exchangeability_(19,0) = 1.39048;
+exchangeability_(0,19) = 1.39048;
+exchangeability_(19,1) = 0.142986;
+exchangeability_(1,19) = 0.142986;
+exchangeability_(19,2) = 0.175068;
+exchangeability_(2,19) = 0.175068;
+exchangeability_(19,3) = 0.106294;
+exchangeability_(3,19) = 0.106294;
+exchangeability_(19,4) = 1.68729;
+exchangeability_(4,19) = 1.68729;
+exchangeability_(19,5) = 0.15952;
+exchangeability_(5,19) = 0.15952;
+exchangeability_(19,6) = 0.297915;
+exchangeability_(6,19) = 0.297915;
+exchangeability_(19,7) = 0.080925;
+exchangeability_(7,19) = 0.080925;
+exchangeability_(19,8) = 0.085103;
+exchangeability_(8,19) = 0.085103;
+exchangeability_(19,9) = 6.41469;
+exchangeability_(9,19) = 6.41469;
+exchangeability_(19,10) = 0.953785;
+exchangeability_(10,19) = 0.953785;
+exchangeability_(19,11) = 0.240157;
+exchangeability_(11,19) = 0.240157;
+exchangeability_(19,12) = 1.09735;
+exchangeability_(12,19) = 1.09735;
+exchangeability_(19,13) = 0.264988;
+exchangeability_(13,19) = 0.264988;
+exchangeability_(19,14) = 0.37387;
+exchangeability_(14,19) = 0.37387;
+exchangeability_(19,15) = 0.14423;
+exchangeability_(15,19) = 0.14423;
+exchangeability_(19,16) = 2.57284;
+exchangeability_(16,19) = 2.57284;
+exchangeability_(19,17) = 0.08911;
+exchangeability_(17,19) = 0.08911;
+exchangeability_(19,18) = 0.115941;
+exchangeability_(18,19) = 0.115941;
+exchangeability_(0,0) = -20.7306;
+exchangeability_(1,1) = -31.2442;
+exchangeability_(2,2) = -34.9269;
+exchangeability_(3,3) = -26.4416;
+exchangeability_(4,4) = -20.4179;
+exchangeability_(5,5) = -38.8351;
+exchangeability_(6,6) = -29.1474;
+exchangeability_(7,7) = -13.9503;
+exchangeability_(8,8) = -35.0591;
+exchangeability_(9,9) = -14.0917;
+exchangeability_(10,10) = -11.2789;
+exchangeability_(11,11) = -35.1191;
+exchangeability_(12,12) = -16.783;
+exchangeability_(13,13) = -16.7058;
+exchangeability_(14,14) = -8.49356;
+exchangeability_(15,15) = -41.1896;
+exchangeability_(16,16) = -27.6276;
+exchangeability_(17,17) = -10.3298;
+exchangeability_(18,18) = -22.0232;
+exchangeability_(19,19) = -16.3925;
+}
+
+
+if (getName()=="BUR_OTH" || getName()=="BUR_OTH+F"){
+exchangeability_(1,0) = 0.406682;
+exchangeability_(0,1) = 0.406682;
+exchangeability_(2,0) = 0.246649;
+exchangeability_(0,2) = 0.246649;
+exchangeability_(2,1) = 0.848592;
+exchangeability_(1,2) = 0.848592;
+exchangeability_(3,0) = 0.36426;
+exchangeability_(0,3) = 0.36426;
+exchangeability_(3,1) = 0.19869;
+exchangeability_(1,3) = 0.19869;
+exchangeability_(3,2) = 4.53584;
+exchangeability_(2,3) = 4.53584;
+exchangeability_(4,0) = 3.29204;
+exchangeability_(0,4) = 3.29204;
+exchangeability_(4,1) = 0.837291;
+exchangeability_(1,4) = 0.837291;
+exchangeability_(4,2) = 1.29514;
+exchangeability_(2,4) = 1.29514;
+exchangeability_(4,3) = 0.420726;
+exchangeability_(3,4) = 0.420726;
+exchangeability_(5,0) = 0.735862;
+exchangeability_(0,5) = 0.735862;
+exchangeability_(5,1) = 4.20509;
+exchangeability_(1,5) = 4.20509;
+exchangeability_(5,2) = 2.0625;
+exchangeability_(2,5) = 2.0625;
+exchangeability_(5,3) = 0.427451;
+exchangeability_(3,5) = 0.427451;
+exchangeability_(5,4) = 0.259335;
+exchangeability_(4,5) = 0.259335;
+exchangeability_(6,0) = 0.954795;
+exchangeability_(0,6) = 0.954795;
+exchangeability_(6,1) = 0.673046;
+exchangeability_(1,6) = 0.673046;
+exchangeability_(6,2) = 0.671062;
+exchangeability_(2,6) = 0.671062;
+exchangeability_(6,3) = 8.39567;
+exchangeability_(3,6) = 8.39567;
+exchangeability_(6,4) = 0.048284;
+exchangeability_(4,6) = 0.048284;
+exchangeability_(6,5) = 8.92274;
+exchangeability_(5,6) = 8.92274;
+exchangeability_(7,0) = 1.95885;
+exchangeability_(0,7) = 1.95885;
+exchangeability_(7,1) = 0.573207;
+exchangeability_(1,7) = 0.573207;
+exchangeability_(7,2) = 0.632317;
+exchangeability_(2,7) = 0.632317;
+exchangeability_(7,3) = 0.572264;
+exchangeability_(3,7) = 0.572264;
+exchangeability_(7,4) = 0.486274;
+exchangeability_(4,7) = 0.486274;
+exchangeability_(7,5) = 0.345345;
+exchangeability_(5,7) = 0.345345;
+exchangeability_(7,6) = 0.650009;
+exchangeability_(6,7) = 0.650009;
+exchangeability_(8,0) = 0.312042;
+exchangeability_(0,8) = 0.312042;
+exchangeability_(8,1) = 2.69966;
+exchangeability_(1,8) = 2.69966;
+exchangeability_(8,2) = 4.96985;
+exchangeability_(2,8) = 4.96985;
+exchangeability_(8,3) = 1.18178;
+exchangeability_(3,8) = 1.18178;
+exchangeability_(8,4) = 0.551188;
+exchangeability_(4,8) = 0.551188;
+exchangeability_(8,5) = 7.62045;
+exchangeability_(5,8) = 7.62045;
+exchangeability_(8,6) = 0.701108;
+exchangeability_(6,8) = 0.701108;
+exchangeability_(8,7) = 0.195346;
+exchangeability_(7,8) = 0.195346;
+exchangeability_(9,0) = 0.071;
+exchangeability_(0,9) = 0.071;
+exchangeability_(9,1) = 0.127041;
+exchangeability_(1,9) = 0.127041;
+exchangeability_(9,2) = 0.184028;
+exchangeability_(2,9) = 0.184028;
+exchangeability_(9,3) = 0.03024;
+exchangeability_(3,9) = 0.03024;
+exchangeability_(9,4) = 0.180591;
+exchangeability_(4,9) = 0.180591;
+exchangeability_(9,5) = 0.065984;
+exchangeability_(5,9) = 0.065984;
+exchangeability_(9,6) = 0.039235;
+exchangeability_(6,9) = 0.039235;
+exchangeability_(9,7) = 0.005033;
+exchangeability_(7,9) = 0.005033;
+exchangeability_(9,8) = 0.098525;
+exchangeability_(8,9) = 0.098525;
+exchangeability_(10,0) = 0.142298;
+exchangeability_(0,10) = 0.142298;
+exchangeability_(10,1) = 0.338853;
+exchangeability_(1,10) = 0.338853;
+exchangeability_(10,2) = 0.086876;
+exchangeability_(2,10) = 0.086876;
+exchangeability_(10,3) = 0.026095;
+exchangeability_(3,10) = 0.026095;
+exchangeability_(10,4) = 0.484427;
+exchangeability_(4,10) = 0.484427;
+exchangeability_(10,5) = 0.867777;
+exchangeability_(5,10) = 0.867777;
+exchangeability_(10,6) = 0.08778;
+exchangeability_(6,10) = 0.08778;
+exchangeability_(10,7) = 0.017129;
+exchangeability_(7,10) = 0.017129;
+exchangeability_(10,8) = 0.309774;
+exchangeability_(8,10) = 0.309774;
+exchangeability_(10,9) = 3.47714;
+exchangeability_(9,10) = 3.47714;
+exchangeability_(11,0) = 0.624622;
+exchangeability_(0,11) = 0.624622;
+exchangeability_(11,1) = 18.3906;
+exchangeability_(1,11) = 18.3906;
+exchangeability_(11,2) = 2.74865;
+exchangeability_(2,11) = 2.74865;
+exchangeability_(11,3) = 0.442886;
+exchangeability_(3,11) = 0.442886;
+exchangeability_(11,4) = 0.238266;
+exchangeability_(4,11) = 0.238266;
+exchangeability_(11,5) = 6.99394;
+exchangeability_(5,11) = 6.99394;
+exchangeability_(11,6) = 3.90697;
+exchangeability_(6,11) = 3.90697;
+exchangeability_(11,7) = 0.652336;
+exchangeability_(7,11) = 0.652336;
+exchangeability_(11,8) = 1.36581;
+exchangeability_(8,11) = 1.36581;
+exchangeability_(11,9) = 0.219252;
+exchangeability_(9,11) = 0.219252;
+exchangeability_(11,10) = 0.28848;
+exchangeability_(10,11) = 0.28848;
+exchangeability_(12,0) = 0.610604;
+exchangeability_(0,12) = 0.610604;
+exchangeability_(12,1) = 0.581287;
+exchangeability_(1,12) = 0.581287;
+exchangeability_(12,2) = 0.382156;
+exchangeability_(2,12) = 0.382156;
+exchangeability_(12,3) = 0.048508;
+exchangeability_(3,12) = 0.048508;
+exchangeability_(12,4) = 0.963147;
+exchangeability_(4,12) = 0.963147;
+exchangeability_(12,5) = 2.67289;
+exchangeability_(5,12) = 2.67289;
+exchangeability_(12,6) = 0.384585;
+exchangeability_(6,12) = 0.384585;
+exchangeability_(12,7) = 0.051334;
+exchangeability_(7,12) = 0.051334;
+exchangeability_(12,8) = 0.386066;
+exchangeability_(8,12) = 0.386066;
+exchangeability_(12,9) = 3.75229;
+exchangeability_(9,12) = 3.75229;
+exchangeability_(12,10) = 6.85853;
+exchangeability_(10,12) = 6.85853;
+exchangeability_(12,11) = 1.52445;
+exchangeability_(11,12) = 1.52445;
+exchangeability_(13,0) = 0.12467;
+exchangeability_(0,13) = 0.12467;
+exchangeability_(13,1) = 0.047666;
+exchangeability_(1,13) = 0.047666;
+exchangeability_(13,2) = 0.102656;
+exchangeability_(2,13) = 0.102656;
+exchangeability_(13,3) = 0.031532;
+exchangeability_(3,13) = 0.031532;
+exchangeability_(13,4) = 0.699124;
+exchangeability_(4,13) = 0.699124;
+exchangeability_(13,5) = 0.129867;
+exchangeability_(5,13) = 0.129867;
+exchangeability_(13,6) = 0.004923;
+exchangeability_(6,13) = 0.004923;
+exchangeability_(13,7) = 0.039185;
+exchangeability_(7,13) = 0.039185;
+exchangeability_(13,8) = 0.70169;
+exchangeability_(8,13) = 0.70169;
+exchangeability_(13,9) = 0.643782;
+exchangeability_(9,13) = 0.643782;
+exchangeability_(13,10) = 2.01947;
+exchangeability_(10,13) = 2.01947;
+exchangeability_(13,11) = 0.104308;
+exchangeability_(11,13) = 0.104308;
+exchangeability_(13,12) = 1.56825;
+exchangeability_(12,13) = 1.56825;
+exchangeability_(14,0) = 1.12639;
+exchangeability_(0,14) = 1.12639;
+exchangeability_(14,1) = 0.321347;
+exchangeability_(1,14) = 0.321347;
+exchangeability_(14,2) = 0.107738;
+exchangeability_(2,14) = 0.107738;
+exchangeability_(14,3) = 0.137858;
+exchangeability_(3,14) = 0.137858;
+exchangeability_(14,4) = 0.150346;
+exchangeability_(4,14) = 0.150346;
+exchangeability_(14,5) = 0.601413;
+exchangeability_(5,14) = 0.601413;
+exchangeability_(14,6) = 0.310374;
+exchangeability_(6,14) = 0.310374;
+exchangeability_(14,7) = 0.073794;
+exchangeability_(7,14) = 0.073794;
+exchangeability_(14,8) = 0.33291;
+exchangeability_(8,14) = 0.33291;
+exchangeability_(14,9) = 0.05623;
+exchangeability_(9,14) = 0.05623;
+exchangeability_(14,10) = 0.208204;
+exchangeability_(10,14) = 0.208204;
+exchangeability_(14,11) = 0.368816;
+exchangeability_(11,14) = 0.368816;
+exchangeability_(14,12) = 0.078902;
+exchangeability_(12,14) = 0.078902;
+exchangeability_(14,13) = 0.06241;
+exchangeability_(13,14) = 0.06241;
+exchangeability_(15,0) = 5.90855;
+exchangeability_(0,15) = 5.90855;
+exchangeability_(15,1) = 0.834735;
+exchangeability_(1,15) = 0.834735;
+exchangeability_(15,2) = 3.61159;
+exchangeability_(2,15) = 3.61159;
+exchangeability_(15,3) = 0.969189;
+exchangeability_(3,15) = 0.969189;
+exchangeability_(15,4) = 4.76587;
+exchangeability_(4,15) = 4.76587;
+exchangeability_(15,5) = 0.881934;
+exchangeability_(5,15) = 0.881934;
+exchangeability_(15,6) = 0.528944;
+exchangeability_(6,15) = 0.528944;
+exchangeability_(15,7) = 1.43931;
+exchangeability_(7,15) = 1.43931;
+exchangeability_(15,8) = 0.746876;
+exchangeability_(8,15) = 0.746876;
+exchangeability_(15,9) = 0.060111;
+exchangeability_(9,15) = 0.060111;
+exchangeability_(15,10) = 0.114374;
+exchangeability_(10,15) = 0.114374;
+exchangeability_(15,11) = 0.784754;
+exchangeability_(11,15) = 0.784754;
+exchangeability_(15,12) = 0.235963;
+exchangeability_(12,15) = 0.235963;
+exchangeability_(15,13) = 0.219009;
+exchangeability_(13,15) = 0.219009;
+exchangeability_(15,14) = 0.7101;
+exchangeability_(14,15) = 0.7101;
+exchangeability_(16,0) = 1.85638;
+exchangeability_(0,16) = 1.85638;
+exchangeability_(16,1) = 0.574277;
+exchangeability_(1,16) = 0.574277;
+exchangeability_(16,2) = 1.57358;
+exchangeability_(2,16) = 1.57358;
+exchangeability_(16,3) = 0.223054;
+exchangeability_(3,16) = 0.223054;
+exchangeability_(16,4) = 2.03879;
+exchangeability_(4,16) = 2.03879;
+exchangeability_(16,5) = 0.763848;
+exchangeability_(5,16) = 0.763848;
+exchangeability_(16,6) = 0.461329;
+exchangeability_(6,16) = 0.461329;
+exchangeability_(16,7) = 0.076195;
+exchangeability_(7,16) = 0.076195;
+exchangeability_(16,8) = 0.396095;
+exchangeability_(8,16) = 0.396095;
+exchangeability_(16,9) = 0.701247;
+exchangeability_(9,16) = 0.701247;
+exchangeability_(16,10) = 0.249302;
+exchangeability_(10,16) = 0.249302;
+exchangeability_(16,11) = 1.09132;
+exchangeability_(11,16) = 1.09132;
+exchangeability_(16,12) = 1.28264;
+exchangeability_(12,16) = 1.28264;
+exchangeability_(16,13) = 0.070553;
+exchangeability_(13,16) = 0.070553;
+exchangeability_(16,14) = 0.41907;
+exchangeability_(14,16) = 0.41907;
+exchangeability_(16,15) = 6.61698;
+exchangeability_(15,16) = 6.61698;
+exchangeability_(17,0) = 0.069294;
+exchangeability_(0,17) = 0.069294;
+exchangeability_(17,1) = 0.654056;
+exchangeability_(1,17) = 0.654056;
+exchangeability_(17,2) = 0.127255;
+exchangeability_(2,17) = 0.127255;
+exchangeability_(17,3) = 0.078896;
+exchangeability_(3,17) = 0.078896;
+exchangeability_(17,4) = 0.517561;
+exchangeability_(4,17) = 0.517561;
+exchangeability_(17,5) = 0.188732;
+exchangeability_(5,17) = 0.188732;
+exchangeability_(17,6) = 0.125541;
+exchangeability_(6,17) = 0.125541;
+exchangeability_(17,7) = 0.104279;
+exchangeability_(7,17) = 0.104279;
+exchangeability_(17,8) = 0.547504;
+exchangeability_(8,17) = 0.547504;
+exchangeability_(17,9) = 0.066927;
+exchangeability_(9,17) = 0.066927;
+exchangeability_(17,10) = 0.454998;
+exchangeability_(10,17) = 0.454998;
+exchangeability_(17,11) = 0.056498;
+exchangeability_(11,17) = 0.056498;
+exchangeability_(17,12) = 0.425274;
+exchangeability_(12,17) = 0.425274;
+exchangeability_(17,13) = 2.66884;
+exchangeability_(13,17) = 2.66884;
+exchangeability_(17,14) = 0.050943;
+exchangeability_(14,17) = 0.050943;
+exchangeability_(17,15) = 0.151483;
+exchangeability_(15,17) = 0.151483;
+exchangeability_(17,16) = 0.062698;
+exchangeability_(16,17) = 0.062698;
+exchangeability_(18,0) = 0.128158;
+exchangeability_(0,18) = 0.128158;
+exchangeability_(18,1) = 0.354167;
+exchangeability_(1,18) = 0.354167;
+exchangeability_(18,2) = 0.64014;
+exchangeability_(2,18) = 0.64014;
+exchangeability_(18,3) = 0.182565;
+exchangeability_(3,18) = 0.182565;
+exchangeability_(18,4) = 0.79399;
+exchangeability_(4,18) = 0.79399;
+exchangeability_(18,5) = 0.368725;
+exchangeability_(5,18) = 0.368725;
+exchangeability_(18,6) = 0.157796;
+exchangeability_(6,18) = 0.157796;
+exchangeability_(18,7) = 0.037084;
+exchangeability_(7,18) = 0.037084;
+exchangeability_(18,8) = 4.30714;
+exchangeability_(8,18) = 4.30714;
+exchangeability_(18,9) = 0.140691;
+exchangeability_(9,18) = 0.140691;
+exchangeability_(18,10) = 0.241076;
+exchangeability_(10,18) = 0.241076;
+exchangeability_(18,11) = 0.323966;
+exchangeability_(11,18) = 0.323966;
+exchangeability_(18,12) = 0.293629;
+exchangeability_(12,18) = 0.293629;
+exchangeability_(18,13) = 9.71141;
+exchangeability_(13,18) = 9.71141;
+exchangeability_(18,14) = 0.060323;
+exchangeability_(14,18) = 0.060323;
+exchangeability_(18,15) = 0.207489;
+exchangeability_(15,18) = 0.207489;
+exchangeability_(18,16) = 0.111492;
+exchangeability_(16,18) = 0.111492;
+exchangeability_(18,17) = 2.85745;
+exchangeability_(17,18) = 2.85745;
+exchangeability_(19,0) = 1.98276;
+exchangeability_(0,19) = 1.98276;
+exchangeability_(19,1) = 0.158227;
+exchangeability_(1,19) = 0.158227;
+exchangeability_(19,2) = 0.115545;
+exchangeability_(2,19) = 0.115545;
+exchangeability_(19,3) = 0.051117;
+exchangeability_(3,19) = 0.051117;
+exchangeability_(19,4) = 2.0659;
+exchangeability_(4,19) = 2.0659;
+exchangeability_(19,5) = 0.338262;
+exchangeability_(5,19) = 0.338262;
+exchangeability_(19,6) = 0.258245;
+exchangeability_(6,19) = 0.258245;
+exchangeability_(19,7) = 0.04577;
+exchangeability_(7,19) = 0.04577;
+exchangeability_(19,8) = 0.089942;
+exchangeability_(8,19) = 0.089942;
+exchangeability_(19,9) = 10.1131;
+exchangeability_(9,19) = 10.1131;
+exchangeability_(19,10) = 1.38202;
+exchangeability_(10,19) = 1.38202;
+exchangeability_(19,11) = 0.431385;
+exchangeability_(11,19) = 0.431385;
+exchangeability_(19,12) = 1.45661;
+exchangeability_(12,19) = 1.45661;
+exchangeability_(19,13) = 0.295718;
+exchangeability_(13,19) = 0.295718;
+exchangeability_(19,14) = 0.273919;
+exchangeability_(14,19) = 0.273919;
+exchangeability_(19,15) = 0.066465;
+exchangeability_(15,19) = 0.066465;
+exchangeability_(19,16) = 1.66806;
+exchangeability_(16,19) = 1.66806;
+exchangeability_(19,17) = 0.113899;
+exchangeability_(17,19) = 0.113899;
+exchangeability_(19,18) = 0.144981;
+exchangeability_(18,19) = 0.144981;
+exchangeability_(0,0) = -20.9159;
+exchangeability_(1,1) = -32.8246;
+exchangeability_(2,2) = -24.9422;
+exchangeability_(3,3) = -18.3186;
+exchangeability_(4,4) = -20.0883;
+exchangeability_(5,5) = -38.4521;
+exchangeability_(6,6) = -27.2824;
+exchangeability_(7,7) = -7.95505;
+exchangeability_(8,8) = -27.5138;
+exchangeability_(9,9) = -20.0325;
+exchangeability_(10,10) = -17.6546;
+exchangeability_(11,11) = -40.5574;
+exchangeability_(12,12) = -23.5571;
+exchangeability_(13,13) = -19.2451;
+exchangeability_(14,14) = -5.45108;
+exchangeability_(15,15) = -28.8537;
+exchangeability_(16,16) = -20.2369;
+exchangeability_(17,17) = -9.32212;
+exchangeability_(18,18) = -21.0623;
+exchangeability_(19,19) = -21.052;
+}
+
+
+if (getName()=="EXP_EXT" || getName()=="EXP_EXT+F"){
+exchangeability_(1,0) = 0.464716;
+exchangeability_(0,1) = 0.464716;
+exchangeability_(2,0) = 0.597009;
+exchangeability_(0,2) = 0.597009;
+exchangeability_(2,1) = 0.420578;
+exchangeability_(1,2) = 0.420578;
+exchangeability_(3,0) = 1.01069;
+exchangeability_(0,3) = 1.01069;
+exchangeability_(3,1) = 0.048553;
+exchangeability_(1,3) = 0.048553;
+exchangeability_(3,2) = 5.94429;
+exchangeability_(2,3) = 5.94429;
+exchangeability_(4,0) = 3.91583;
+exchangeability_(0,4) = 3.91583;
+exchangeability_(4,1) = 2.08824;
+exchangeability_(1,4) = 2.08824;
+exchangeability_(4,2) = 0.878468;
+exchangeability_(2,4) = 0.878468;
+exchangeability_(4,3) = 0.236108;
+exchangeability_(3,4) = 0.236108;
+exchangeability_(5,0) = 1.15602;
+exchangeability_(0,5) = 1.15602;
+exchangeability_(5,1) = 1.88232;
+exchangeability_(1,5) = 1.88232;
+exchangeability_(5,2) = 1.43593;
+exchangeability_(2,5) = 1.43593;
+exchangeability_(5,3) = 0.338823;
+exchangeability_(3,5) = 0.338823;
+exchangeability_(5,4) = 0.482742;
+exchangeability_(4,5) = 0.482742;
+exchangeability_(6,0) = 1.1311;
+exchangeability_(0,6) = 1.1311;
+exchangeability_(6,1) = 0.12715;
+exchangeability_(1,6) = 0.12715;
+exchangeability_(6,2) = 0.346338;
+exchangeability_(2,6) = 0.346338;
+exchangeability_(6,3) = 3.31719;
+exchangeability_(3,6) = 3.31719;
+exchangeability_(6,4) = 0.06106;
+exchangeability_(4,6) = 0.06106;
+exchangeability_(6,5) = 2.7247;
+exchangeability_(5,6) = 2.7247;
+exchangeability_(7,0) = 4.63866;
+exchangeability_(0,7) = 4.63866;
+exchangeability_(7,1) = 0.351041;
+exchangeability_(1,7) = 0.351041;
+exchangeability_(7,2) = 1.37917;
+exchangeability_(2,7) = 1.37917;
+exchangeability_(7,3) = 1.21652;
+exchangeability_(3,7) = 1.21652;
+exchangeability_(7,4) = 1.39605;
+exchangeability_(4,7) = 1.39605;
+exchangeability_(7,5) = 0.199361;
+exchangeability_(5,7) = 0.199361;
+exchangeability_(7,6) = 0.35397;
+exchangeability_(6,7) = 0.35397;
+exchangeability_(8,0) = 0.657615;
+exchangeability_(0,8) = 0.657615;
+exchangeability_(8,1) = 2.21599;
+exchangeability_(1,8) = 2.21599;
+exchangeability_(8,2) = 4.15025;
+exchangeability_(2,8) = 4.15025;
+exchangeability_(8,3) = 0.717363;
+exchangeability_(3,8) = 0.717363;
+exchangeability_(8,4) = 1.85397;
+exchangeability_(4,8) = 1.85397;
+exchangeability_(8,5) = 3.76886;
+exchangeability_(5,8) = 3.76886;
+exchangeability_(8,6) = 0.347165;
+exchangeability_(6,8) = 0.347165;
+exchangeability_(8,7) = 0.313421;
+exchangeability_(7,8) = 0.313421;
+exchangeability_(9,0) = 0.078558;
+exchangeability_(0,9) = 0.078558;
+exchangeability_(9,1) = 0.127092;
+exchangeability_(1,9) = 0.127092;
+exchangeability_(9,2) = 0.347281;
+exchangeability_(2,9) = 0.347281;
+exchangeability_(9,3) = 0.032361;
+exchangeability_(3,9) = 0.032361;
+exchangeability_(9,4) = 0.605448;
+exchangeability_(4,9) = 0.605448;
+exchangeability_(9,5) = 0.171553;
+exchangeability_(5,9) = 0.171553;
+exchangeability_(9,6) = 0.104678;
+exchangeability_(6,9) = 0.104678;
+exchangeability_(9,7) = 0.010608;
+exchangeability_(7,9) = 0.010608;
+exchangeability_(9,8) = 0.309418;
+exchangeability_(8,9) = 0.309418;
+exchangeability_(10,0) = 0.516672;
+exchangeability_(0,10) = 0.516672;
+exchangeability_(10,1) = 0.510585;
+exchangeability_(1,10) = 0.510585;
+exchangeability_(10,2) = 0.105529;
+exchangeability_(2,10) = 0.105529;
+exchangeability_(10,3) = 0.039188;
+exchangeability_(3,10) = 0.039188;
+exchangeability_(10,4) = 1.80827;
+exchangeability_(4,10) = 1.80827;
+exchangeability_(10,5) = 1.01758;
+exchangeability_(5,10) = 1.01758;
+exchangeability_(10,6) = 0.11201;
+exchangeability_(6,10) = 0.11201;
+exchangeability_(10,7) = 0.044661;
+exchangeability_(7,10) = 0.044661;
+exchangeability_(10,8) = 0.772131;
+exchangeability_(8,10) = 0.772131;
+exchangeability_(10,9) = 5.6931;
+exchangeability_(9,10) = 5.6931;
+exchangeability_(11,0) = 0.519389;
+exchangeability_(0,11) = 0.519389;
+exchangeability_(11,1) = 3.5711;
+exchangeability_(1,11) = 3.5711;
+exchangeability_(11,2) = 1.84405;
+exchangeability_(2,11) = 1.84405;
+exchangeability_(11,3) = 0.109305;
+exchangeability_(3,11) = 0.109305;
+exchangeability_(11,4) = 0.103105;
+exchangeability_(4,11) = 0.103105;
+exchangeability_(11,5) = 2.23275;
+exchangeability_(5,11) = 2.23275;
+exchangeability_(11,6) = 0.653339;
+exchangeability_(6,11) = 0.653339;
+exchangeability_(11,7) = 0.195325;
+exchangeability_(7,11) = 0.195325;
+exchangeability_(11,8) = 0.547017;
+exchangeability_(8,11) = 0.547017;
+exchangeability_(11,9) = 0.219311;
+exchangeability_(9,11) = 0.219311;
+exchangeability_(11,10) = 0.253086;
+exchangeability_(10,11) = 0.253086;
+exchangeability_(12,0) = 1.65826;
+exchangeability_(0,12) = 1.65826;
+exchangeability_(12,1) = 0.640712;
+exchangeability_(1,12) = 0.640712;
+exchangeability_(12,2) = 0.558751;
+exchangeability_(2,12) = 0.558751;
+exchangeability_(12,3) = 0.063591;
+exchangeability_(3,12) = 0.063591;
+exchangeability_(12,4) = 1.69488;
+exchangeability_(4,12) = 1.69488;
+exchangeability_(12,5) = 2.08844;
+exchangeability_(5,12) = 2.08844;
+exchangeability_(12,6) = 0.194697;
+exchangeability_(6,12) = 0.194697;
+exchangeability_(12,7) = 0.291701;
+exchangeability_(7,12) = 0.291701;
+exchangeability_(12,8) = 0.321392;
+exchangeability_(8,12) = 0.321392;
+exchangeability_(12,9) = 6.22046;
+exchangeability_(9,12) = 6.22046;
+exchangeability_(12,10) = 12.3926;
+exchangeability_(10,12) = 12.3926;
+exchangeability_(12,11) = 0.862547;
+exchangeability_(11,12) = 0.862547;
+exchangeability_(13,0) = 0.426071;
+exchangeability_(0,13) = 0.426071;
+exchangeability_(13,1) = 0.064894;
+exchangeability_(1,13) = 0.064894;
+exchangeability_(13,2) = 0.132019;
+exchangeability_(2,13) = 0.132019;
+exchangeability_(13,3) = 0.034872;
+exchangeability_(3,13) = 0.034872;
+exchangeability_(13,4) = 2.07657;
+exchangeability_(4,13) = 2.07657;
+exchangeability_(13,5) = 0.085745;
+exchangeability_(5,13) = 0.085745;
+exchangeability_(13,6) = 0.026972;
+exchangeability_(6,13) = 0.026972;
+exchangeability_(13,7) = 0.099963;
+exchangeability_(7,13) = 0.099963;
+exchangeability_(13,8) = 1.38825;
+exchangeability_(8,13) = 1.38825;
+exchangeability_(13,9) = 1.76529;
+exchangeability_(9,13) = 1.76529;
+exchangeability_(13,10) = 3.85964;
+exchangeability_(10,13) = 3.85964;
+exchangeability_(13,11) = 0.032198;
+exchangeability_(11,13) = 0.032198;
+exchangeability_(13,12) = 3.13411;
+exchangeability_(12,13) = 3.13411;
+exchangeability_(14,0) = 3.08273;
+exchangeability_(0,14) = 3.08273;
+exchangeability_(14,1) = 0.25047;
+exchangeability_(1,14) = 0.25047;
+exchangeability_(14,2) = 0.232578;
+exchangeability_(2,14) = 0.232578;
+exchangeability_(14,3) = 0.376163;
+exchangeability_(3,14) = 0.376163;
+exchangeability_(14,4) = 0.290522;
+exchangeability_(4,14) = 0.290522;
+exchangeability_(14,5) = 0.502379;
+exchangeability_(5,14) = 0.502379;
+exchangeability_(14,6) = 0.240501;
+exchangeability_(6,14) = 0.240501;
+exchangeability_(14,7) = 0.302007;
+exchangeability_(7,14) = 0.302007;
+exchangeability_(14,8) = 0.28395;
+exchangeability_(8,14) = 0.28395;
+exchangeability_(14,9) = 0.013574;
+exchangeability_(9,14) = 0.013574;
+exchangeability_(14,10) = 0.606936;
+exchangeability_(10,14) = 0.606936;
+exchangeability_(14,11) = 0.248475;
+exchangeability_(11,14) = 0.248475;
+exchangeability_(14,12) = 0.226716;
+exchangeability_(12,14) = 0.226716;
+exchangeability_(14,13) = 0.058246;
+exchangeability_(13,14) = 0.058246;
+exchangeability_(15,0) = 7.01288;
+exchangeability_(0,15) = 7.01288;
+exchangeability_(15,1) = 0.866957;
+exchangeability_(1,15) = 0.866957;
+exchangeability_(15,2) = 5.009;
+exchangeability_(2,15) = 5.009;
+exchangeability_(15,3) = 0.814153;
+exchangeability_(3,15) = 0.814153;
+exchangeability_(15,4) = 4.75835;
+exchangeability_(4,15) = 4.75835;
+exchangeability_(15,5) = 1.19208;
+exchangeability_(5,15) = 1.19208;
+exchangeability_(15,6) = 0.595351;
+exchangeability_(6,15) = 0.595351;
+exchangeability_(15,7) = 2.51427;
+exchangeability_(7,15) = 2.51427;
+exchangeability_(15,8) = 0.993487;
+exchangeability_(8,15) = 0.993487;
+exchangeability_(15,9) = 0.135167;
+exchangeability_(9,15) = 0.135167;
+exchangeability_(15,10) = 0.349525;
+exchangeability_(10,15) = 0.349525;
+exchangeability_(15,11) = 0.542021;
+exchangeability_(11,15) = 0.542021;
+exchangeability_(15,12) = 0.512591;
+exchangeability_(12,15) = 0.512591;
+exchangeability_(15,13) = 0.744682;
+exchangeability_(13,15) = 0.744682;
+exchangeability_(15,14) = 1.25817;
+exchangeability_(14,15) = 1.25817;
+exchangeability_(16,0) = 2.03776;
+exchangeability_(0,16) = 2.03776;
+exchangeability_(16,1) = 0.446367;
+exchangeability_(1,16) = 0.446367;
+exchangeability_(16,2) = 1.6183;
+exchangeability_(2,16) = 1.6183;
+exchangeability_(16,3) = 0.203392;
+exchangeability_(3,16) = 0.203392;
+exchangeability_(16,4) = 1.17742;
+exchangeability_(4,16) = 1.17742;
+exchangeability_(16,5) = 0.840646;
+exchangeability_(5,16) = 0.840646;
+exchangeability_(16,6) = 0.583757;
+exchangeability_(6,16) = 0.583757;
+exchangeability_(16,7) = 0.071515;
+exchangeability_(7,16) = 0.071515;
+exchangeability_(16,8) = 0.466886;
+exchangeability_(8,16) = 0.466886;
+exchangeability_(16,9) = 1.50388;
+exchangeability_(9,16) = 1.50388;
+exchangeability_(16,10) = 0.260405;
+exchangeability_(10,16) = 0.260405;
+exchangeability_(16,11) = 0.93423;
+exchangeability_(11,16) = 0.93423;
+exchangeability_(16,12) = 2.24561;
+exchangeability_(12,16) = 2.24561;
+exchangeability_(16,13) = 0.123552;
+exchangeability_(13,16) = 0.123552;
+exchangeability_(16,14) = 0.258896;
+exchangeability_(14,16) = 0.258896;
+exchangeability_(16,15) = 4.50483;
+exchangeability_(15,16) = 4.50483;
+exchangeability_(17,0) = 0.171334;
+exchangeability_(0,17) = 0.171334;
+exchangeability_(17,1) = 0.385971;
+exchangeability_(1,17) = 0.385971;
+exchangeability_(17,2) = 0.087717;
+exchangeability_(2,17) = 0.087717;
+exchangeability_(17,3) = 0.019596;
+exchangeability_(3,17) = 0.019596;
+exchangeability_(17,4) = 1.01551;
+exchangeability_(4,17) = 1.01551;
+exchangeability_(17,5) = 0.127027;
+exchangeability_(5,17) = 0.127027;
+exchangeability_(17,6) = 0.037725;
+exchangeability_(6,17) = 0.037725;
+exchangeability_(17,7) = 0.217844;
+exchangeability_(7,17) = 0.217844;
+exchangeability_(17,8) = 0.82278;
+exchangeability_(8,17) = 0.82278;
+exchangeability_(17,9) = 0.095756;
+exchangeability_(9,17) = 0.095756;
+exchangeability_(17,10) = 0.777332;
+exchangeability_(10,17) = 0.777332;
+exchangeability_(17,11) = 0.039952;
+exchangeability_(11,17) = 0.039952;
+exchangeability_(17,12) = 0.977419;
+exchangeability_(12,17) = 0.977419;
+exchangeability_(17,13) = 3.21729;
+exchangeability_(13,17) = 3.21729;
+exchangeability_(17,14) = 0.01524;
+exchangeability_(14,17) = 0.01524;
+exchangeability_(17,15) = 0.301259;
+exchangeability_(15,17) = 0.301259;
+exchangeability_(17,16) = 0.102153;
+exchangeability_(16,17) = 0.102153;
+exchangeability_(18,0) = 0.194998;
+exchangeability_(0,18) = 0.194998;
+exchangeability_(18,1) = 0.091803;
+exchangeability_(1,18) = 0.091803;
+exchangeability_(18,2) = 0.433021;
+exchangeability_(2,18) = 0.433021;
+exchangeability_(18,3) = 0.086495;
+exchangeability_(3,18) = 0.086495;
+exchangeability_(18,4) = 3.07488;
+exchangeability_(4,18) = 3.07488;
+exchangeability_(18,5) = 0.111578;
+exchangeability_(5,18) = 0.111578;
+exchangeability_(18,6) = 0.041481;
+exchangeability_(6,18) = 0.041481;
+exchangeability_(18,7) = 0.048438;
+exchangeability_(7,18) = 0.048438;
+exchangeability_(18,8) = 4.90479;
+exchangeability_(8,18) = 4.90479;
+exchangeability_(18,9) = 0.336528;
+exchangeability_(9,18) = 0.336528;
+exchangeability_(18,10) = 0.411742;
+exchangeability_(10,18) = 0.411742;
+exchangeability_(18,11) = 0.087476;
+exchangeability_(11,18) = 0.087476;
+exchangeability_(18,12) = 0.640594;
+exchangeability_(12,18) = 0.640594;
+exchangeability_(18,13) = 14.1268;
+exchangeability_(13,18) = 14.1268;
+exchangeability_(18,14) = 0.061656;
+exchangeability_(14,18) = 0.061656;
+exchangeability_(18,15) = 0.338111;
+exchangeability_(15,18) = 0.338111;
+exchangeability_(18,16) = 0.129249;
+exchangeability_(16,18) = 0.129249;
+exchangeability_(18,17) = 2.90214;
+exchangeability_(17,18) = 2.90214;
+exchangeability_(19,0) = 2.81139;
+exchangeability_(0,19) = 2.81139;
+exchangeability_(19,1) = 0.216605;
+exchangeability_(1,19) = 0.216605;
+exchangeability_(19,2) = 0.12724;
+exchangeability_(2,19) = 0.12724;
+exchangeability_(19,3) = 0.061503;
+exchangeability_(3,19) = 0.061503;
+exchangeability_(19,4) = 2.32027;
+exchangeability_(4,19) = 2.32027;
+exchangeability_(19,5) = 0.390874;
+exchangeability_(5,19) = 0.390874;
+exchangeability_(19,6) = 0.450783;
+exchangeability_(6,19) = 0.450783;
+exchangeability_(19,7) = 0.132513;
+exchangeability_(7,19) = 0.132513;
+exchangeability_(19,8) = 0.234279;
+exchangeability_(8,19) = 0.234279;
+exchangeability_(19,9) = 12.1814;
+exchangeability_(9,19) = 12.1814;
+exchangeability_(19,10) = 2.53951;
+exchangeability_(10,19) = 2.53951;
+exchangeability_(19,11) = 0.233848;
+exchangeability_(11,19) = 0.233848;
+exchangeability_(19,12) = 3.36316;
+exchangeability_(12,19) = 3.36316;
+exchangeability_(19,13) = 0.717467;
+exchangeability_(13,19) = 0.717467;
+exchangeability_(19,14) = 0.138035;
+exchangeability_(14,19) = 0.138035;
+exchangeability_(19,15) = 0.159602;
+exchangeability_(15,19) = 0.159602;
+exchangeability_(19,16) = 1.61537;
+exchangeability_(16,19) = 1.61537;
+exchangeability_(19,17) = 0.132268;
+exchangeability_(17,19) = 0.132268;
+exchangeability_(19,18) = 0.186175;
+exchangeability_(18,19) = 0.186175;
+exchangeability_(0,0) = -32.0817;
+exchangeability_(1,1) = -14.7711;
+exchangeability_(2,2) = -25.6475;
+exchangeability_(3,3) = -14.6702;
+exchangeability_(4,4) = -29.8377;
+exchangeability_(5,5) = -20.7494;
+exchangeability_(6,6) = -11.45;
+exchangeability_(7,7) = -13.777;
+exchangeability_(8,8) = -25.069;
+exchangeability_(9,9) = -29.9514;
+exchangeability_(10,10) = -32.0705;
+exchangeability_(11,11) = -13.2285;
+exchangeability_(12,12) = -38.0882;
+exchangeability_(13,13) = -32.1147;
+exchangeability_(14,14) = -8.44724;
+exchangeability_(15,15) = -32.6025;
+exchangeability_(16,16) = -19.1242;
+exchangeability_(17,17) = -11.4463;
+exchangeability_(18,18) = -28.208;
+exchangeability_(19,19) = -28.0122;
+}
+
+
+if (getName()=="EXP_HEL" || getName()=="EXP_HEL+F"){
+exchangeability_(1,0) = 0.434227;
+exchangeability_(0,1) = 0.434227;
+exchangeability_(2,0) = 0.551823;
+exchangeability_(0,2) = 0.551823;
+exchangeability_(2,1) = 0.569806;
+exchangeability_(1,2) = 0.569806;
+exchangeability_(3,0) = 0.698268;
+exchangeability_(0,3) = 0.698268;
+exchangeability_(3,1) = 0.056291;
+exchangeability_(1,3) = 0.056291;
+exchangeability_(3,2) = 3.06431;
+exchangeability_(2,3) = 3.06431;
+exchangeability_(4,0) = 2.026;
+exchangeability_(0,4) = 2.026;
+exchangeability_(4,1) = 2.3792;
+exchangeability_(1,4) = 2.3792;
+exchangeability_(4,2) = 1.07728;
+exchangeability_(2,4) = 1.07728;
+exchangeability_(4,3) = 0.016649;
+exchangeability_(3,4) = 0.016649;
+exchangeability_(5,0) = 0.986617;
+exchangeability_(0,5) = 0.986617;
+exchangeability_(5,1) = 1.60628;
+exchangeability_(1,5) = 1.60628;
+exchangeability_(5,2) = 1.33157;
+exchangeability_(2,5) = 1.33157;
+exchangeability_(5,3) = 0.426399;
+exchangeability_(3,5) = 0.426399;
+exchangeability_(5,4) = 0.409724;
+exchangeability_(4,5) = 0.409724;
+exchangeability_(6,0) = 1.00594;
+exchangeability_(0,6) = 1.00594;
+exchangeability_(6,1) = 0.120122;
+exchangeability_(1,6) = 0.120122;
+exchangeability_(6,2) = 0.390888;
+exchangeability_(2,6) = 0.390888;
+exchangeability_(6,3) = 2.99974;
+exchangeability_(3,6) = 2.99974;
+exchangeability_(6,4) = 0.021217;
+exchangeability_(4,6) = 0.021217;
+exchangeability_(6,5) = 1.88116;
+exchangeability_(5,6) = 1.88116;
+exchangeability_(7,0) = 3.2212;
+exchangeability_(0,7) = 3.2212;
+exchangeability_(7,1) = 0.736168;
+exchangeability_(1,7) = 0.736168;
+exchangeability_(7,2) = 2.26962;
+exchangeability_(2,7) = 2.26962;
+exchangeability_(7,3) = 1.27289;
+exchangeability_(3,7) = 1.27289;
+exchangeability_(7,4) = 1.77171;
+exchangeability_(4,7) = 1.77171;
+exchangeability_(7,5) = 0.62243;
+exchangeability_(5,7) = 0.62243;
+exchangeability_(7,6) = 0.656603;
+exchangeability_(6,7) = 0.656603;
+exchangeability_(8,0) = 0.515574;
+exchangeability_(0,8) = 0.515574;
+exchangeability_(8,1) = 2.03257;
+exchangeability_(1,8) = 2.03257;
+exchangeability_(8,2) = 5.485;
+exchangeability_(2,8) = 5.485;
+exchangeability_(8,3) = 0.666491;
+exchangeability_(3,8) = 0.666491;
+exchangeability_(8,4) = 2.98555;
+exchangeability_(4,8) = 2.98555;
+exchangeability_(8,5) = 3.38053;
+exchangeability_(5,8) = 3.38053;
+exchangeability_(8,6) = 0.265244;
+exchangeability_(6,8) = 0.265244;
+exchangeability_(8,7) = 0.557878;
+exchangeability_(7,8) = 0.557878;
+exchangeability_(9,0) = 0.20081;
+exchangeability_(0,9) = 0.20081;
+exchangeability_(9,1) = 0.241566;
+exchangeability_(1,9) = 0.241566;
+exchangeability_(9,2) = 0.441585;
+exchangeability_(2,9) = 0.441585;
+exchangeability_(9,3) = 0.00983;
+exchangeability_(3,9) = 0.00983;
+exchangeability_(9,4) = 1.5412;
+exchangeability_(4,9) = 1.5412;
+exchangeability_(9,5) = 0.198621;
+exchangeability_(5,9) = 0.198621;
+exchangeability_(9,6) = 0.069562;
+exchangeability_(6,9) = 0.069562;
+exchangeability_(9,7) = 0.043838;
+exchangeability_(7,9) = 0.043838;
+exchangeability_(9,8) = 0.339616;
+exchangeability_(8,9) = 0.339616;
+exchangeability_(10,0) = 0.328669;
+exchangeability_(0,10) = 0.328669;
+exchangeability_(10,1) = 0.583849;
+exchangeability_(1,10) = 0.583849;
+exchangeability_(10,2) = 0.178015;
+exchangeability_(2,10) = 0.178015;
+exchangeability_(10,3) = 0.022077;
+exchangeability_(3,10) = 0.022077;
+exchangeability_(10,4) = 2.0454;
+exchangeability_(4,10) = 2.0454;
+exchangeability_(10,5) = 1.04612;
+exchangeability_(5,10) = 1.04612;
+exchangeability_(10,6) = 0.089148;
+exchangeability_(6,10) = 0.089148;
+exchangeability_(10,7) = 0.104708;
+exchangeability_(7,10) = 0.104708;
+exchangeability_(10,8) = 0.875298;
+exchangeability_(8,10) = 0.875298;
+exchangeability_(10,9) = 8.62824;
+exchangeability_(9,10) = 8.62824;
+exchangeability_(11,0) = 0.598864;
+exchangeability_(0,11) = 0.598864;
+exchangeability_(11,1) = 3.09026;
+exchangeability_(1,11) = 3.09026;
+exchangeability_(11,2) = 1.68241;
+exchangeability_(2,11) = 1.68241;
+exchangeability_(11,3) = 0.113637;
+exchangeability_(3,11) = 0.113637;
+exchangeability_(11,4) = 0.207957;
+exchangeability_(4,11) = 0.207957;
+exchangeability_(11,5) = 2.08525;
+exchangeability_(5,11) = 2.08525;
+exchangeability_(11,6) = 0.582536;
+exchangeability_(6,11) = 0.582536;
+exchangeability_(11,7) = 0.376534;
+exchangeability_(7,11) = 0.376534;
+exchangeability_(11,8) = 0.554395;
+exchangeability_(8,11) = 0.554395;
+exchangeability_(11,9) = 0.371883;
+exchangeability_(9,11) = 0.371883;
+exchangeability_(11,10) = 0.290692;
+exchangeability_(10,11) = 0.290692;
+exchangeability_(12,0) = 0.799278;
+exchangeability_(0,12) = 0.799278;
+exchangeability_(12,1) = 0.528354;
+exchangeability_(1,12) = 0.528354;
+exchangeability_(12,2) = 0.704087;
+exchangeability_(2,12) = 0.704087;
+exchangeability_(12,3) = 0.06229;
+exchangeability_(3,12) = 0.06229;
+exchangeability_(12,4) = 2.30385;
+exchangeability_(4,12) = 2.30385;
+exchangeability_(12,5) = 1.50762;
+exchangeability_(5,12) = 1.50762;
+exchangeability_(12,6) = 0.173293;
+exchangeability_(6,12) = 0.173293;
+exchangeability_(12,7) = 0.35658;
+exchangeability_(7,12) = 0.35658;
+exchangeability_(12,8) = 0.492228;
+exchangeability_(8,12) = 0.492228;
+exchangeability_(12,9) = 10.0285;
+exchangeability_(9,12) = 10.0285;
+exchangeability_(12,10) = 12.1627;
+exchangeability_(10,12) = 12.1627;
+exchangeability_(12,11) = 0.867109;
+exchangeability_(11,12) = 0.867109;
+exchangeability_(13,0) = 0.256227;
+exchangeability_(0,13) = 0.256227;
+exchangeability_(13,1) = 0.083117;
+exchangeability_(1,13) = 0.083117;
+exchangeability_(13,2) = 0.192262;
+exchangeability_(2,13) = 0.192262;
+exchangeability_(13,3) = 0.030759;
+exchangeability_(3,13) = 0.030759;
+exchangeability_(13,4) = 4.32895;
+exchangeability_(4,13) = 4.32895;
+exchangeability_(13,5) = 0.078062;
+exchangeability_(5,13) = 0.078062;
+exchangeability_(13,6) = 0.02289;
+exchangeability_(6,13) = 0.02289;
+exchangeability_(13,7) = 0.181917;
+exchangeability_(7,13) = 0.181917;
+exchangeability_(13,8) = 2.40682;
+exchangeability_(8,13) = 2.40682;
+exchangeability_(13,9) = 2.01478;
+exchangeability_(9,13) = 2.01478;
+exchangeability_(13,10) = 4.85694;
+exchangeability_(10,13) = 4.85694;
+exchangeability_(13,11) = 0.041675;
+exchangeability_(11,13) = 0.041675;
+exchangeability_(13,12) = 3.52123;
+exchangeability_(12,13) = 3.52123;
+exchangeability_(14,0) = 1.11884;
+exchangeability_(0,14) = 1.11884;
+exchangeability_(14,1) = 0.147481;
+exchangeability_(1,14) = 0.147481;
+exchangeability_(14,2) = 0.061969;
+exchangeability_(2,14) = 0.061969;
+exchangeability_(14,3) = 0.323498;
+exchangeability_(3,14) = 0.323498;
+exchangeability_(14,4) = 0.171678;
+exchangeability_(4,14) = 0.171678;
+exchangeability_(14,5) = 0.387521;
+exchangeability_(5,14) = 0.387521;
+exchangeability_(14,6) = 0.237715;
+exchangeability_(6,14) = 0.237715;
+exchangeability_(14,7) = 0.641036;
+exchangeability_(7,14) = 0.641036;
+exchangeability_(14,8) = 0.433529;
+exchangeability_(8,14) = 0.433529;
+exchangeability_(14,9) = 0.069102;
+exchangeability_(9,14) = 0.069102;
+exchangeability_(14,10) = 0.359935;
+exchangeability_(10,14) = 0.359935;
+exchangeability_(14,11) = 0.164055;
+exchangeability_(11,14) = 0.164055;
+exchangeability_(14,12) = 0.063832;
+exchangeability_(12,14) = 0.063832;
+exchangeability_(14,13) = 0.126592;
+exchangeability_(13,14) = 0.126592;
+exchangeability_(15,0) = 5.06905;
+exchangeability_(0,15) = 5.06905;
+exchangeability_(15,1) = 0.749554;
+exchangeability_(1,15) = 0.749554;
+exchangeability_(15,2) = 5.24549;
+exchangeability_(2,15) = 5.24549;
+exchangeability_(15,3) = 0.840686;
+exchangeability_(3,15) = 0.840686;
+exchangeability_(15,4) = 7.11453;
+exchangeability_(4,15) = 7.11453;
+exchangeability_(15,5) = 1.1778;
+exchangeability_(5,15) = 1.1778;
+exchangeability_(15,6) = 0.382956;
+exchangeability_(6,15) = 0.382956;
+exchangeability_(15,7) = 6.13984;
+exchangeability_(7,15) = 6.13984;
+exchangeability_(15,8) = 1.08678;
+exchangeability_(8,15) = 1.08678;
+exchangeability_(15,9) = 0.194824;
+exchangeability_(9,15) = 0.194824;
+exchangeability_(15,10) = 0.424579;
+exchangeability_(10,15) = 0.424579;
+exchangeability_(15,11) = 0.655759;
+exchangeability_(11,15) = 0.655759;
+exchangeability_(15,12) = 0.682174;
+exchangeability_(12,15) = 0.682174;
+exchangeability_(15,13) = 0.753148;
+exchangeability_(13,15) = 0.753148;
+exchangeability_(15,14) = 1.35581;
+exchangeability_(14,15) = 1.35581;
+exchangeability_(16,0) = 2.94974;
+exchangeability_(0,16) = 2.94974;
+exchangeability_(16,1) = 0.623328;
+exchangeability_(1,16) = 0.623328;
+exchangeability_(16,2) = 3.24888;
+exchangeability_(2,16) = 3.24888;
+exchangeability_(16,3) = 0.406219;
+exchangeability_(3,16) = 0.406219;
+exchangeability_(16,4) = 3.34574;
+exchangeability_(4,16) = 3.34574;
+exchangeability_(16,5) = 1.21428;
+exchangeability_(5,16) = 1.21428;
+exchangeability_(16,6) = 0.538553;
+exchangeability_(6,16) = 0.538553;
+exchangeability_(16,7) = 0.867954;
+exchangeability_(7,16) = 0.867954;
+exchangeability_(16,8) = 0.747654;
+exchangeability_(8,16) = 0.747654;
+exchangeability_(16,9) = 3.31635;
+exchangeability_(9,16) = 3.31635;
+exchangeability_(16,10) = 0.754081;
+exchangeability_(10,16) = 0.754081;
+exchangeability_(16,11) = 1.19359;
+exchangeability_(11,16) = 1.19359;
+exchangeability_(16,12) = 3.51648;
+exchangeability_(12,16) = 3.51648;
+exchangeability_(16,13) = 0.366653;
+exchangeability_(13,16) = 0.366653;
+exchangeability_(16,14) = 0.622665;
+exchangeability_(14,16) = 0.622665;
+exchangeability_(16,15) = 7.97565;
+exchangeability_(15,16) = 7.97565;
+exchangeability_(17,0) = 0.115446;
+exchangeability_(0,17) = 0.115446;
+exchangeability_(17,1) = 0.394156;
+exchangeability_(1,17) = 0.394156;
+exchangeability_(17,2) = 0.090971;
+exchangeability_(2,17) = 0.090971;
+exchangeability_(17,3) = 0.055309;
+exchangeability_(3,17) = 0.055309;
+exchangeability_(17,4) = 1.94785;
+exchangeability_(4,17) = 1.94785;
+exchangeability_(17,5) = 0.185912;
+exchangeability_(5,17) = 0.185912;
+exchangeability_(17,6) = 0.046886;
+exchangeability_(6,17) = 0.046886;
+exchangeability_(17,7) = 0.451084;
+exchangeability_(7,17) = 0.451084;
+exchangeability_(17,8) = 1.17301;
+exchangeability_(8,17) = 1.17301;
+exchangeability_(17,9) = 0.277029;
+exchangeability_(9,17) = 0.277029;
+exchangeability_(17,10) = 1.07878;
+exchangeability_(10,17) = 1.07878;
+exchangeability_(17,11) = 0.054622;
+exchangeability_(11,17) = 0.054622;
+exchangeability_(17,12) = 1.51624;
+exchangeability_(12,17) = 1.51624;
+exchangeability_(17,13) = 5.81353;
+exchangeability_(13,17) = 5.81353;
+exchangeability_(17,14) = 0.071865;
+exchangeability_(14,17) = 0.071865;
+exchangeability_(17,15) = 0.359167;
+exchangeability_(15,17) = 0.359167;
+exchangeability_(17,16) = 0.106921;
+exchangeability_(16,17) = 0.106921;
+exchangeability_(18,0) = 0.20568;
+exchangeability_(0,18) = 0.20568;
+exchangeability_(18,1) = 0.197878;
+exchangeability_(1,18) = 0.197878;
+exchangeability_(18,2) = 0.678775;
+exchangeability_(2,18) = 0.678775;
+exchangeability_(18,3) = 0.118188;
+exchangeability_(3,18) = 0.118188;
+exchangeability_(18,4) = 4.18318;
+exchangeability_(4,18) = 4.18318;
+exchangeability_(18,5) = 0.139485;
+exchangeability_(5,18) = 0.139485;
+exchangeability_(18,6) = 0.059999;
+exchangeability_(6,18) = 0.059999;
+exchangeability_(18,7) = 0.051336;
+exchangeability_(7,18) = 0.051336;
+exchangeability_(18,8) = 10.2007;
+exchangeability_(8,18) = 10.2007;
+exchangeability_(18,9) = 0.507328;
+exchangeability_(9,18) = 0.507328;
+exchangeability_(18,10) = 0.721921;
+exchangeability_(10,18) = 0.721921;
+exchangeability_(18,11) = 0.086974;
+exchangeability_(11,18) = 0.086974;
+exchangeability_(18,12) = 0.741023;
+exchangeability_(12,18) = 0.741023;
+exchangeability_(18,13) = 24.1915;
+exchangeability_(13,18) = 24.1915;
+exchangeability_(18,14) = 0.04646;
+exchangeability_(14,18) = 0.04646;
+exchangeability_(18,15) = 0.48982;
+exchangeability_(15,18) = 0.48982;
+exchangeability_(18,16) = 0.247367;
+exchangeability_(16,18) = 0.247367;
+exchangeability_(18,17) = 4.90404;
+exchangeability_(17,18) = 4.90404;
+exchangeability_(19,0) = 2.49421;
+exchangeability_(0,19) = 2.49421;
+exchangeability_(19,1) = 0.280293;
+exchangeability_(1,19) = 0.280293;
+exchangeability_(19,2) = 0.235248;
+exchangeability_(2,19) = 0.235248;
+exchangeability_(19,3) = 0.083648;
+exchangeability_(3,19) = 0.083648;
+exchangeability_(19,4) = 5.50993;
+exchangeability_(4,19) = 5.50993;
+exchangeability_(19,5) = 0.429196;
+exchangeability_(5,19) = 0.429196;
+exchangeability_(19,6) = 0.409105;
+exchangeability_(6,19) = 0.409105;
+exchangeability_(19,7) = 0.44713;
+exchangeability_(7,19) = 0.44713;
+exchangeability_(19,8) = 0.351675;
+exchangeability_(8,19) = 0.351675;
+exchangeability_(19,9) = 23.404;
+exchangeability_(9,19) = 23.404;
+exchangeability_(19,10) = 3.84075;
+exchangeability_(10,19) = 3.84075;
+exchangeability_(19,11) = 0.300727;
+exchangeability_(11,19) = 0.300727;
+exchangeability_(19,12) = 4.12666;
+exchangeability_(12,19) = 4.12666;
+exchangeability_(19,13) = 1.48305;
+exchangeability_(13,19) = 1.48305;
+exchangeability_(19,14) = 0.67556;
+exchangeability_(14,19) = 0.67556;
+exchangeability_(19,15) = 0.336101;
+exchangeability_(15,19) = 0.336101;
+exchangeability_(19,16) = 4.42671;
+exchangeability_(16,19) = 4.42671;
+exchangeability_(19,17) = 0.30994;
+exchangeability_(17,19) = 0.30994;
+exchangeability_(19,18) = 0.588217;
+exchangeability_(18,19) = 0.588217;
+exchangeability_(0,0) = -23.5765;
+exchangeability_(1,1) = -14.8545;
+exchangeability_(2,2) = -27.5;
+exchangeability_(3,3) = -11.2672;
+exchangeability_(4,4) = -43.3876;
+exchangeability_(5,5) = -19.0946;
+exchangeability_(6,6) = -9.95355;
+exchangeability_(7,7) = -20.7705;
+exchangeability_(8,8) = -34.5505;
+exchangeability_(9,9) = -51.8986;
+exchangeability_(10,10) = -38.3919;
+exchangeability_(11,11) = -13.3189;
+exchangeability_(12,12) = -44.1535;
+exchangeability_(13,13) = -50.7501;
+exchangeability_(14,14) = -7.07915;
+exchangeability_(15,15) = -41.0337;
+exchangeability_(16,16) = -36.4688;
+exchangeability_(17,17) = -18.9528;
+exchangeability_(18,18) = -48.3598;
+exchangeability_(19,19) = -49.7322;
+}
+
+
+if (getName()=="EXP_OTH" || getName()=="EXP_OTH+F"){
+exchangeability_(1,0) = 0.603175;
+exchangeability_(0,1) = 0.603175;
+exchangeability_(2,0) = 0.478745;
+exchangeability_(0,2) = 0.478745;
+exchangeability_(2,1) = 0.562615;
+exchangeability_(1,2) = 0.562615;
+exchangeability_(3,0) = 0.608325;
+exchangeability_(0,3) = 0.608325;
+exchangeability_(3,1) = 0.056553;
+exchangeability_(1,3) = 0.056553;
+exchangeability_(3,2) = 3.75557;
+exchangeability_(2,3) = 3.75557;
+exchangeability_(4,0) = 2.37184;
+exchangeability_(0,4) = 2.37184;
+exchangeability_(4,1) = 2.48067;
+exchangeability_(1,4) = 2.48067;
+exchangeability_(4,2) = 0.889513;
+exchangeability_(2,4) = 0.889513;
+exchangeability_(4,3) = 0.170707;
+exchangeability_(3,4) = 0.170707;
+exchangeability_(5,0) = 1.55112;
+exchangeability_(0,5) = 1.55112;
+exchangeability_(5,1) = 2.686;
+exchangeability_(1,5) = 2.686;
+exchangeability_(5,2) = 1.46235;
+exchangeability_(2,5) = 1.46235;
+exchangeability_(5,3) = 0.424139;
+exchangeability_(3,5) = 0.424139;
+exchangeability_(5,4) = 0.669728;
+exchangeability_(4,5) = 0.669728;
+exchangeability_(6,0) = 1.62408;
+exchangeability_(0,6) = 1.62408;
+exchangeability_(6,1) = 0.129505;
+exchangeability_(1,6) = 0.129505;
+exchangeability_(6,2) = 0.314826;
+exchangeability_(2,6) = 0.314826;
+exchangeability_(6,3) = 3.40421;
+exchangeability_(3,6) = 3.40421;
+exchangeability_(6,4) = 0.049823;
+exchangeability_(4,6) = 0.049823;
+exchangeability_(6,5) = 3.37547;
+exchangeability_(5,6) = 3.37547;
+exchangeability_(7,0) = 0.987777;
+exchangeability_(0,7) = 0.987777;
+exchangeability_(7,1) = 0.356744;
+exchangeability_(1,7) = 0.356744;
+exchangeability_(7,2) = 1.29408;
+exchangeability_(2,7) = 1.29408;
+exchangeability_(7,3) = 0.640234;
+exchangeability_(3,7) = 0.640234;
+exchangeability_(7,4) = 0.58398;
+exchangeability_(4,7) = 0.58398;
+exchangeability_(7,5) = 0.331879;
+exchangeability_(5,7) = 0.331879;
+exchangeability_(7,6) = 0.304731;
+exchangeability_(6,7) = 0.304731;
+exchangeability_(8,0) = 0.667236;
+exchangeability_(0,8) = 0.667236;
+exchangeability_(8,1) = 2.78843;
+exchangeability_(1,8) = 2.78843;
+exchangeability_(8,2) = 4.71917;
+exchangeability_(2,8) = 4.71917;
+exchangeability_(8,3) = 0.731257;
+exchangeability_(3,8) = 0.731257;
+exchangeability_(8,4) = 1.87267;
+exchangeability_(4,8) = 1.87267;
+exchangeability_(8,5) = 4.61221;
+exchangeability_(5,8) = 4.61221;
+exchangeability_(8,6) = 0.316233;
+exchangeability_(6,8) = 0.316233;
+exchangeability_(8,7) = 0.320454;
+exchangeability_(7,8) = 0.320454;
+exchangeability_(9,0) = 0.186911;
+exchangeability_(0,9) = 0.186911;
+exchangeability_(9,1) = 0.269245;
+exchangeability_(1,9) = 0.269245;
+exchangeability_(9,2) = 0.318538;
+exchangeability_(2,9) = 0.318538;
+exchangeability_(9,3) = 0.028464;
+exchangeability_(3,9) = 0.028464;
+exchangeability_(9,4) = 0.987958;
+exchangeability_(4,9) = 0.987958;
+exchangeability_(9,5) = 0.242926;
+exchangeability_(5,9) = 0.242926;
+exchangeability_(9,6) = 0.090427;
+exchangeability_(6,9) = 0.090427;
+exchangeability_(9,7) = 0.007312;
+exchangeability_(7,9) = 0.007312;
+exchangeability_(9,8) = 0.327205;
+exchangeability_(8,9) = 0.327205;
+exchangeability_(10,0) = 0.527992;
+exchangeability_(0,10) = 0.527992;
+exchangeability_(10,1) = 0.844027;
+exchangeability_(1,10) = 0.844027;
+exchangeability_(10,2) = 0.167295;
+exchangeability_(2,10) = 0.167295;
+exchangeability_(10,3) = 0.021423;
+exchangeability_(3,10) = 0.021423;
+exchangeability_(10,4) = 1.62359;
+exchangeability_(4,10) = 1.62359;
+exchangeability_(10,5) = 1.63688;
+exchangeability_(5,10) = 1.63688;
+exchangeability_(10,6) = 0.135662;
+exchangeability_(6,10) = 0.135662;
+exchangeability_(10,7) = 0.04456;
+exchangeability_(7,10) = 0.04456;
+exchangeability_(10,8) = 0.939347;
+exchangeability_(8,10) = 0.939347;
+exchangeability_(10,9) = 10.338;
+exchangeability_(9,10) = 10.338;
+exchangeability_(11,0) = 0.842575;
+exchangeability_(0,11) = 0.842575;
+exchangeability_(11,1) = 5.07627;
+exchangeability_(1,11) = 5.07627;
+exchangeability_(11,2) = 1.73617;
+exchangeability_(2,11) = 1.73617;
+exchangeability_(11,3) = 0.106076;
+exchangeability_(3,11) = 0.106076;
+exchangeability_(11,4) = 0.132985;
+exchangeability_(4,11) = 0.132985;
+exchangeability_(11,5) = 3.36587;
+exchangeability_(5,11) = 3.36587;
+exchangeability_(11,6) = 0.969736;
+exchangeability_(6,11) = 0.969736;
+exchangeability_(11,7) = 0.270931;
+exchangeability_(7,11) = 0.270931;
+exchangeability_(11,8) = 0.669196;
+exchangeability_(8,11) = 0.669196;
+exchangeability_(11,9) = 0.356829;
+exchangeability_(9,11) = 0.356829;
+exchangeability_(11,10) = 0.35283;
+exchangeability_(10,11) = 0.35283;
+exchangeability_(12,0) = 1.29615;
+exchangeability_(0,12) = 1.29615;
+exchangeability_(12,1) = 0.863599;
+exchangeability_(1,12) = 0.863599;
+exchangeability_(12,2) = 0.469732;
+exchangeability_(2,12) = 0.469732;
+exchangeability_(12,3) = 0.075018;
+exchangeability_(3,12) = 0.075018;
+exchangeability_(12,4) = 1.8326;
+exchangeability_(4,12) = 1.8326;
+exchangeability_(12,5) = 2.6426;
+exchangeability_(5,12) = 2.6426;
+exchangeability_(12,6) = 0.217378;
+exchangeability_(6,12) = 0.217378;
+exchangeability_(12,7) = 0.107935;
+exchangeability_(7,12) = 0.107935;
+exchangeability_(12,8) = 0.624941;
+exchangeability_(8,12) = 0.624941;
+exchangeability_(12,9) = 10.6704;
+exchangeability_(9,12) = 10.6704;
+exchangeability_(12,10) = 17.5935;
+exchangeability_(10,12) = 17.5935;
+exchangeability_(12,11) = 1.24799;
+exchangeability_(11,12) = 1.24799;
+exchangeability_(13,0) = 0.325034;
+exchangeability_(0,13) = 0.325034;
+exchangeability_(13,1) = 0.135328;
+exchangeability_(1,13) = 0.135328;
+exchangeability_(13,2) = 0.192352;
+exchangeability_(2,13) = 0.192352;
+exchangeability_(13,3) = 0.021631;
+exchangeability_(3,13) = 0.021631;
+exchangeability_(13,4) = 2.73142;
+exchangeability_(4,13) = 2.73142;
+exchangeability_(13,5) = 0.103263;
+exchangeability_(5,13) = 0.103263;
+exchangeability_(13,6) = 0.027708;
+exchangeability_(6,13) = 0.027708;
+exchangeability_(13,7) = 0.06074;
+exchangeability_(7,13) = 0.06074;
+exchangeability_(13,8) = 2.14847;
+exchangeability_(8,13) = 2.14847;
+exchangeability_(13,9) = 2.34477;
+exchangeability_(9,13) = 2.34477;
+exchangeability_(13,10) = 5.498;
+exchangeability_(10,13) = 5.498;
+exchangeability_(13,11) = 0.057563;
+exchangeability_(11,13) = 0.057563;
+exchangeability_(13,12) = 3.27863;
+exchangeability_(12,13) = 3.27863;
+exchangeability_(14,0) = 1.67009;
+exchangeability_(0,14) = 1.67009;
+exchangeability_(14,1) = 0.235642;
+exchangeability_(1,14) = 0.235642;
+exchangeability_(14,2) = 0.042844;
+exchangeability_(2,14) = 0.042844;
+exchangeability_(14,3) = 0.164518;
+exchangeability_(3,14) = 0.164518;
+exchangeability_(14,4) = 0.112539;
+exchangeability_(4,14) = 0.112539;
+exchangeability_(14,5) = 0.479958;
+exchangeability_(5,14) = 0.479958;
+exchangeability_(14,6) = 0.32678;
+exchangeability_(6,14) = 0.32678;
+exchangeability_(14,7) = 0.05754;
+exchangeability_(7,14) = 0.05754;
+exchangeability_(14,8) = 0.291899;
+exchangeability_(8,14) = 0.291899;
+exchangeability_(14,9) = 0.110067;
+exchangeability_(9,14) = 0.110067;
+exchangeability_(14,10) = 0.380466;
+exchangeability_(10,14) = 0.380466;
+exchangeability_(14,11) = 0.240061;
+exchangeability_(11,14) = 0.240061;
+exchangeability_(14,12) = 0.109541;
+exchangeability_(12,14) = 0.109541;
+exchangeability_(14,13) = 0.08376;
+exchangeability_(13,14) = 0.08376;
+exchangeability_(15,0) = 5.09815;
+exchangeability_(0,15) = 5.09815;
+exchangeability_(15,1) = 0.831455;
+exchangeability_(1,15) = 0.831455;
+exchangeability_(15,2) = 3.66192;
+exchangeability_(2,15) = 3.66192;
+exchangeability_(15,3) = 0.978777;
+exchangeability_(3,15) = 0.978777;
+exchangeability_(15,4) = 4.50024;
+exchangeability_(4,15) = 4.50024;
+exchangeability_(15,5) = 1.06473;
+exchangeability_(5,15) = 1.06473;
+exchangeability_(15,6) = 0.455496;
+exchangeability_(6,15) = 0.455496;
+exchangeability_(15,7) = 1.09563;
+exchangeability_(7,15) = 1.09563;
+exchangeability_(15,8) = 0.915898;
+exchangeability_(8,15) = 0.915898;
+exchangeability_(15,9) = 0.226713;
+exchangeability_(9,15) = 0.226713;
+exchangeability_(15,10) = 0.405;
+exchangeability_(10,15) = 0.405;
+exchangeability_(15,11) = 0.608323;
+exchangeability_(11,15) = 0.608323;
+exchangeability_(15,12) = 0.525496;
+exchangeability_(12,15) = 0.525496;
+exchangeability_(15,13) = 0.593321;
+exchangeability_(13,15) = 0.593321;
+exchangeability_(15,14) = 1.03573;
+exchangeability_(14,15) = 1.03573;
+exchangeability_(16,0) = 2.1745;
+exchangeability_(0,16) = 2.1745;
+exchangeability_(16,1) = 0.630453;
+exchangeability_(1,16) = 0.630453;
+exchangeability_(16,2) = 1.79175;
+exchangeability_(2,16) = 1.79175;
+exchangeability_(16,3) = 0.396219;
+exchangeability_(3,16) = 0.396219;
+exchangeability_(16,4) = 1.68171;
+exchangeability_(4,16) = 1.68171;
+exchangeability_(16,5) = 1.0838;
+exchangeability_(5,16) = 1.0838;
+exchangeability_(16,6) = 0.556968;
+exchangeability_(6,16) = 0.556968;
+exchangeability_(16,7) = 0.100584;
+exchangeability_(7,16) = 0.100584;
+exchangeability_(16,8) = 0.45707;
+exchangeability_(8,16) = 0.45707;
+exchangeability_(16,9) = 2.36112;
+exchangeability_(9,16) = 2.36112;
+exchangeability_(16,10) = 0.543612;
+exchangeability_(10,16) = 0.543612;
+exchangeability_(16,11) = 1.21182;
+exchangeability_(11,16) = 1.21182;
+exchangeability_(16,12) = 2.98722;
+exchangeability_(12,16) = 2.98722;
+exchangeability_(16,13) = 0.198957;
+exchangeability_(13,16) = 0.198957;
+exchangeability_(16,14) = 0.368383;
+exchangeability_(14,16) = 0.368383;
+exchangeability_(16,15) = 7.50591;
+exchangeability_(15,16) = 7.50591;
+exchangeability_(17,0) = 0.203719;
+exchangeability_(0,17) = 0.203719;
+exchangeability_(17,1) = 0.615713;
+exchangeability_(1,17) = 0.615713;
+exchangeability_(17,2) = 0.044203;
+exchangeability_(2,17) = 0.044203;
+exchangeability_(17,3) = 0.046952;
+exchangeability_(3,17) = 0.046952;
+exchangeability_(17,4) = 1.74509;
+exchangeability_(4,17) = 1.74509;
+exchangeability_(17,5) = 0.303876;
+exchangeability_(5,17) = 0.303876;
+exchangeability_(17,6) = 0.05092;
+exchangeability_(6,17) = 0.05092;
+exchangeability_(17,7) = 0.155176;
+exchangeability_(7,17) = 0.155176;
+exchangeability_(17,8) = 0.920001;
+exchangeability_(8,17) = 0.920001;
+exchangeability_(17,9) = 0.165182;
+exchangeability_(9,17) = 0.165182;
+exchangeability_(17,10) = 1.38583;
+exchangeability_(10,17) = 1.38583;
+exchangeability_(17,11) = 0.055323;
+exchangeability_(11,17) = 0.055323;
+exchangeability_(17,12) = 1.27492;
+exchangeability_(12,17) = 1.27492;
+exchangeability_(17,13) = 5.8966;
+exchangeability_(13,17) = 5.8966;
+exchangeability_(17,14) = 0.059081;
+exchangeability_(14,17) = 0.059081;
+exchangeability_(17,15) = 0.303111;
+exchangeability_(15,17) = 0.303111;
+exchangeability_(17,16) = 0.156402;
+exchangeability_(16,17) = 0.156402;
+exchangeability_(18,0) = 0.27122;
+exchangeability_(0,18) = 0.27122;
+exchangeability_(18,1) = 0.253084;
+exchangeability_(1,18) = 0.253084;
+exchangeability_(18,2) = 0.643377;
+exchangeability_(2,18) = 0.643377;
+exchangeability_(18,3) = 0.142691;
+exchangeability_(3,18) = 0.142691;
+exchangeability_(18,4) = 3.76323;
+exchangeability_(4,18) = 3.76323;
+exchangeability_(18,5) = 0.209729;
+exchangeability_(5,18) = 0.209729;
+exchangeability_(18,6) = 0.093004;
+exchangeability_(6,18) = 0.093004;
+exchangeability_(18,7) = 0.035856;
+exchangeability_(7,18) = 0.035856;
+exchangeability_(18,8) = 8.1675;
+exchangeability_(8,18) = 8.1675;
+exchangeability_(18,9) = 0.490579;
+exchangeability_(9,18) = 0.490579;
+exchangeability_(18,10) = 0.894778;
+exchangeability_(10,18) = 0.894778;
+exchangeability_(18,11) = 0.077103;
+exchangeability_(11,18) = 0.077103;
+exchangeability_(18,12) = 1.0297;
+exchangeability_(12,18) = 1.0297;
+exchangeability_(18,13) = 26.2104;
+exchangeability_(13,18) = 26.2104;
+exchangeability_(18,14) = 0.045876;
+exchangeability_(14,18) = 0.045876;
+exchangeability_(18,15) = 0.373529;
+exchangeability_(15,18) = 0.373529;
+exchangeability_(18,16) = 0.218567;
+exchangeability_(16,18) = 0.218567;
+exchangeability_(18,17) = 5.72644;
+exchangeability_(17,18) = 5.72644;
+exchangeability_(19,0) = 3.47064;
+exchangeability_(0,19) = 3.47064;
+exchangeability_(19,1) = 0.410713;
+exchangeability_(1,19) = 0.410713;
+exchangeability_(19,2) = 0.180011;
+exchangeability_(2,19) = 0.180011;
+exchangeability_(19,3) = 0.081584;
+exchangeability_(3,19) = 0.081584;
+exchangeability_(19,4) = 4.32343;
+exchangeability_(4,19) = 4.32343;
+exchangeability_(19,5) = 0.751254;
+exchangeability_(5,19) = 0.751254;
+exchangeability_(19,6) = 0.686467;
+exchangeability_(6,19) = 0.686467;
+exchangeability_(19,7) = 0.086874;
+exchangeability_(7,19) = 0.086874;
+exchangeability_(19,8) = 0.318032;
+exchangeability_(8,19) = 0.318032;
+exchangeability_(19,9) = 29.8003;
+exchangeability_(9,19) = 29.8003;
+exchangeability_(19,10) = 3.85604;
+exchangeability_(10,19) = 3.85604;
+exchangeability_(19,11) = 0.48293;
+exchangeability_(11,19) = 0.48293;
+exchangeability_(19,12) = 4.86227;
+exchangeability_(12,19) = 4.86227;
+exchangeability_(19,13) = 1.1824;
+exchangeability_(13,19) = 1.1824;
+exchangeability_(19,14) = 0.390522;
+exchangeability_(14,19) = 0.390522;
+exchangeability_(19,15) = 0.268937;
+exchangeability_(15,19) = 0.268937;
+exchangeability_(19,16) = 2.83682;
+exchangeability_(16,19) = 2.83682;
+exchangeability_(19,17) = 0.229423;
+exchangeability_(17,19) = 0.229423;
+exchangeability_(19,18) = 0.453335;
+exchangeability_(18,19) = 0.453335;
+exchangeability_(0,0) = -24.9593;
+exchangeability_(1,1) = -19.8292;
+exchangeability_(2,2) = -22.7251;
+exchangeability_(3,3) = -11.8543;
+exchangeability_(4,4) = -32.5237;
+exchangeability_(5,5) = -26.9978;
+exchangeability_(6,6) = -13.1294;
+exchangeability_(7,7) = -6.84301;
+exchangeability_(8,8) = -31.8072;
+exchangeability_(9,9) = -59.323;
+exchangeability_(10,10) = -47.1889;
+exchangeability_(11,11) = -17.8606;
+exchangeability_(12,12) = -51.7097;
+exchangeability_(13,13) = -51.0903;
+exchangeability_(14,14) = -6.20529;
+exchangeability_(15,15) = -30.4484;
+exchangeability_(16,16) = -27.2619;
+exchangeability_(17,17) = -19.338;
+exchangeability_(18,18) = -49.1;
+exchangeability_(19,19) = -54.6719;
+}
+
diff --git a/src/Bpp/Phyl/Model/Protein/__LG10_EX_EHOFrequenciesCode b/src/Bpp/Phyl/Model/Protein/__LG10_EX_EHOFrequenciesCode
new file mode 100644
index 0000000..686faa0
--- /dev/null
+++ b/src/Bpp/Phyl/Model/Protein/__LG10_EX_EHOFrequenciesCode
@@ -0,0 +1,142 @@
+if (getName()=="BUR_EXT" || getName()=="BUR_EXT+F"){
+freq_[0] = 0.087158;
+freq_[1] = 0.015906;
+freq_[2] = 0.012970;
+freq_[3] = 0.012566;
+freq_[4] = 0.020325;
+freq_[5] = 0.013301;
+freq_[6] = 0.013777;
+freq_[7] = 0.039603;
+freq_[8] = 0.014597;
+freq_[9] = 0.161107;
+freq_[10] = 0.147775;
+freq_[11] = 0.011033;
+freq_[12] = 0.031334;
+freq_[13] = 0.064281;
+freq_[14] = 0.013322;
+freq_[15] = 0.035417;
+freq_[16] = 0.048583;
+freq_[17] = 0.012672;
+freq_[18] = 0.045210;
+freq_[19] = 0.199064;
+}
+
+
+if (getName()=="BUR_HEL" || getName()=="BUR_HEL+F"){
+freq_[0] = 0.158060;
+freq_[1] = 0.021566;
+freq_[2] = 0.016487;
+freq_[3] = 0.014079;
+freq_[4] = 0.016937;
+freq_[5] = 0.020232;
+freq_[6] = 0.023096;
+freq_[7] = 0.032822;
+freq_[8] = 0.014618;
+freq_[9] = 0.114447;
+freq_[10] = 0.198900;
+freq_[11] = 0.014668;
+freq_[12] = 0.042840;
+freq_[13] = 0.053434;
+freq_[14] = 0.015640;
+freq_[15] = 0.037275;
+freq_[16] = 0.043095;
+freq_[17] = 0.012211;
+freq_[18] = 0.036330;
+freq_[19] = 0.113263;
+}                    
+
+
+if (getName()=="BUR_OTH" || getName()=="BUR_OTH+F"){
+freq_[0] = 0.102123;
+freq_[1] = 0.021199;
+freq_[2] = 0.032404;
+freq_[3] = 0.032350;
+freq_[4] = 0.018985;
+freq_[5] = 0.017469;
+freq_[6] = 0.017625;
+freq_[7] = 0.089270;
+freq_[8] = 0.021090;
+freq_[9] = 0.083642;
+freq_[10] = 0.123866;
+freq_[11] = 0.012720;
+freq_[12] = 0.029789;
+freq_[13] = 0.055399;
+freq_[14] = 0.072705;
+freq_[15] = 0.061298;
+freq_[16] = 0.061705;
+freq_[17] = 0.013496;
+freq_[18] = 0.039682;
+freq_[19] = 0.093184;
+}
+
+
+if (getName()=="EXP_EXT" || getName()=="EXP_EXT+F"){
+freq_[0] = 0.043140;
+freq_[1] = 0.090761;
+freq_[2] = 0.034408;
+freq_[3] = 0.052848;
+freq_[4] = 0.006370;
+freq_[5] = 0.053817;
+freq_[6] = 0.107749;
+freq_[7] = 0.024812;
+freq_[8] = 0.029498;
+freq_[9] = 0.049134;
+freq_[10] = 0.050167;
+freq_[11] = 0.098127;
+freq_[12] = 0.013722;
+freq_[13] = 0.025841;
+freq_[14] = 0.037395;
+freq_[15] = 0.056505;
+freq_[16] = 0.094326;
+freq_[17] = 0.012045;
+freq_[18] = 0.039238;
+freq_[19] = 0.080099;
+}
+
+
+if (getName()=="EXP_HEL" || getName()=="EXP_HEL+F"){
+freq_[0] = 0.115826;
+freq_[1] = 0.094038;
+freq_[2] = 0.037357;
+freq_[3] = 0.085821;
+freq_[4] = 0.003363;
+freq_[5] = 0.073078;
+freq_[6] = 0.167709;
+freq_[7] = 0.025416;
+freq_[8] = 0.021634;
+freq_[9] = 0.024147;
+freq_[10] = 0.050238;
+freq_[11] = 0.106612;
+freq_[12] = 0.013318;
+freq_[13] = 0.013330;
+freq_[14] = 0.029895;
+freq_[15] = 0.044902;
+freq_[16] = 0.037901;
+freq_[17] = 0.006460;
+freq_[18] = 0.018548;
+freq_[19] = 0.030407;
+}
+
+
+if (getName()=="EXP_OTH" || getName()=="EXP_OTH+F"){
+freq_[0] = 0.071716;
+freq_[1] = 0.058979;
+freq_[2] = 0.060316;
+freq_[3] = 0.101089;
+freq_[4] = 0.005039;
+freq_[5] = 0.044673;
+freq_[6] = 0.093349;
+freq_[7] = 0.105394;
+freq_[8] = 0.026228;
+freq_[9] = 0.020220;
+freq_[10] = 0.037831;
+freq_[11] = 0.081647;
+freq_[12] = 0.010677;
+freq_[13] = 0.015875;
+freq_[14] = 0.090566;
+freq_[15] = 0.065046;
+freq_[16] = 0.054453;
+freq_[17] = 0.005546;
+freq_[18] = 0.019924;
+freq_[19] = 0.031432;
+}
diff --git a/src/Bpp/Phyl/Model/Protein/__LG10_EX_EHORatesProps b/src/Bpp/Phyl/Model/Protein/__LG10_EX_EHORatesProps
new file mode 100644
index 0000000..df54027
--- /dev/null
+++ b/src/Bpp/Phyl/Model/Protein/__LG10_EX_EHORatesProps
@@ -0,0 +1,34 @@
+if (getName()=="BUR_EXT" || getName()=="BUR_EXT+F"){
+	rate_ = 0.6218078;
+	proportion_ = 0.133;
+}
+
+
+if (getName()=="BUR_HEL" || getName()=="BUR_HEL+F"){
+	rate_ = 0.6071195;
+	proportion_ = 0.171;
+}                    
+
+
+if (getName()=="BUR_OTH" || getName()=="BUR_OTH+F"){
+	rate_ = 0.4341231;
+	proportion_ = 0.1445;
+}
+
+
+if (getName()=="EXP_EXT" || getName()=="EXP_EXT+F"){
+	rate_ = 1.276257;
+	proportion_ = 0.075;
+}
+
+
+if (getName()=="EXP_HEL" || getName()=="EXP_HEL+F"){
+	rate_ = 1.684267;
+	proportion_ = 0.19;
+}
+
+
+if (getName()=="EXP_OTH" || getName()=="EXP_OTH+F"){
+	rate_ = 1.169358;
+	proportion_ = 0.2865;
+}
diff --git a/src/Bpp/Phyl/Model/RE08.cpp b/src/Bpp/Phyl/Model/RE08.cpp
index d19992e..8174b30 100755
--- a/src/Bpp/Phyl/Model/RE08.cpp
+++ b/src/Bpp/Phyl/Model/RE08.cpp
@@ -49,8 +49,7 @@ using namespace std;
 
 RE08::RE08(ReversibleSubstitutionModel* simpleModel, double lambda, double mu) :
   AbstractParameterAliasable("RE08."),
-  AbstractSubstitutionModel(simpleModel->getAlphabet(), "RE08."),
-  AbstractReversibleSubstitutionModel(simpleModel->getAlphabet(), "RE08."),
+  AbstractReversibleSubstitutionModel(simpleModel->getAlphabet(), new CanonicalStateMap(simpleModel->getStateMap(), true), "RE08."),
   simpleModel_(simpleModel),
   simpleGenerator_(),
   simpleExchangeabilities_(),
@@ -64,7 +63,6 @@ RE08::RE08(ReversibleSubstitutionModel* simpleModel, double lambda, double mu) :
   //We need to overrired this from the AbstractSubstitutionModel constructor,
   //since the number of states in the model is no longer equal to the size of the alphabet.
   size_ = simpleModel->getNumberOfStates() + 1;
-  chars_.insert(chars_.begin(), -1);
   generator_.resize(size_, size_);
   exchangeability_.resize(size_, size_);
   freq_.resize(size_);
@@ -212,7 +210,7 @@ double RE08::d2Pij_dt2(size_t i, size_t j, double d) const
 
 /******************************************************************************/
 
-const Matrix<double> & RE08::getPij_t(double d) const
+const Matrix<double>& RE08::getPij_t(double d) const
 {
   RowMatrix<double> simpleP = simpleModel_->getPij_t(d);
   double f = (lambda_ == 0 && mu_ == 0) ? 1. : lambda_ / (lambda_ + mu_);
@@ -238,7 +236,7 @@ const Matrix<double> & RE08::getPij_t(double d) const
 
 /******************************************************************************/
 
-const Matrix<double> & RE08::getdPij_dt(double d) const
+const Matrix<double>& RE08::getdPij_dt(double d) const
 {
   RowMatrix<double> simpleP = simpleModel_->getPij_t(d);
   RowMatrix<double> simpleDP = simpleModel_->getdPij_dt(d);
@@ -266,7 +264,7 @@ const Matrix<double> & RE08::getdPij_dt(double d) const
 
 /******************************************************************************/
 
-const Matrix<double> & RE08::getd2Pij_dt2(double d) const
+const Matrix<double>& RE08::getd2Pij_dt2(double d) const
 {
   RowMatrix<double> simpleP = simpleModel_->getPij_t(d);
   RowMatrix<double> simpleDP = simpleModel_->getdPij_dt(d);
diff --git a/src/Bpp/Phyl/Model/RE08.h b/src/Bpp/Phyl/Model/RE08.h
index 078fdc0..395863b 100755
--- a/src/Bpp/Phyl/Model/RE08.h
+++ b/src/Bpp/Phyl/Model/RE08.h
@@ -5,36 +5,36 @@
 //
 
 /*
-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.
+  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 _RE08_H_
@@ -93,11 +93,11 @@ namespace bpp
  * Reference:
  * - Rivas E and Eddy SR (2008), _Probabilistic Phylogenetic Inference with Insertions and Deletions_, 4(9):e1000172, in _PLoS Computational Biology_. 
  */
-class RE08:
-  public AbstractReversibleSubstitutionModel
-{
+  class RE08:
+    public AbstractReversibleSubstitutionModel
+  {
   private:
-    ReversibleSubstitutionModel* simpleModel_;
+    std::auto_ptr<ReversibleSubstitutionModel> simpleModel_;
     RowMatrix<double> simpleGenerator_;
     RowMatrix<double> simpleExchangeabilities_;
     mutable double exp_;
@@ -106,7 +106,7 @@ class RE08:
     double mu_;
     std::string nestedPrefix_;
 
-	public:
+  public:
     /**
      * @brief Build a new Rivas & Eddy model from a standard substitution model.
      * 
@@ -118,11 +118,11 @@ class RE08:
      * @param lambda Insertion rate.
      * @param mu     Deletion rate.
      */
-		RE08(ReversibleSubstitutionModel* simpleModel, double lambda = 0, double mu = 0);
+    RE08(ReversibleSubstitutionModel* simpleModel, double lambda = 0, double mu = 0);
 
     RE08(const RE08& model):
       AbstractParameterAliasable(model),
-      AbstractSubstitutionModel(model),
+      //AbstractSubstitutionModel(model),
       AbstractReversibleSubstitutionModel(model),
       simpleModel_(dynamic_cast<ReversibleSubstitutionModel*>(model.simpleModel_->clone())),
       simpleGenerator_(model.simpleGenerator_),
@@ -139,7 +139,7 @@ class RE08:
       AbstractParameterAliasable::operator=(model);
       AbstractSubstitutionModel::operator=(model);
       AbstractReversibleSubstitutionModel::operator=(model);
-      simpleModel_             = dynamic_cast<ReversibleSubstitutionModel*>(model.simpleModel_->clone());
+      simpleModel_.reset(dynamic_cast<ReversibleSubstitutionModel*>(model.simpleModel_->clone()));
       simpleGenerator_         = model.simpleGenerator_;
       simpleExchangeabilities_ = model.simpleExchangeabilities_;
       exp_                     = model.exp_;
@@ -150,18 +150,18 @@ class RE08:
       return *this;
     }
 
-		virtual ~RE08() { delete simpleModel_; }
+    virtual ~RE08() {}
 
     RE08* clone() const { return new RE08(*this); }
 
   public:
 	
-		double Pij_t    (size_t i, size_t j, double d) const;
-		double dPij_dt  (size_t i, size_t j, double d) const;
-		double d2Pij_dt2(size_t i, size_t j, double d) const;
-		const Matrix<double>& getPij_t    (double d) const;
-		const Matrix<double>& getdPij_dt  (double d) const;
-		const Matrix<double>& getd2Pij_dt2(double d) const;
+    double Pij_t    (size_t i, size_t j, double d) const;
+    double dPij_dt  (size_t i, size_t j, double d) const;
+    double d2Pij_dt2(size_t i, size_t j, double d) const;
+    const Matrix<double>& getPij_t    (double d) const;
+    const Matrix<double>& getdPij_dt  (double d) const;
+    const Matrix<double>& getd2Pij_dt2(double d) const;
 
     std::string getName() const { return "RE08"; }
 
@@ -169,8 +169,12 @@ class RE08:
      * @brief This method is forwarded to the simple model.
      *
      * @param data The data to be passed to the simple model (gaps will be ignored).
+     * @param pseudoCount A (typically small) value to add to each count to avoid 0 estimates.
      */
-    void setFreqFromData(const SequenceContainer& data) {}
+    void setFreqFromData(const SequenceContainer& data, double pseudoCount = 0)
+    {
+      simpleModel_->setFreqFromData(data, pseudoCount);
+    }
 	
     void fireParameterChanged(const ParameterList& parameters)
     {
@@ -187,12 +191,12 @@ class RE08:
   
     void setNamespace(const std::string& prefix);
 
-    const SubstitutionModel* getNestedModel() const { return simpleModel_; }
+    const SubstitutionModel* getNestedModel() const { return simpleModel_.get(); }
 
   protected:
 
-		void updateMatrices();
-};
+    void updateMatrices();
+  };
 
 } //end of namespace bpp.
 
diff --git a/src/Bpp/Phyl/Model/StateMap.cpp b/src/Bpp/Phyl/Model/StateMap.cpp
index b2c9730..68995d6 100644
--- a/src/Bpp/Phyl/Model/StateMap.cpp
+++ b/src/Bpp/Phyl/Model/StateMap.cpp
@@ -44,10 +44,30 @@ using namespace bpp;
 CanonicalStateMap::CanonicalStateMap(const Alphabet* alphabet, bool includeGaps):
   AbstractStateMap(alphabet)
 {
-  for (unsigned int i = 0; i < alphabet->getSize(); ++i) {
+  for (int i = 0; i < static_cast<int>(alphabet->getSize()); ++i) {
     states_.push_back(i);
   }
   if (includeGaps)
     states_.push_back(alphabet->getGapCharacterCode());
 }
 
+CanonicalStateMap::CanonicalStateMap(const StateMap& sm, bool includeGaps):
+  AbstractStateMap(sm.getAlphabet())
+{
+  for (size_t i = 0; i < sm.getNumberOfModelStates(); ++i) {
+    states_.push_back(sm.getAlphabetStateAsInt(i));
+  }
+  if (includeGaps)
+    states_.push_back(sm.getAlphabet()->getGapCharacterCode());
+}
+
+MarkovModulatedStateMap::MarkovModulatedStateMap(const StateMap& unitMap, unsigned int nbClasses):
+  AbstractStateMap(unitMap.getAlphabet())
+{
+  for (unsigned int j = 0; j < nbClasses; ++j) {
+    for (size_t i = 0; i < unitMap.getNumberOfModelStates(); ++i) {
+      states_.push_back(unitMap.getAlphabetStateAsInt(i));
+    }
+  }
+}
+
diff --git a/src/Bpp/Phyl/Model/StateMap.h b/src/Bpp/Phyl/Model/StateMap.h
index 0c3011b..86a930d 100644
--- a/src/Bpp/Phyl/Model/StateMap.h
+++ b/src/Bpp/Phyl/Model/StateMap.h
@@ -71,31 +71,39 @@ namespace bpp
       /**
        * @return The number of states supported by the model.
        */
-      virtual size_t getNumberOfStates() const = 0;
+      virtual size_t getNumberOfModelStates() const = 0;
+
+      /**
+       * @return A vector with the corresponding alphabet states for each model state.
+       * the size of the vector is the number of model states, not the number of supported alphabet states,
+       * as distinct model states can correspond to a single alphabet state.
+       */
+      virtual const std::vector<int>& getAlphabetStates() const = 0;
 
       /**
        * @param index The model state.
-       * @return The corresponding alphabet character as int code.
+       * @return The corresponding alphabet state as character code.
        */
-      virtual int stateAsInt(size_t index) const = 0;
+      virtual std::string getAlphabetStateAsChar(size_t index) const = 0;
 
       /**
        * @param index The model state.
-       * @return The corresponding alphabet character as character code.
+       * @return The corresponding alphabet state as int code.
        */
-      virtual std::string stateAsChar(size_t index) const = 0;
+      virtual int getAlphabetStateAsInt(size_t index) const = 0;
 
       /**
-       * @param code The int code of the character to check.
-       * @return The corresponding model state, is any.
+       * @param code The character code of the alphabet state to check.
+       * @return The corresponding model states, is any.
        */
-      virtual size_t whichState(int code) const = 0;
-      
+      virtual std::vector<size_t> getModelStates(const std::string& code) const = 0;
+
       /**
-       * @param code The character code of the character to check.
-       * @return The corresponding model state, is any.
+       * @param code The int code of the alphabet state to check.
+       * @return The corresponding model states, is any.
        */
-      virtual size_t whichState(const std::string& code) const = 0;
+      virtual std::vector<size_t> getModelStates(int code) const = 0;
+      
   };
 
   /**
@@ -131,16 +139,15 @@ namespace bpp
 
     public:
       virtual const Alphabet* getAlphabet() const { return alphabet_; }
-      virtual size_t getNumberOfStates() const { return states_.size(); }
-      virtual int stateAsInt(size_t index) const { return states_[index]; }
-      virtual std::string stateAsChar(size_t index) const { return alphabet_->intToChar(states_[index]); }
-      virtual size_t whichState(int code) const throw (Exception) {
-        try { return VectorTools::which(states_, code); }
-        catch (ElementNotFoundException<int>& ex) { throw Exception("AbstractStateMap::whichState. Unsupported alphabet char: " + code); }
+      virtual size_t getNumberOfModelStates() const { return states_.size(); }
+      virtual const std::vector<int>& getAlphabetStates() const { return states_; }
+      virtual int getAlphabetStateAsInt(size_t index) const { return states_[index]; }
+      virtual std::string getAlphabetStateAsChar(size_t index) const { return alphabet_->intToChar(states_[index]); }
+      virtual std::vector<size_t> getModelStates(int code) const {
+        return VectorTools::whichAll(states_, code);
       }
-      virtual size_t whichState(const std::string& code) const throw (Exception) {
-        try { return VectorTools::which(states_, alphabet_->charToInt(code)); }
-        catch (ElementNotFoundException<int>& ex) { throw Exception("AbstractStateMap::whichState. Unsupported alphabet char: " + code); }
+      virtual std::vector<size_t> getModelStates(const std::string& code) const {
+        return VectorTools::whichAll(states_, alphabet_->charToInt(code));
       }
 
   };
@@ -156,10 +163,34 @@ namespace bpp
   {
     public:
       CanonicalStateMap(const Alphabet* alphabet, bool includeGaps);
+
+      /**
+       * @brief this contructors takes an existing StateMap and adds one model states for gaps.
+       * If the original StateMap alread had a state for gaps, a new one will be appended.
+       */
+      CanonicalStateMap(const StateMap& sm, bool includeGaps);
+
       virtual CanonicalStateMap* clone() const { return new CanonicalStateMap(*this); }
 
   };
 
+
+  
+  /**
+   * @brief This class implements a state map for Markov modulated models.
+   *
+   * For nucleotides with two classes, the underlying states are for instance:
+   * A (0), C (1), G (2), T/U (3), A (4), C (5), G (6), T/U (7).
+   */
+  class MarkovModulatedStateMap:
+    public AbstractStateMap
+  {
+    public:
+      MarkovModulatedStateMap(const StateMap& unitMap, unsigned int nbClasses);
+      virtual MarkovModulatedStateMap* clone() const { return new MarkovModulatedStateMap(*this); }
+
+  };
+
 }// end of namespace bpp
 
 #endif //_STATEMAP_H_
diff --git a/src/Bpp/Phyl/Model/SubstitutionModel.h b/src/Bpp/Phyl/Model/SubstitutionModel.h
index dd5a518..65d60f2 100755
--- a/src/Bpp/Phyl/Model/SubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/SubstitutionModel.h
@@ -40,10 +40,10 @@
 #ifndef _SUBSTITUTIONMODEL_H_
 #define _SUBSTITUTIONMODEL_H_
 
-#include <cstdlib>
-#include <map>
-#include <string>
+#include "FrequenciesSet/FrequenciesSet.h"
+#include "StateMap.h"
 
+// From bpp-core:
 #include <Bpp/Exceptions.h>
 #include <Bpp/Numeric/Parameter.h>
 #include <Bpp/Numeric/ParameterList.h>
@@ -51,10 +51,14 @@
 #include <Bpp/Numeric/VectorTools.h>
 #include <Bpp/Numeric/Matrix/Matrix.h>
 
-//From Seqlib:
+// From bpp-seq:
 #include <Bpp/Seq/Alphabet/Alphabet.h>
 #include <Bpp/Seq/Container/SequenceContainer.h>
-#include "FrequenciesSet/FrequenciesSet.h"
+
+// From the STL:
+#include <cstdlib>
+#include <map>
+#include <string>
 
 namespace bpp
 {
@@ -212,30 +216,44 @@ public:
   virtual std::string getName() const = 0;
 
   /**
-   * @return The supported states of the model, as a vector of int codes.
+   * @return The alphabet states of each state of the model, as a vector of int codes.
    *
    * @see Alphabet
    */
-  virtual const std::vector<int>& getAlphabetChars() const = 0;
+  virtual const std::vector<int>& getAlphabetStates() const = 0;
+
+  /**
+   * @return The mapping of model states with alphabet states.
+   */
+  virtual const StateMap& getStateMap() const = 0;
 
   /**
-   * @brief Get the char in the alphabet corresponding to a given state in the model.
+   * @brief Get the state in the model corresponding to a particular state in the alphabet.
    *
-   * In most cases, this method will return i.
-   * @param i The index of the state.
-   * @return The corresponding state in the alphabet.
-   * @see MarkovModulatedSubstitutionModel
-   * @see getStates()
+   * @param code The alphabet state to check.
+   * @return A vector of indices of model states.
    */
-  virtual int getAlphabetChar(size_t i) const = 0;
+  virtual std::vector<size_t> getModelStates(int code) const = 0;
 
   /**
-   * @brief Get the state in the model corresponding to a particular char in the alphabet.
+   * @brief Get the state in the model corresponding to a particular state in the alphabet.
    *
-   * @param i The alphabet char to check.
+   * @param code The alphabet state to check.
    * @return A vector of indices of model states.
    */
-  virtual std::vector<size_t> getModelStates(int i) const = 0;
+  virtual std::vector<size_t> getModelStates(const std::string& code) const = 0;
+
+  /**
+   * @param index The model state.
+   * @return The corresponding alphabet state as character code.
+   */
+  virtual int getAlphabetStateAsInt(size_t index) const = 0;
+  
+  /**
+   * @param index The model state.
+   * @return The corresponding alphabet state as character code.
+   */
+  virtual std::string getAlphabetStateAsChar(size_t index) const = 0;
 
   /**
    * @return Equilibrium frequency associated to character i.
@@ -378,6 +396,7 @@ public:
    * @brief Get the number of states.
    *
    * For most models, this equals the size of the alphabet.
+   * @see getAlphabetChars for the list of supported states.
    *
    * @return The number of different states in the model.
    */
@@ -409,14 +428,13 @@ public:
   virtual double getScale() const = 0;
 
   /**
-   * @brief Set the rate of the generator, defined as the scalar
-   * product of diagonal elements of the generator and the frequencies
-   * vector.
+   * 
+   * @brief Multiplies the current generator by the given scale.
    *
-   * When the generator is normalized, scale=1. Otherwise each element
-   * is multiplied such that the correct scale is set.
+   * @param scale the scale by which the generator is multiplied.
    *
    */
+
   virtual void setScale(double scale) = 0;
 
   /**
@@ -457,9 +475,7 @@ public:
   /**
    * @brief If the model owns a FrequenciesSet, returns a pointer to
    * it, otherwise return 0.
-   *
    */
-
   virtual const FrequenciesSet* getFrequenciesSet() const {return NULL;}
 };
 
diff --git a/src/Bpp/Phyl/Model/SubstitutionModelSet.cpp b/src/Bpp/Phyl/Model/SubstitutionModelSet.cpp
index e0567a7..44d27b0 100644
--- a/src/Bpp/Phyl/Model/SubstitutionModelSet.cpp
+++ b/src/Bpp/Phyl/Model/SubstitutionModelSet.cpp
@@ -54,9 +54,6 @@ SubstitutionModelSet::SubstitutionModelSet(const SubstitutionModelSet& set) :
   rootFrequencies_(set.stationarity_ ? 0 : dynamic_cast<FrequenciesSet*>(set.rootFrequencies_->clone())),
   nodeToModel_          (set.nodeToModel_),
   modelToNodes_         (set.modelToNodes_),
-  paramToModels_        (set.paramToModels_),
-  paramNamesCount_      (set.paramNamesCount_),
-  modelParameterNames_  (set.modelParameterNames_),
   modelParameters_      (set.modelParameters_),
   stationarity_         (set.stationarity_)
 {
@@ -74,9 +71,6 @@ SubstitutionModelSet& SubstitutionModelSet::operator=(const SubstitutionModelSet
   nbStates_            = set.nbStates_;
   nodeToModel_         = set.nodeToModel_;
   modelToNodes_        = set.modelToNodes_;
-  paramToModels_       = set.paramToModels_;
-  paramNamesCount_     = set.paramNamesCount_;
-  modelParameterNames_ = set.modelParameterNames_;
   modelParameters_     = set.modelParameters_;
   stationarity_        = set.stationarity_;
   if (set.stationarity_)
@@ -104,9 +98,6 @@ void SubstitutionModelSet::clear()
   modelSet_.clear();
   rootFrequencies_.reset();
   nodeToModel_.clear();
-  paramToModels_.clear();
-  paramNamesCount_.clear();
-  modelParameterNames_.clear();
   modelParameters_.clear();
   stationarity_=true;
 
@@ -124,37 +115,24 @@ void SubstitutionModelSet::setRootFrequencies(FrequenciesSet* rootFreqs)
 std::vector<int> SubstitutionModelSet::getNodesWithParameter(const std::string& name) const
   throw (ParameterNotFoundException)
 {
-  vector<int> ids;
-  size_t offset = stationarity_ ? 0 : rootFrequencies_->getNumberOfParameters();
-  for (size_t i = 0; i < paramToModels_.size(); i++)
+  if (!(hasParameter(name)))
+    throw ParameterNotFoundException("SubstitutionModelSet::getNodesWithParameter.", name);
+    
+  vector<string> nalias=getAlias(name);
+  size_t p=name.rfind("_");
+  vector<int> inode = getNodesWithModel(TextTools::to<size_t>(name.substr(p+1,string::npos)) - 1);
+  
+  for (size_t i = 0; i < nalias.size(); i++)
     {
-      if (getParameter_(offset + i).getName() == name)
-        {
-          for (size_t j = 0; j < paramToModels_[i].size(); j++)
-            {
-              vector<int> v = modelToNodes_[paramToModels_[i][j]];
-              VectorTools::append(ids, v);
-            }
-          return ids;
-        }
+      p=nalias[i].rfind("_");
+      vector<int> ni = getNodesWithModel(TextTools::to<size_t>(nalias[i].substr(p+1,string::npos))-1);
+      inode.insert(inode.end(),ni.begin(),ni.end());
     }
-  throw ParameterNotFoundException("SubstitutionModelSet::getNodesWithParameter.", name);
+  
+  return inode;
 }
 
-vector<size_t> SubstitutionModelSet::getModelsWithParameter(const std::string& name) const
-  throw (ParameterNotFoundException)
-{
-  vector<size_t> indices;
-  size_t offset = stationarity_ ? 0 : rootFrequencies_->getNumberOfParameters();
-  for (size_t i = 0; i < paramToModels_.size(); i++)
-    {
-      if (getParameter_(offset + i).getName() == name)
-        return paramToModels_[i];
-    }
-  throw ParameterNotFoundException("SubstitutionModelSet::getModelsWithParameter.", name);
-}
-
-void SubstitutionModelSet::addModel(SubstitutionModel* model, const std::vector<int>& nodesId, const vector<string>& newParams) throw (Exception)
+void SubstitutionModelSet::addModel(SubstitutionModel* model, const std::vector<int>& nodesId)//, const vector<string>& newParams) throw (Exception)
 {
   if (model->getAlphabet()->getAlphabetType() != alphabet_->getAlphabetType())
     throw Exception("SubstitutionModelSet::addModel. A Substitution Model cannot be added to a Model Set if it does not have the same alphabet.");
@@ -174,67 +152,67 @@ void SubstitutionModelSet::addModel(SubstitutionModel* model, const std::vector<
 
   // Associate parameters:
   string pname;
-  modelParameters_.push_back(ParameterList());
-  for (size_t i  = 0; i < newParams.size(); i++)
+
+  vector<string> nplm=model->getParameters().getParameterNames();
+  
+  modelParameters_.push_back(*model->getParameters().clone());
+  
+  for (size_t i  = 0; i < nplm.size(); i++)
     {
-      pname = newParams[i];
-      modelParameterNames_.push_back(pname);
-      vector<size_t> modelsIndex(1, thisModelIndex);
-      paramToModels_.push_back(modelsIndex);
+      pname = nplm[i];
       Parameter* p = new Parameter(model->getParameters().getParameter(pname)); // We work with namespaces here, so model->getParameter(pname) does not work.
-      modelParameters_[thisModelIndex].addParameter(p->clone());
-      p->setName(pname + "_" + TextTools::toString(++paramNamesCount_[pname])); // Change name to unique name in case of shared parameters.
+      p->setName(pname + "_" + TextTools::toString(thisModelIndex+1));
       addParameter_(p);
     }
 }
 
-void SubstitutionModelSet::setModel(SubstitutionModel* model, size_t modelIndex) throw (Exception, IndexOutOfBoundsException)
+void SubstitutionModelSet::replaceModel(size_t modelIndex, SubstitutionModel* model) throw (Exception)
 {
-  if (model->getAlphabet()->getAlphabetType() != alphabet_->getAlphabetType())
-    throw Exception("SubstitutionModelSet::setModel. A Substitution Model cannot be added to a Model Set if it does not have the same alphabet");
-  if (modelIndex >= modelSet_.size())
-    throw IndexOutOfBoundsException("SubstitutionModelSet::setModel.", modelIndex, 0, modelSet_.size());
   delete modelSet_[modelIndex];
-  modelSet_[modelIndex] = model;
-}
+  modelSet_[modelIndex]=model;
+  
+  
+  // Erase all parameter references to this model
 
-void SubstitutionModelSet::removeModel(size_t modelIndex) throw (Exception)
-{
-  modelSet_.erase(modelSet_.begin() + modelIndex);
-  // Erase all parameter references to this model and translate other indices...
-  for (size_t i = 0; i < paramToModels_.size(); i++)
-    {
-      for (size_t j = paramToModels_[i].size(); j > 0; j--)
-        {
-          if (paramToModels_[i][j - 1] == modelIndex)
-            {
-              paramToModels_[i].erase(paramToModels_[i].begin() + j - 1);
-            }
-          else if (paramToModels_[i][j - 1] > modelIndex)
-            paramToModels_[i][j - 1]--;  // Correct indice due to removal!
-        }
-    }
-  checkOrphanParameters(true);
-}
+  ParameterList pl=getNodeParameters();
 
-ParameterList SubstitutionModelSet::getModelParameters(size_t modelIndex) const
-{
-  ParameterList pl;
-  size_t offset = stationarity_ ? 0 : rootFrequencies_->getNumberOfParameters(); // Root frequencies are the first parameters! We should ignore them here.
-  for (size_t i = 0; i < modelParameterNames_.size(); i++)
+  for (size_t i = pl.size(); i>0; i--)
     {
-      // Check associations:
-      const vector<size_t>* modelIndexes = &paramToModels_[i];
-      for (size_t j = 0; j < modelIndexes->size(); j++)
-        {
-          if ((*modelIndexes)[j] == modelIndex)
+      string pn=pl[i-1].getName();
+
+      size_t pu=pn.rfind("_");
+      int nm=TextTools::toInt(pn.substr(pu+1,string::npos));
+      if (nm==(int)modelIndex+1){
+        vector<string> alpn=getAlias(pn);
+        for (unsigned j=0; j<alpn.size(); j++)
+          try {
+            unaliasParameters(alpn[j],pn);
+          }
+          catch (Exception& e)
             {
-              pl.addParameter(getParameter_(offset + i));
-              break;
+              continue;
             }
-        }
+        deleteParameter_(i-1);
+      }
     }
-  return pl;
+
+  // Associate new parameters
+  string pname;
+
+  vector<string> nplm=model->getParameters().getParameterNames();
+  
+  for (size_t i  = 0; i < nplm.size(); i++)
+  {
+    pname = nplm[i];
+    Parameter* p = new Parameter(model->getParameters().getParameter(pname)); // We work with namespaces here, so model->getParameter(pname) does not work.
+    p->setName(pname + "_" + TextTools::toString(modelIndex+1));
+    addParameter_(p);
+  }
+
+  // update modelParameters_
+
+  modelParameters_[modelIndex].reset();
+  modelParameters_[modelIndex]=*model->getParameters().clone();
 }
 
 void SubstitutionModelSet::listModelNames(std::ostream& out) const
@@ -250,145 +228,20 @@ void SubstitutionModelSet::listModelNames(std::ostream& out) const
     }
 }
 
-void SubstitutionModelSet::setParameterToModel(size_t parameterIndex, size_t modelIndex) throw (IndexOutOfBoundsException)
-{
-  size_t offset = stationarity_ ? 0 : rootFrequencies_->getNumberOfParameters();
-  if (parameterIndex < offset)
-    throw IndexOutOfBoundsException("SubstitutionModelSet::setParameterToModel. Can't assign a root frequency parameter to a branch model.", parameterIndex, offset - 1, paramToModels_.size() + offset - 1);
-  if (parameterIndex >= paramToModels_.size() + offset)
-    throw IndexOutOfBoundsException("SubstitutionModelSet::setParameterToModel.", parameterIndex, offset - 1, paramToModels_.size() + offset - 1);
-  if (modelIndex >= modelSet_.size())
-    throw IndexOutOfBoundsException("SubstitutionModelSet::setParameterToModel.", modelIndex, 0, modelSet_.size() - 1);
-  if (VectorTools::contains(paramToModels_[parameterIndex - offset], modelIndex))
-    throw Exception("SubstitutionModelSet::setParameterToModel: parameter " + getParameter_(parameterIndex - offset).getName() + " already set to model " + TextTools::toString(modelIndex) + ".");
-  paramToModels_[parameterIndex - offset].push_back(modelIndex);
-  modelParameters_[modelIndex].addParameter(
-                                            modelSet_[modelIndex]->getParameters().getParameter(modelParameterNames_[parameterIndex - offset]));
-  //Update value of modified model:
-  modelSet_[modelIndex]->matchParametersValues(getParameters().subList(parameterIndex - offset));
-}
-
-void SubstitutionModelSet::unsetParameterToModel(size_t parameterIndex, size_t modelIndex) throw (IndexOutOfBoundsException, Exception)
-{
-  size_t offset = stationarity_ ? 0 : rootFrequencies_->getNumberOfParameters();
-  if (parameterIndex < offset)
-    throw IndexOutOfBoundsException("SubstitutionModelSet::unsetParameterToModel. Can't unset a root frequency parameter.", parameterIndex, offset - 1, paramToModels_.size() + offset - 1);
-  if (parameterIndex >= paramToModels_.size() + offset)
-    throw IndexOutOfBoundsException("SubstitutionModelSet::unsetParameterToModel.", parameterIndex, offset - 1, paramToModels_.size() + offset - 1);
-  if (modelIndex >= modelSet_.size())
-    throw IndexOutOfBoundsException("SubstitutionModelSet::setParameterToModel.", modelIndex, 0, modelSet_.size() - 1);
-  if (!VectorTools::contains(paramToModels_[parameterIndex - offset], modelIndex))
-    throw Exception("SubstitutionModelSet::unsetParameterToModel: parameter " + getParameter_(parameterIndex).getName() + " is not currently set to model " + TextTools::toString(modelIndex) + ".");
-  remove(paramToModels_[parameterIndex - offset].begin(), paramToModels_[parameterIndex - offset].end(), modelIndex);
-  modelParameters_[modelIndex].deleteParameter(modelParameterNames_[parameterIndex - offset]);
-  checkOrphanModels(true);
-  checkOrphanParameters(true);
-}
-
-void SubstitutionModelSet::addParameter(const Parameter& parameter, const vector<int>& nodesId) throw (Exception)
-{
-  modelParameterNames_.push_back(parameter.getName());
-  Parameter* p = parameter.clone();
-  p->setName(p->getName() + "_" + TextTools::toString(++paramNamesCount_[p->getName()]));
-  addParameter_(p);
-  // Build model indexes:
-  vector<size_t> modelIndexes(nodesId.size());
-  for (size_t i = 0; i < nodesId.size(); ++i)
-  {
-    if (nodeToModel_.find(nodesId[i]) == nodeToModel_.end())
-      throw Exception("SubstitutionModelSet::addParameter. This node has no associated model: " + TextTools::toString(nodesId[i]));
-    size_t pos = nodeToModel_[nodesId[i]];
-    modelParameters_[pos].addParameter(parameter);
-    modelIndexes[i] = pos;
-  }
-  paramToModels_.push_back(modelIndexes);
-  //Update model values:
-  fireParameterChanged(getParameters().subList(p->getName()));
-}
-
-void SubstitutionModelSet::addParameters(const ParameterList& parameters, const vector<int>& nodesId) throw (Exception)
-{
-  for (size_t i = 0; i < parameters.size(); i++)
-    {
-      modelParameterNames_.push_back(parameters[i].getName());
-    }
-  ParameterList pl(parameters);
-  for (size_t i = 0; i < pl.size(); i++)
-    {
-      pl[i].setName(pl[i].getName() + "_" + TextTools::toString(++paramNamesCount_[pl[i].getName()]));
-    }
-  addParameters_(pl);
-  // Build model indexes:
-  vector<size_t> modelIndexes(nodesId.size());
-  map<size_t, size_t> counts; //Check is a model is affected to several nodes.
-  for (size_t i = 0; i < nodesId.size(); i++)
-    {
-      if (nodeToModel_.find(nodesId[i]) == nodeToModel_.end())
-        throw Exception("SubstitutionModelSet::addParameters. This node has no associated model: " + TextTools::toString(nodesId[i]));
-      size_t pos = nodeToModel_[nodesId[i]];
-      size_t count = counts[pos]++;
-      if (count == 0)
-        modelParameters_[pos].addParameters(parameters);
-      modelIndexes[i] = pos;
-    }
-  for (size_t i = 0; i < pl.size(); i++)
-    {
-      paramToModels_.push_back(modelIndexes);
-    }
-  //Update model values:
-  fireParameterChanged(pl);
-}
-
-void SubstitutionModelSet::removeParameter(const string& name) throw (ParameterNotFoundException)
-{
-  size_t offset = stationarity_ ? 0 : rootFrequencies_->getNumberOfParameters();
-  for (size_t i = 0; i < modelParameterNames_.size(); i++)
-    {
-      if (getParameter_(offset + i).getName() == name)
-        {
-          vector<int> nodesId = getNodesWithParameter(name);
-          for (size_t j = 0; j < nodesId.size(); j++)
-            {
-              size_t pos = nodeToModel_[nodesId[j]];
-              string tmp = modelParameterNames_[i];
-              if (modelParameters_[pos].hasParameter(tmp))
-                modelParameters_[pos].deleteParameter(tmp);
-            }
-          paramToModels_.erase(paramToModels_.begin() + i);
-          modelParameterNames_.erase(modelParameterNames_.begin() + i);
-          deleteParameter_(offset + i);
-          return;
-        }
-    }
-  throw ParameterNotFoundException("SubstitutionModelSet::removeParameter.", name);
-}
-
 void SubstitutionModelSet::fireParameterChanged(const ParameterList& parameters)
 {
-  // For now, we actualize all parameters... we'll optimize later!
+  AbstractParameterAliasable::fireParameterChanged(parameters);
+  
   // Update root frequencies:
   updateRootFrequencies();
 
-  // First we actualize the modelParameters_ array:
-  size_t offset = stationarity_ ? 0 : rootFrequencies_->getNumberOfParameters(); // Root frequencies are the first parameters! We should ignore them here.
-  for (size_t i = 0; i < modelParameterNames_.size(); i++)
-    {
-      // Check associations:
-      vector<size_t>* modelIndexes = &paramToModels_[i];
-      for (size_t j = 0; j < modelIndexes->size(); j++)
-        {
-          if (!modelParameters_[(*modelIndexes)[j]].hasParameter(modelParameterNames_[i]))
-            {
-              cerr << "DEBUG: Error, no parameter with name " << modelParameterNames_[i] << " for model " << (*modelIndexes)[j] << endl;
-            }
-          if (offset + i > getNumberOfParameters()) cerr << "DEBUG: Error, missing parameter " << (offset + i) << "/" << getNumberOfParameters() << endl;
-          modelParameters_[(*modelIndexes)[j]].getParameter(modelParameterNames_[i]).setValue(getParameter_(offset + i).getValue());
-        }
-    }
-
   // Then we update all models in the set:
   for (size_t i = 0; i < modelParameters_.size(); i++)
     {
+      for (size_t np = 0 ; np< modelParameters_[i].size() ; np++)
+        {
+          modelParameters_[i][np].setValue(getParameterValue(modelParameters_[i][np].getName()+"_"+TextTools::toString(i+1)));
+        }
       modelSet_[i]->matchParametersValues(modelParameters_[i]);
     }
 }
@@ -408,20 +261,6 @@ bool SubstitutionModelSet::checkOrphanModels(bool throwEx) const
   return true;
 }
 
-bool SubstitutionModelSet::checkOrphanParameters(bool throwEx) const
-  throw (Exception)
-{
-  for (size_t i = 0; i < paramToModels_.size(); i++)
-    {
-      if (paramToModels_[i].size() == 0)
-        {
-          if (throwEx) throw Exception("SubstitutionModelSet::checkOrphanParameters(). Parameter '" + getParameter_(i).getName() + "' is associated to no model.");
-          return false;
-        }
-    }
-  return true;
-}
-
 bool SubstitutionModelSet::checkOrphanNodes(const Tree& tree, bool throwEx) const
   throw (Exception)
 {
diff --git a/src/Bpp/Phyl/Model/SubstitutionModelSet.h b/src/Bpp/Phyl/Model/SubstitutionModelSet.h
index 71c2299..7863ac6 100644
--- a/src/Bpp/Phyl/Model/SubstitutionModelSet.h
+++ b/src/Bpp/Phyl/Model/SubstitutionModelSet.h
@@ -66,18 +66,23 @@ namespace bpp
 /**
  * @brief Substitution models manager for non-homogeneous / non-reversible models of evolution.
  *
- * This class contains a set of substitution models, and their assigment toward the branches of a phylogenetic tree.
- * Each branch in the tree corresponds to a model in the set, but a susbstitution model may correspond to several branches.
- * The particular case where all branches point toward a unique model is the homogeneous case.
+ * This class contains a set of substitution models, and their
+ * assigment toward the branches of a phylogenetic tree. Each branch
+ * in the tree corresponds to a model in the set, but a susbstitution
+ * model may correspond to several branches. The particular case where
+ * all branches point toward a unique model is the homogeneous case.
  *
  * This class also deals with the parameters associated to the models.
- * In the homogeneous case, the parameter list is the same as the list in susbstitution model.
- * When two models at least are specified, these models may have their own parameters or share some of them.
- * To deal with this issue, the SubstitutionModelSet class contains its own parameter list and an index which tells to which
- * models these parameters apply to.
- * Since parameters in a list must have unique names, duplicated names are numbered according to the order in the list.
- * To track the relationships between names in the list and names in each model, the parameter list is duplicated in modelParameters_.
- * The user only act on parameters_, the fireParameterChanged function, automatically called, will update the modelParameters_ field.
+ * In the homogeneous case, the parameter list is the same as the list
+ * in susbstitution model. When two models at least are specified,
+ * these models may have their own parameters or share some of them.
+ * To deal with this issue, the SubstitutionModelSet class contains
+ * its own parameter list, where parameters are numbered according to
+ * the model they belong to.
+ *
+ * The user only act on parameters_, the fireParameterChanged
+ * function, automatically called, will update the modelParameters_
+ * field.
  *
  * In the non-homogeneous and homogeneous non-reversible cases, the likelihood depends on the position of the root.
  * The states frequencies at the root of the tree are hence distinct parameters.
@@ -125,18 +130,6 @@ private:
   mutable std::map<size_t, std::vector<int> > modelToNodes_;
 
   /**
-   * @brief Contains for each parameter in the list the indexes of the corresponding models in modelSet_ that share this parameter.
-   */
-  std::vector< std::vector<size_t> > paramToModels_;
-
-  std::map<std::string, size_t> paramNamesCount_;
-
-  /**
-   * @brief Contains for each parameter in the list the corresponding name in substitution models.
-   */
-  std::vector<std::string> modelParameterNames_;
-
-  /**
    * @brief Parameters for each model in the set.
    *
    * The parameters_ field, inherited from AbstractSubstitutionModel contains all parameters, with unique names.
@@ -162,9 +155,6 @@ public:
     rootFrequencies_(0),
     nodeToModel_(),
     modelToNodes_(),
-    paramToModels_(),
-    paramNamesCount_(),
-    modelParameterNames_(),
     modelParameters_(),
     stationarity_(true)
   {
@@ -185,9 +175,6 @@ public:
     rootFrequencies_(0),
     nodeToModel_(),
     modelToNodes_(),
-    paramToModels_(),
-    paramNamesCount_(),
-    modelParameterNames_(),
     modelParameters_(),
     stationarity_(true)
   {
@@ -238,43 +225,6 @@ public:
   }
 
   /**
-   * @brief Get the index of a given parameter in the list of all parameters.
-   *
-   * @param name The name of the parameter to look for.
-   * @return The position of the parameter in the global parameter list.
-   * @throw ParameterNotFoundException If no parameter with this name is found.
-   */
-  size_t getParameterIndex(const std::string& name) const throw (ParameterNotFoundException)
-  {
-    for (size_t i = 0; i < getNumberOfParameters(); i++)
-    {
-      if (getParameter_(i).getName() == name) return i;
-    }
-    throw ParameterNotFoundException("SubstitutionModelSet::getParameterIndex().", name);
-  }
-
-  /**
-   * @brief Get the model name of a given parameter in the list of all parameters.
-   *
-   * @param name The name of the parameter to look for.
-   * @return The model name of the parameter in the global parameter list.
-   * @throw ParameterNotFoundException If no parameter with this name is found.
-   * @throw Exception If the parameter is not a 'model' parameter (that is, it is a root frequency parameter).
-   */
-  std::string getParameterModelName(const std::string& name) const throw (ParameterNotFoundException, Exception)
-  {
-    size_t pos = getParameterIndex(name);
-    if (stationarity_)
-      return modelParameterNames_[pos];
-    else
-    {
-      size_t rfs = rootFrequencies_->getNumberOfParameters();
-      if (pos < rfs) throw Exception("SubstitutionModelSet::getParameterModelName(). This parameter as no model name: " + name);
-      return modelParameterNames_[pos - rfs];
-    }
-  }
-
-  /**
    * To be called when a parameter has changed.
    * Depending on parameters, this will actualize the _initialFrequencies vector or the corresponding models in the set.
    * @param parameters The modified parameters.
@@ -365,14 +315,8 @@ public:
    * @return The list of nodes with a model containing the specified parameter.
    * @throw ParameterNotFoundException If no parameter with the specified name is found.
    */
-  std::vector<int> getNodesWithParameter(const std::string& name) const throw (ParameterNotFoundException);
 
-  /**
-   * @param name The name of the parameter to look for.
-   * @return The list of model indices containing the specified parameter.
-   * @throw ParameterNotFoundException If no parameter with the specified name is found.
-   */
-  std::vector<size_t> getModelsWithParameter(const std::string& name) const throw (ParameterNotFoundException);
+  std::vector<int> getNodesWithParameter(const std::string& name) const throw (ParameterNotFoundException);
 
   /**
    * @brief Add a new model to the set, and set relationships with nodes and params.
@@ -382,12 +326,7 @@ public:
    * Copy the model first if you don't want it to be lost!
    * @param nodesId the set of nodes in the tree that points toward this model.
    * This will override any previous affectation.
-   * @param newParams The names of the parameters that have to be added to the global list.
-   * These parameters will only be affected to this susbstitution model.
-   * You can use the setParameterToModel function to assign this parameter to an additional model, and the
-   * unsetParameterToModel to remove the relationship with this model for instance.
-   * Parameters not specified in newParams will be ignored, unless you manually assign them to another parameter with
-   * setParameterToModel.
+   *
    * @throw Exception in case of error:
    * <ul>
    * <li>if the new model does not match the alphabet<li>
@@ -395,89 +334,19 @@ public:
    * <li>etc.</li>
    * </ul>
    */
-  void addModel(SubstitutionModel* model, const std::vector<int>& nodesId, const std::vector<std::string>& newParams) throw (Exception);
+  void addModel(SubstitutionModel* model, const std::vector<int>& nodesId);//, const std::vector<std::string>& newParams) throw (Exception);
 
   /**
-   * @brief Change a given model.
-   *
-   * The new model will be copied and will replace the old one.
-   * All previous associations will be kept the same.
-   * @param model A pointer toward a susbstitution model, that will added to the set.
-   * Warning! The set will now be the owner of the pointer, and will destroy it if needed!
-   * Copy the model first if you don't want it to be lost!
-   * @param modelIndex The index of the existing model to replace.
-   */
-  void setModel(SubstitutionModel* model, size_t modelIndex) throw (Exception, IndexOutOfBoundsException);
-
-  /**
-   * @brief Associate an existing model with a given node.
-   *
-   * If the node was was previously associated to a model, the old association is deleted.
-   * If other nodes are associated to this model, the association is conserved.
-   *
-   * @param modelIndex The position of the model in the set.
-   * @param nodeNumber The id of the corresponding node.
-   */
-  void setModelToNode(size_t modelIndex, int nodeNumber) throw (IndexOutOfBoundsException)
-  {
-    if (modelIndex >= nodeToModel_.size()) throw IndexOutOfBoundsException("SubstitutionModelSet::setModelToNode.", modelIndex, 0, nodeToModel_.size() - 1);
-    nodeToModel_[nodeNumber] = modelIndex;
-  }
-
-  /**
-   * @brief Assign a parameter to a model.
-   *
-   * @param parameterIndex The index of the parameter in the list.
-   * @param modelIndex     The index of the model in the list.
-   * @throw IndexOutOfBoundsException If one of the index is not valid.
-   */
-  void setParameterToModel(size_t parameterIndex, size_t modelIndex) throw (IndexOutOfBoundsException);
-
-  /**
-   * @brief Unset a given parameter to the specified model.
-   *
-   * @param parameterIndex The index of the parameter in the list.
-   * @param modelIndex     The index of the model in the list.
-   * @throw IndexOutOfBoundsException If one of the index is not valid.
-   * @throw Exception If the pseicified parameter is not currently associated to the specified model.
-   */
-  void unsetParameterToModel(size_t parameterIndex, size_t modelIndex) throw (IndexOutOfBoundsException, Exception);
-
-  /**
-   * @brief Add a parameter to the list, and link it to specified existing nodes.
-   *
-   * @param parameter The parameter to add. Its name must match model parameter names.
-   * @param nodesId The list of ids of the nodes to link with these parameters.
-   * Nodes must have a corresponding model in the set.
-   * @throw Exception If one of the above requirement is not true.
-   */
-  void addParameter(const Parameter& parameter, const std::vector<int>& nodesId) throw (Exception);
-
-  /**
-   * @brief Add several parameters to the list, and link them to specified existing nodes.
-   *
-   * @param parameters The list of parameters to add. Its name must match model parameter names.
-   * @param nodesId The list of ids of the nodes to link with these parameters.
-   * Nodes must have a corresponding model in the set.
-   * @throw Exception If one of the above requirement is not true.
-   */
-  void addParameters(const ParameterList& parameters, const std::vector<int>& nodesId) throw (Exception);
-
-  /**
-   * @brief Remove a parameter from the list, and unset it to all linked nodes and models.
-   *
-   * @param name The name of the parameter to remove.
-   * @throw ParameterNotFoundException If no parameter with the given name is found in the list.
-   */
-  void removeParameter(const std::string& name) throw (ParameterNotFoundException);
-
-  /**
-   * @brief Remove a model from the set, and all corresponding parameters.
+   * @brief Replace a model in the set, and all corresponding
+   * parameters. The replaced model deleted.
    *
    * @param modelIndex The index of the model in the set.
+   * @param model the new model. This model will be owned by the Set.
+   *
    * @throw Exception if a parameter becomes orphan because of the removal.
    */
-  void removeModel(size_t modelIndex) throw (Exception);
+
+  void replaceModel(size_t modelIndex, SubstitutionModel* model) throw (Exception);
 
   void listModelNames(std::ostream& out = std::cout) const;
 
@@ -541,6 +410,43 @@ public:
   const Alphabet* getAlphabet() const { return alphabet_; }
 
   /**
+   * @return The supported states of the model set, as a vector of int codes.
+   *
+   * @see Alphabet
+   */
+  virtual const std::vector<int>& getAlphabetStates() const {
+    return getModel(0)->getAlphabetStates();
+  }
+
+  virtual const StateMap& getStateMap() const {
+    return getModel(0)->getStateMap();
+  }
+
+  virtual std::vector<size_t> getModelStates(int code) const {
+    return getModel(0)->getModelStates(code);
+  }
+
+  virtual std::vector<size_t> getModelStates(const std::string& code) const {
+    return getModel(0)->getModelStates(code);
+  }
+
+  /**
+   * @param index The model state.
+   * @return The corresponding alphabet state as character code.
+   */
+  virtual int getAlphabetStateAsInt(size_t index) const {
+    return getModel(0)->getAlphabetStateAsInt(index);
+  }
+  
+  /**
+   * @param index The model state.
+   * @return The corresponding alphabet state as character code.
+   */
+  virtual std::string getAlphabetStateAsChar(size_t index) const {
+    return getModel(0)->getAlphabetStateAsChar(index);
+  }
+
+  /**
    * @brief Check if the model set is fully specified for a given tree.
    *
    * This include:
@@ -555,7 +461,7 @@ public:
   bool isFullySetUpFor(const Tree& tree, bool throwEx = true) const throw (Exception)
   {
     return checkOrphanModels(throwEx)
-           && checkOrphanParameters(throwEx)
+      //           && checkOrphanParameters(throwEx)
            && checkOrphanNodes(tree, throwEx)
            && checkUnknownNodes(tree, throwEx);
   }
@@ -577,8 +483,6 @@ protected:
    */
   bool checkOrphanModels(bool throwEx) const throw (Exception);
 
-  bool checkOrphanParameters(bool throwEx) const throw (Exception);
-
   bool checkOrphanNodes(const Tree& tree, bool throwEx) const throw (Exception);
 
   bool checkUnknownNodes(const Tree& tree, bool throwEx) const throw (Exception);
diff --git a/src/Bpp/Phyl/Model/SubstitutionModelSetTools.cpp b/src/Bpp/Phyl/Model/SubstitutionModelSetTools.cpp
index 35a3cf5..1da9ddd 100644
--- a/src/Bpp/Phyl/Model/SubstitutionModelSetTools.cpp
+++ b/src/Bpp/Phyl/Model/SubstitutionModelSetTools.cpp
@@ -73,7 +73,7 @@ SubstitutionModelSet* SubstitutionModelSetTools::createHomogeneousModelSet(
     }
   }
   ids.erase(ids.begin() + pos);
-  modelSet->addModel(model, ids, model->getParameters().getParameterNames());
+  modelSet->addModel(model, ids);
 
   return modelSet;
 }
@@ -178,15 +178,21 @@ SubstitutionModelSet* SubstitutionModelSetTools::createNonHomogeneousModelSet(
     }
   }
 
-  ids.erase(ids.begin() + pos);
+  ids.erase(ids.begin() + static_cast<ptrdiff_t>(pos));
   for (i = 0; i < ids.size(); i++)
   {
-    modelSet->addModel(dynamic_cast<SubstitutionModel*>(model->clone()), vector<int>(1, ids[i]), branchParameters.getParameterNames());
+    modelSet->addModel(dynamic_cast<SubstitutionModel*>(model->clone()), vector<int>(1, ids[i]));
   }
 
-  // Now add global parameters to all nodes:
-  modelSet->addParameters(globalParameters, ids);
+  // Now alias all global parameters on all nodes:
+  for (i=0; i < globalParameters.size(); i++)
+    {
+      string pname=globalParameters[i].getName();
 
+      for (size_t nn = 1; nn < ids.size(); nn++)
+        modelSet->aliasParameters(pname+"_1",pname+"_"+TextTools::toString(nn+1));
+    }
+  
   // Defines the hypernodes if mixed
   if (mixed)
   {
diff --git a/src/Bpp/Phyl/Model/TS98.h b/src/Bpp/Phyl/Model/TS98.h
index 48208af..667348a 100644
--- a/src/Bpp/Phyl/Model/TS98.h
+++ b/src/Bpp/Phyl/Model/TS98.h
@@ -5,7 +5,7 @@
 //
 
 /*
-  Copyright or © or Copr. CNRS, (November 16, 2004)
+  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.
@@ -86,13 +86,9 @@ namespace bpp
      * @param s2    Second rate parameter.
      * @param normalizeRateChanges Tell if the rate transition matrix should be normalized.
      */
-    TS98(ReversibleSubstitutionModel * model, double s1 = 1., double s2 = 1., bool normalizeRateChanges = false):
-      MarkovModulatedSubstitutionModel(model, normalizeRateChanges, "TS98.")
+    TS98(ReversibleSubstitutionModel* model, double s1 = 1., double s2 = 1., bool normalizeRateChanges = false):
+      MarkovModulatedSubstitutionModel(model, 2, normalizeRateChanges, "TS98.")
     {
-      nbRates_ = 2;
-      ratesExchangeability_.resize(2, 2);
-      rates_.resize(2, 2);
-      ratesFreq_.resize(2);
       addParameter_(new Parameter("TS98.s1", s1, &Parameter::R_PLUS_STAR));
       addParameter_(new Parameter("TS98.s2", s2, &Parameter::R_PLUS_STAR));
       updateRatesModel();
diff --git a/src/Bpp/Phyl/Model/WordSubstitutionModel.cpp b/src/Bpp/Phyl/Model/WordSubstitutionModel.cpp
index 5f10c0c..976f873 100644
--- a/src/Bpp/Phyl/Model/WordSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/WordSubstitutionModel.cpp
@@ -58,12 +58,10 @@ using namespace std;
 
 WordSubstitutionModel::WordSubstitutionModel(
   const std::vector<SubstitutionModel*>& modelVector,
-  const std::string& st) :
-  AbstractParameterAliasable((st == "") ? "Word." : st),
-  AbstractSubstitutionModel(AbstractWordSubstitutionModel::extractAlph(modelVector),
-                            (st == "") ? "Word." : st),
+  const std::string& prefix) :
+  AbstractParameterAliasable((prefix == "") ? "Word." : prefix),
   AbstractWordSubstitutionModel(modelVector,
-                                (st == "") ? "Word." : st)
+                                (prefix == "") ? "Word." : prefix)
 {
   size_t i, nbmod = VSubMod_.size();
 
@@ -78,24 +76,20 @@ WordSubstitutionModel::WordSubstitutionModel(
 
 WordSubstitutionModel::WordSubstitutionModel(
   const Alphabet* alph,
-  const std::string& st) :
-  AbstractParameterAliasable((st == "") ? "Word." : st),
-  AbstractSubstitutionModel(alph,
-                            (st == "") ? "Word." : st),
-  AbstractWordSubstitutionModel(alph,
-                                (st == "") ? "Word." : st)
+  StateMap* stateMap,
+  const std::string& prefix) :
+  AbstractParameterAliasable((prefix == "") ? "Word." : prefix),
+  AbstractWordSubstitutionModel(alph, stateMap, (prefix == "") ? "Word." : prefix)
 {}
 
 WordSubstitutionModel::WordSubstitutionModel(
   SubstitutionModel* pmodel,
   unsigned int num,
-  const std::string& st) :
-  AbstractParameterAliasable((st == "") ? "Word." : st),
-  AbstractSubstitutionModel(pmodel->getAlphabet(),
-                            (st == "") ? "Word." : st),
+  const std::string& prefix) :
+  AbstractParameterAliasable((prefix == "") ? "Word." : prefix),
   AbstractWordSubstitutionModel(pmodel,
                                 num,
-                                (st == "") ? "Word." : st)
+                                (prefix == "") ? "Word." : prefix)
 {
   size_t i;
 
@@ -137,10 +131,10 @@ void WordSubstitutionModel::completeMatrices()
   {
     freq_[i] = 1;
     j = i;
-    for (p = nbmod - 1; p >= 0; p--)
+    for (p = nbmod; p > 0; p--)
     {
-      m = VSubMod_[p]->getNumberOfStates();
-      freq_[i] *= VSubMod_[p]->getFrequencies()[j % m];
+      m = VSubMod_[p-1]->getNumberOfStates();
+      freq_[i] *= VSubMod_[p-1]->getFrequencies()[j % m];
       j /= m;
     }
   }
diff --git a/src/Bpp/Phyl/Model/WordSubstitutionModel.h b/src/Bpp/Phyl/Model/WordSubstitutionModel.h
index fe32fbb..9227e27 100644
--- a/src/Bpp/Phyl/Model/WordSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/WordSubstitutionModel.h
@@ -84,9 +84,9 @@ public:
    *   the models must be different objects to avoid parameters
    *   redundancy, otherwise only the first model is used. The used models
    *   are owned by the instance.
-   * @param st the Namespace.
+   * @param prefix the Namespace.
    */
-  WordSubstitutionModel(const std::vector<SubstitutionModel*>& modelVector, const std::string& st = "");
+  WordSubstitutionModel(const std::vector<SubstitutionModel*>& modelVector, const std::string& prefix = "");
 
   /**
    * @brief Build a new WordSubstitutionModel object from a
@@ -96,20 +96,20 @@ public:
    * @param pmodel pointer to the substitution model to use in all the
    *  positions. It is owned by the instance.
    * @param num The number of models involved.
-   * @param st the Namespace.
+   * @param prefix the Namespace.
    */
-  WordSubstitutionModel(SubstitutionModel* pmodel, unsigned int num, const std::string& st = "");
+  WordSubstitutionModel(SubstitutionModel* pmodel, unsigned int num, const std::string& prefix = "");
 
   virtual ~WordSubstitutionModel() {}
 
   WordSubstitutionModel* clone() const { return new WordSubstitutionModel(*this); }
 
 protected:
+  
   /**
-   *@brief Constructor for the derived classes only
+   * @brief Constructor for the derived classes only
    */
-
-  WordSubstitutionModel(const Alphabet* alph, const std::string& = "");
+  WordSubstitutionModel(const Alphabet* alph, StateMap* stateMap, const std::string& prefix = "");
 
   virtual void updateMatrices();
   virtual void completeMatrices();
diff --git a/src/Bpp/Phyl/NNITopologySearch.cpp b/src/Bpp/Phyl/NNITopologySearch.cpp
index 668a5dd..c8cb7ef 100644
--- a/src/Bpp/Phyl/NNITopologySearch.cpp
+++ b/src/Bpp/Phyl/NNITopologySearch.cpp
@@ -107,9 +107,9 @@ void NNITopologySearch::searchFast() throw (Exception)
     {
       // !!! must not reach i==0 because of size_t
       if (!(nodesSub[i - 1]->hasFather()))
-        nodesSub.erase(nodesSub.begin() + i - 1);  // Remove root node.
+        nodesSub.erase(nodesSub.begin() + static_cast<ptrdiff_t>(i - 1));  // Remove root node.
       else if (!(nodesSub[i - 1]->getFather()->hasFather()))
-        nodesSub.erase(nodesSub.begin() + i - 1);  // Remove son of root node.
+        nodesSub.erase(nodesSub.begin() + static_cast<ptrdiff_t>(i - 1));  // Remove son of root node.
     }
 
     // Test all NNIs:
@@ -161,9 +161,9 @@ void NNITopologySearch::searchBetter() throw (Exception)
     for (size_t i = nodesSub.size(); i > 0; i--)
     { // !!! must not reach i==0 because of size_t
       if (!(nodesSub[i - 1]->hasFather()))
-        nodesSub.erase(nodesSub.begin() + i - 1);  // Remove root node.
+        nodesSub.erase(nodesSub.begin() + static_cast<ptrdiff_t>(i - 1));  // Remove root node.
       else if (!(nodesSub[i - 1]->getFather()->hasFather()))
-        nodesSub.erase(nodesSub.begin() + i - 1);  // Remove son of root node.
+        nodesSub.erase(nodesSub.begin() + static_cast<ptrdiff_t>(i - 1));  // Remove son of root node.
     }
 
     // Test all NNIs:
@@ -225,9 +225,9 @@ void NNITopologySearch::searchPhyML() throw (Exception)
     {
       // !!! must not reach i==0 because of size_t
       if (!(nodesSub[i - 1]->hasFather()))
-        nodesSub.erase(nodesSub.begin() + i - 1);  // Remove root node.
+        nodesSub.erase(nodesSub.begin() + static_cast<ptrdiff_t>(i - 1));  // Remove root node.
       else if (!(nodesSub[i - 1]->getFather()->hasFather()))
-        nodesSub.erase(nodesSub.begin() + i - 1);  // Remove son of root node.
+        nodesSub.erase(nodesSub.begin() + static_cast<ptrdiff_t>(i - 1));  // Remove son of root node.
     }
 
     // Test all NNIs:
@@ -262,9 +262,9 @@ void NNITopologySearch::searchPhyML() throw (Exception)
             // These are incompatible NNIs. We only keep the best:
             if (diff < improvement[j - 1])
             { // Erase previous node
-              improvingNodes.erase(improvingNodes.begin() + j - 1);
-              improving.erase(improving.begin() + j - 1);
-              improvement.erase(improvement.begin() + j - 1);
+              improvingNodes.erase(improvingNodes.begin() + static_cast<ptrdiff_t>(j - 1));
+              improving.erase(improving.begin() + static_cast<ptrdiff_t>(j - 1));
+              improvement.erase(improvement.begin() + static_cast<ptrdiff_t>(j - 1));
             } // Otherwise forget about this NNI.
             else
             {
@@ -285,9 +285,9 @@ void NNITopologySearch::searchPhyML() throw (Exception)
           }
           if (pos < improvement.size())
           {
-            improvingNodes.insert(improvingNodes.begin() + pos, node);
-            improving.insert(improving.begin() + pos, node->getId());
-            improvement.insert(improvement.begin() + pos, diff);
+            improvingNodes.insert(improvingNodes.begin() + static_cast<ptrdiff_t>(pos), node);
+            improving.insert(improving.begin() + static_cast<ptrdiff_t>(pos), node->getId());
+            improvement.insert(improvement.begin() + static_cast<ptrdiff_t>(pos), diff);
           }
           else
           {
@@ -348,8 +348,8 @@ void NNITopologySearch::searchPhyML() throw (Exception)
             throw Exception("NNITopologySearch::searchPhyML. Error, no improving NNI!\n This may be due to a change in parameters between testNNI and doNNI. Check your code!");
           }
           size_t n = (size_t)ceil((double)improving.size() / 2.);
-          improving.erase(improving.begin() + n, improving.end());
-          improvement.erase(improvement.begin() + n, improvement.end());
+          improving.erase(improving.begin() + static_cast<ptrdiff_t>(n), improving.end());
+          improvement.erase(improvement.begin() + static_cast<ptrdiff_t>(n), improvement.end());
         }
         else
         {
diff --git a/src/Bpp/Phyl/Node.h b/src/Bpp/Phyl/Node.h
index 3a2f013..65b6244 100644
--- a/src/Bpp/Phyl/Node.h
+++ b/src/Bpp/Phyl/Node.h
@@ -53,6 +53,7 @@
 #include <map>
 #include <iostream>
 #include <algorithm>
+#include <cstddef>
 
 namespace bpp
 {
@@ -408,7 +409,7 @@ public:
     if (!node)
       throw NullPointerException("Node::addSon(). Empty node given as input.");
     if (find(sons_.begin(), sons_.end(), node) == sons_.end())
-      sons_.insert(sons_.begin() + pos, node);
+      sons_.insert(sons_.begin() + static_cast<ptrdiff_t>(pos), node);
     else // Otherwise node is already present.
       std::cerr << "DEVEL warning: Node::addSon. Son node already registered! No pb here, but could be a bug in your implementation..." << std::endl;
 
@@ -433,7 +434,7 @@ public:
     if (pos >= sons_.size())
       throw IndexOutOfBoundsException("Node::setSon(). Invalid node position.", pos, 0, sons_.size() - 1);
     std::vector<Node*>::iterator search = find(sons_.begin(), sons_.end(), node);
-    if (search == sons_.end() || search == sons_.begin() + pos)
+    if (search == sons_.end() || search == sons_.begin() + static_cast<ptrdiff_t>(pos))
       sons_[pos] = node;
     else
       throw NodePException("Node::setSon. Trying to set a node which is already present.");
@@ -445,7 +446,7 @@ public:
     if (pos >= sons_.size())
       throw IndexOutOfBoundsException("Node::removeSon(). Invalid node position.", pos, 0, sons_.size() - 1);
     Node* node = sons_[pos];
-    sons_.erase(sons_.begin() + pos);
+    sons_.erase(sons_.begin() + static_cast<ptrdiff_t>(pos));
     node->removeFather();
     return node;
   }
@@ -458,7 +459,7 @@ public:
     {
       if (sons_[i] == node)
       {
-        sons_.erase(sons_.begin() + i);
+        sons_.erase(sons_.begin() + static_cast<ptrdiff_t>(i));
         node->removeFather();
         return;
       }
@@ -494,9 +495,9 @@ public:
    *
    * @{
    */
-  Node* operator[](int i) { return (i < 0) ? father_ : sons_[i]; }
+  Node* operator[](int i) { return (i < 0) ? father_ : sons_[static_cast<size_t>(i)]; }
 
-  const Node* operator[](int i) const { return (i < 0) ? father_ : sons_[i]; }
+  const Node* operator[](int i) const { return (i < 0) ? father_ : sons_[static_cast<size_t>(i)]; }
 
   /** @} */
 
diff --git a/src/Bpp/Phyl/OptimizationTools.cpp b/src/Bpp/Phyl/OptimizationTools.cpp
index 5a7e39c..213a5ca 100644
--- a/src/Bpp/Phyl/OptimizationTools.cpp
+++ b/src/Bpp/Phyl/OptimizationTools.cpp
@@ -121,7 +121,7 @@ throw (ParameterException)
 unsigned int OptimizationTools::optimizeTreeScale(
   TreeLikelihood* tl,
   double tolerance,
-  int tlEvalMax,
+  unsigned int tlEvalMax,
   OutputStream* messageHandler,
   OutputStream* profiler,
   unsigned int verbose)
@@ -245,7 +245,7 @@ throw (Exception)
     ApplicationTools::displayMessage("\n");
 
   // We're done.
-  int nb = poptimizer->getNumberOfEvaluations();
+  unsigned int nb = poptimizer->getNumberOfEvaluations();
   delete poptimizer;
   return nb;
 }
@@ -299,7 +299,7 @@ throw (Exception)
   {
     fnum.reset(new TwoPointsNumericalDerivative(f));
     fnum->setInterval(0.0000001);
-    optimizer.reset(new ConjugateGradientMultiDimensions(reinterpret_cast<DerivableFirstOrder*>(fnum.get()))); // Removes strict-aliasing warning with gcc 4.4
+    optimizer.reset(new ConjugateGradientMultiDimensions(fnum.get()));
   }
   else if (optMethodDeriv == OPTIMIZATION_NEWTON)
   {
@@ -567,7 +567,7 @@ NNIHomogeneousTreeLikelihood* OptimizationTools::optimizeTreeNNI(
   bool optimizeNumFirst,
   double tolBefore,
   double tolDuring,
-  int tlEvalMax,
+  unsigned int tlEvalMax,
   unsigned int numStep,
   OutputStream* messageHandler,
   OutputStream* profiler,
@@ -600,7 +600,7 @@ NNIHomogeneousTreeLikelihood* OptimizationTools::optimizeTreeNNI2(
   bool optimizeNumFirst,
   double tolBefore,
   double tolDuring,
-  int tlEvalMax,
+  unsigned int tlEvalMax,
   unsigned int numStep,
   OutputStream* messageHandler,
   OutputStream* profiler,
diff --git a/src/Bpp/Phyl/OptimizationTools.h b/src/Bpp/Phyl/OptimizationTools.h
index 13c2326..36b3268 100644
--- a/src/Bpp/Phyl/OptimizationTools.h
+++ b/src/Bpp/Phyl/OptimizationTools.h
@@ -84,7 +84,7 @@ class NaNListener: public OptimizationListener
     void optimizationInitializationPerformed(const OptimizationEvent &event) {}
     void optimizationStepPerformed(const OptimizationEvent &event) throw (Exception)
     {
-      if (isnan(optimizer_->getFunction()->getValue()))
+      if (std::isnan(optimizer_->getFunction()->getValue()))
       {
          cerr << "Oups... something abnormal happened!" << endl;
          function_->getParameters().printParameters(cerr);
@@ -567,7 +567,7 @@ public:
   static unsigned int optimizeTreeScale(
     TreeLikelihood* tl,
     double tolerance = 0.000001,
-    int tlEvalMax = 1000000,
+    unsigned int tlEvalMax = 1000000,
     OutputStream* messageHandler = ApplicationTools::message,
     OutputStream* profiler       = ApplicationTools::message,
     unsigned int verbose = 1)
@@ -618,7 +618,7 @@ public:
     bool optimizeNumFirst        = true,
     double tolBefore             = 100,
     double tolDuring             = 100,
-    int tlEvalMax                = 1000000,
+    unsigned int tlEvalMax       = 1000000,
     unsigned int numStep         = 1,
     OutputStream* messageHandler = ApplicationTools::message,
     OutputStream* profiler       = ApplicationTools::message,
@@ -673,7 +673,7 @@ public:
     bool optimizeNumFirst        = true,
     double tolBefore             = 100,
     double tolDuring             = 100,
-    int tlEvalMax                = 1000000,
+    unsigned int tlEvalMax       = 1000000,
     unsigned int numStep         = 1,
     OutputStream* messageHandler = ApplicationTools::message,
     OutputStream* profiler       = ApplicationTools::message,
diff --git a/src/Bpp/Phyl/Parsimony/AbstractTreeParsimonyScore.cpp b/src/Bpp/Phyl/Parsimony/AbstractTreeParsimonyScore.cpp
index 1969c9f..1b808d4 100755
--- a/src/Bpp/Phyl/Parsimony/AbstractTreeParsimonyScore.cpp
+++ b/src/Bpp/Phyl/Parsimony/AbstractTreeParsimonyScore.cpp
@@ -59,7 +59,7 @@ throw (Exception) :
   nbStates_(0)
 {
   statesMap_ = new CanonicalStateMap(alphabet_, includeGaps);
-  nbStates_  = statesMap_->getNumberOfStates();
+  nbStates_  = statesMap_->getNumberOfModelStates();
   init_(data, verbose);
 }
 
@@ -74,7 +74,7 @@ throw (Exception) :
   data_(0),
   alphabet_(data.getAlphabet()),
   statesMap_(statesMap),
-  nbStates_(statesMap->getNumberOfStates())
+  nbStates_(statesMap->getNumberOfModelStates())
 {
   init_(data, verbose);
 }
diff --git a/src/Bpp/Phyl/Parsimony/DRTreeParsimonyData.cpp b/src/Bpp/Phyl/Parsimony/DRTreeParsimonyData.cpp
index fc19e0d..5ce6546 100644
--- a/src/Bpp/Phyl/Parsimony/DRTreeParsimonyData.cpp
+++ b/src/Bpp/Phyl/Parsimony/DRTreeParsimonyData.cpp
@@ -89,7 +89,7 @@ DRTreeParsimonyData& DRTreeParsimonyData::operator=(const DRTreeParsimonyData& d
 /******************************************************************************/
 void DRTreeParsimonyData::init(const SiteContainer& sites, const StateMap& stateMap) throw (Exception)
 {
-  nbStates_         = stateMap.getNumberOfStates();
+  nbStates_         = stateMap.getNumberOfModelStates();
   nbSites_          = sites.getNumberOfSites();
   SitePatterns pattern(&sites);
   shrunkData_       = pattern.getSites();
@@ -138,9 +138,9 @@ void DRTreeParsimonyData::init(const Node* node, const SiteContainer& sites, con
         // otherwise value set to 0:
         int state = seq->getValue(i);
         vector<int> states = alphabet->getAlias(state);
-        for (unsigned int j = 0; j < states.size(); j++)
+        for (size_t j = 0; j < states.size(); j++)
         {
-          if (stateMap.stateAsInt(s) == states[j])
+          if (stateMap.getAlphabetStateAsInt(s) == states[j])
             (*leafData_bitsets_i)[s].flip();
         }
       }
diff --git a/src/Bpp/Phyl/Simulation/DetailedSiteSimulator.h b/src/Bpp/Phyl/Simulation/DetailedSiteSimulator.h
index 2a659cc..58cf4ab 100644
--- a/src/Bpp/Phyl/Simulation/DetailedSiteSimulator.h
+++ b/src/Bpp/Phyl/Simulation/DetailedSiteSimulator.h
@@ -64,13 +64,13 @@ class SiteSimulationResult
     mutable std::map<int, size_t> indexes_;
     size_t currentIndex_;
     std::vector<MutationPath> paths_;
-    std::vector<int> ancestralStates_;
+    std::vector<size_t> ancestralStates_;
     const Tree* tree_;
     std::vector<int> leavesId_;
     const Alphabet* alphabet_;
     
   public:
-    SiteSimulationResult(const Tree* tree, const Alphabet* alphabet, int ancestralState) :
+    SiteSimulationResult(const Tree* tree, const Alphabet* alphabet, size_t ancestralState) :
       indexes_        (),
       currentIndex_   (0),
       paths_          (),
@@ -122,9 +122,9 @@ class SiteSimulationResult
       ancestralStates_.push_back(path.getFinalState());
     }
 
-    virtual int getAncestralState(size_t i)    const { return ancestralStates_[i]; }
+    virtual size_t getAncestralState(size_t i) const { return ancestralStates_[i]; }
 
-    virtual int getAncestralState(int nodeId) const { return ancestralStates_[1 + indexes_[nodeId]]; }
+    virtual size_t getAncestralState(int nodeId) const { return ancestralStates_[1 + indexes_[nodeId]]; }
 
     virtual const MutationPath& getMutationPath(size_t i) const { return paths_[i]; }
 
@@ -156,10 +156,10 @@ class SiteSimulationResult
     /**
      * @return The states at the leaves.
      */
-    virtual std::vector<int> getFinalStates() const
+    virtual std::vector<size_t> getFinalStates() const
     {
       size_t n = leavesId_.size(); 
-      std::vector<int> states(n);
+      std::vector<size_t> states(n);
       for (size_t i = 0; i < n; i++)
       {
         states[i] = ancestralStates_[1 + indexes_[leavesId_[i]]];
@@ -170,7 +170,14 @@ class SiteSimulationResult
     /**
      * @return The site corresponding to this simulation.
      */
-    virtual Site* getSite() const { return new Site(getFinalStates(), alphabet_); }
+    virtual Site* getSite(const SubstitutionModel& model) const {
+      std::vector<size_t> mstates = getFinalStates();
+      std::vector<int> astates(mstates.size());
+      for (size_t i = 0; i < mstates.size(); ++i) {
+        astates[i] = model.getAlphabetStateAsInt(mstates[i]);
+      }
+      return new Site(astates, alphabet_);
+    }
 
     /**
      * @return A vector with the leaves names.
@@ -203,8 +210,8 @@ class RASiteSimulationResult:
     double rate_;
     
   public:
-    RASiteSimulationResult(const Tree* tree, const Alphabet * alphabet, int ancestralState, double rate):
-      SiteSimulationResult(tree, alphabet, ancestralState),
+    RASiteSimulationResult(const Tree* tree, const Alphabet * alphabet, size_t ancestralStateIndex, double rate):
+      SiteSimulationResult(tree, alphabet, ancestralStateIndex),
       rate_(rate) {}
 
     virtual ~RASiteSimulationResult() {}
@@ -237,10 +244,10 @@ class DetailedSiteSimulator:
      * @return A SiteSimulationResult object with all ancestral
      * states for all nodes and branches.
      */
-    virtual SiteSimulationResult* dSimulate() const = 0;
-    virtual SiteSimulationResult* dSimulate(int ancestralState) const = 0;
-    virtual SiteSimulationResult* dSimulate(int ancestralState, double rate) const = 0;
-    virtual SiteSimulationResult* dSimulate(double rate) const = 0;
+    virtual SiteSimulationResult* dSimulateSite() const = 0;
+    virtual SiteSimulationResult* dSimulateSite(size_t ancestralStateIndex) const = 0;
+    virtual SiteSimulationResult* dSimulateSite(size_t ancestralStateIndex, double rate) const = 0;
+    virtual SiteSimulationResult* dSimulateSite(double rate) const = 0;
     
 };
 
diff --git a/src/Bpp/Phyl/Simulation/MutationProcess.cpp b/src/Bpp/Phyl/Simulation/MutationProcess.cpp
index cdd0621..135ebc9 100644
--- a/src/Bpp/Phyl/Simulation/MutationProcess.cpp
+++ b/src/Bpp/Phyl/Simulation/MutationProcess.cpp
@@ -45,10 +45,11 @@
 using namespace bpp;
 
 /******************************************************************************/
-int AbstractMutationProcess::mutate(int state) const
+
+size_t AbstractMutationProcess::mutate(size_t state) const
 {
   double alea = RandomTools::giveRandomNumberBetweenZeroAndEntry(1.0);
-  for (unsigned int j = 0; j < size_; j++)
+  for (size_t j = 0; j < size_; j++)
   {
     if (alea < repartition_[state][j]) return j;
   }
@@ -56,13 +57,14 @@ int AbstractMutationProcess::mutate(int state) const
 }
 
 /******************************************************************************/
-int AbstractMutationProcess::mutate(int state, unsigned int n) const
+
+size_t AbstractMutationProcess::mutate(size_t state, unsigned int n) const
 {
-  int s = state;
+  size_t s = state;
   for (unsigned int k = 0; k < n; k++)
   {
     double alea = RandomTools::giveRandomNumberBetweenZeroAndEntry(1.0);
-    for (unsigned int j = 1; j < size_ + 1; j++)
+    for (size_t j = 1; j < size_ + 1; j++)
     {
       if (alea < repartition_[s][j])
       {
@@ -75,16 +77,18 @@ int AbstractMutationProcess::mutate(int state, unsigned int n) const
 }
 
 /******************************************************************************/
-double AbstractMutationProcess::getTimeBeforeNextMutationEvent(int state) const
+
+double AbstractMutationProcess::getTimeBeforeNextMutationEvent(size_t state) const
 {
-  return RandomTools::randExponential(-1./model_->Qij(state, state));
+  return RandomTools::randExponential(-1. / model_->Qij(state, state));
 }
 
 /******************************************************************************/
-int AbstractMutationProcess::evolve(int initialState, double time) const
+
+size_t AbstractMutationProcess::evolve(size_t initialState, double time) const
 {
   double t = 0;
-  int currentState = initialState;
+  size_t currentState = initialState;
   t += getTimeBeforeNextMutationEvent(currentState);
   while (t < time)
   {
@@ -95,11 +99,12 @@ int AbstractMutationProcess::evolve(int initialState, double time) const
 }
 
 /******************************************************************************/
-MutationPath AbstractMutationProcess::detailedEvolve(int initialState, double time) const
+
+MutationPath AbstractMutationProcess::detailedEvolve(size_t initialState, double time) const
 {
   MutationPath mp(model_->getAlphabet(), initialState, time);
   double t = 0;
-  int currentState = initialState;
+  size_t currentState = initialState;
   t += getTimeBeforeNextMutationEvent(currentState);
   while (t < time)
   {
@@ -121,16 +126,16 @@ SimpleMutationProcess::SimpleMutationProcess(const SubstitutionModel* model) :
 
   // We will now initiate each of these probability vector.
   RowMatrix<double> Q = model->getGenerator();
-  for (unsigned int i = 0; i < size_; i++)
+  for (size_t i = 0; i < size_; i++)
   {
     repartition_[i] = Vdouble(size_);
     double cum = 0;
     double sum_Q = 0;
-    for (unsigned int j = 0; j < size_; j++)
+    for (size_t j = 0; j < size_; j++)
     {
       if (j != i) sum_Q += Q(i, j);
     }
-    for (unsigned int j = 0; j < size_; j++)
+    for (size_t j = 0; j < size_; j++)
     {
       if (j != i)
       {
@@ -148,17 +153,18 @@ SimpleMutationProcess::SimpleMutationProcess(const SubstitutionModel* model) :
 SimpleMutationProcess::~SimpleMutationProcess() {}
 
 /******************************************************************************/
-int SimpleMutationProcess::evolve(int initialState, double time) const
+
+size_t SimpleMutationProcess::evolve(size_t initialState, double time) const
 {
   // Compute all cumulative pijt:
   Vdouble pijt(size_);
   pijt[0] = model_->Pij_t(initialState, 0, time);
-  for (unsigned int i = 1; i < size_; i++)
+  for (size_t i = 1; i < size_; i++)
   {
     pijt[i] = pijt[i - 1] + model_->Pij_t(initialState, i, time);
   }
   double rand = RandomTools::giveRandomNumberBetweenZeroAndEntry(1);
-  for (unsigned int i = 0; i < size_; i++)
+  for (size_t i = 0; i < size_; i++)
   {
     if (rand < pijt[i]) return i;
   }
@@ -167,7 +173,7 @@ int SimpleMutationProcess::evolve(int initialState, double time) const
 
 /******************************************************************************/
 
-SelfMutationProcess::SelfMutationProcess(int alphabetSize) :
+SelfMutationProcess::SelfMutationProcess(size_t alphabetSize) :
   AbstractMutationProcess(0)
 {
   size_ = alphabetSize;
diff --git a/src/Bpp/Phyl/Simulation/MutationProcess.h b/src/Bpp/Phyl/Simulation/MutationProcess.h
index 060e7be..0883831 100644
--- a/src/Bpp/Phyl/Simulation/MutationProcess.h
+++ b/src/Bpp/Phyl/Simulation/MutationProcess.h
@@ -55,44 +55,44 @@ namespace bpp
  */
 class MutationPath
 {
-	private:
+  private:
 
     const Alphabet* alphabet_;
 
-		/**
-		 * @brief The states taken, without intiial state.
-		 */
-    std::vector<int> states_;
+    /**
+     * @brief The states taken, without initial state.
+     */
+    std::vector<size_t> states_;
 
-		/**
-		 * @brief Times between states.
-		 * The first element in array is the time between the initial state and the first state in states_.
-		 */
+    /**
+     * @brief Times between states.
+     * The first element in array is the time between the initial state and the first state in states_.
+     */
     std::vector<double> times_;
-		
-		/**
-		 * @brief The initial state.
-		 */
-		int initialState_;
-
-		/**
-		 * @brief Total time of evolution.
-		 * Typically, this is a branch length.
-		 */
-		double totalTime_;
-
-	public:
-
-		/**
-		 * @brief Builds a new MutationPath object with initial state 'initialState' and total time 'time'.
-		 *
+    
+    /**
+     * @brief The initial state.
+     */
+    size_t initialState_;
+
+    /**
+     * @brief Total time of evolution.
+     * Typically, this is a branch length.
+     */
+    double totalTime_;
+
+  public:
+
+    /**
+     * @brief Builds a new MutationPath object with initial state 'initialState' and total time 'time'.
+     *
      * @param alphabet     The alphabet associated to the states in this path.
-		 * @param initialState The initial state.
-		 * @param time         The total time of evolution.
-		 */
-		MutationPath(const Alphabet* alphabet, int initialState, double time) :
+     * @param initialState The initial state.
+     * @param time         The total time of evolution.
+     */
+    MutationPath(const Alphabet* alphabet, size_t initialState, double time) :
       alphabet_(alphabet), states_(), times_(), initialState_(initialState), totalTime_(time) {};
-		
+    
     MutationPath(const MutationPath& path) :
       alphabet_(path.alphabet_), states_(path.states_), times_(path.times_), initialState_(path.initialState_), totalTime_(path.totalTime_) {};
 
@@ -105,46 +105,46 @@ class MutationPath
       return *this;
     }
 
-		virtual ~MutationPath() {};
+    virtual ~MutationPath() {};
 
-	public:
-	
+  public:
+  
     /**
      * @return A pointer toward the alphabet associated to this path.
      */
     const Alphabet* getAlphabet() const { return alphabet_; }
-		
+    
     /**
-		 * @brief Add a new mutation event.
-		 *
-		 * @param state The new state after mutation event.
-		 * @param time  The time between this mutation and previous mutation (or initial state).
-		 */
-		void addEvent(int state, double time) {
-			states_.push_back(state);
-			times_.push_back(time);
-		}
-
-		/**
-		 * @brief Retrieve the initial state.
-		 *
-		 * @return The initial state of this path.
-		 */
-		int getInitialState() const { return initialState_; }
-
-		/**
-		 * @brief Retrieve the total time of evolution.
-		 *
-		 * @return The total time of evolution.
-		 */
-		double getTotalTime() const { return totalTime_; }
-		
-		/**
-		 * @brief Retrieve the number of substitution events.
-		 *
-		 * @return The number of substitution events, i.e. the number of states (without initial state).
-		 */
-		size_t getNumberOfEvents() const { return states_.size(); }
+     * @brief Add a new mutation event.
+     *
+     * @param state The new state after mutation event.
+     * @param time  The time between this mutation and previous mutation (or initial state).
+     */
+    void addEvent(size_t state, double time) {
+      states_.push_back(state);
+      times_.push_back(time);
+    }
+
+    /**
+     * @brief Retrieve the initial state.
+     *
+     * @return The initial state of this path.
+     */
+    size_t getInitialState() const { return initialState_; }
+
+    /**
+     * @brief Retrieve the total time of evolution.
+     *
+     * @return The total time of evolution.
+     */
+    double getTotalTime() const { return totalTime_; }
+    
+    /**
+     * @brief Retrieve the number of substitution events.
+     *
+     * @return The number of substitution events, i.e. the number of states (without initial state).
+     */
+    size_t getNumberOfEvents() const { return states_.size(); }
 
     /**
      * @brief Retrieve the number of substitution events per type of substitution.
@@ -156,9 +156,9 @@ class MutationPath
       if (counts.getNumberOfRows()    != alphabet_->getSize()
        || counts.getNumberOfColumns() != alphabet_->getSize())
         throw Exception("MutationPath::getEventCounts. Incorrect input matrix, does not match alphabet size.");
-      int currentState = initialState_;
+      size_t currentState = initialState_;
       for (size_t i = 0; i < states_.size(); ++i) {
-        int newState = states_[i];
+        size_t newState = states_[i];
         counts(currentState, newState)++;
         currentState = newState;
       }
@@ -174,24 +174,24 @@ class MutationPath
     void getEventCounts(std::vector<Scalar>& counts, const SubstitutionRegister& reg) const {
       if (counts.size() != reg.getNumberOfSubstitutionTypes())
         throw Exception("MutationPath::getEventCounts. Incorrect input vector, does not match alphabet size.");
-      int currentState = initialState_;
+      size_t currentState = initialState_;
       for (size_t i = 0; i < states_.size(); ++i) {
-        int newState = states_[i];
+        size_t newState = states_[i];
         size_t type = reg.getType(currentState, newState);
         if (type > 0) counts[type - 1]++;
         currentState = newState;
       }
     }
 
-		/**
-		 * @brief Retrieve the final state of this path.
-		 *
-		 * @return The initial state if no mutation occured, otherwise sends the state after last mutation event.
-		 */
-		int getFinalState() const {
-			if (states_.size() == 0) return initialState_;
-			else return states_[states_.size() - 1];
-		}
+    /**
+     * @brief Retrieve the final state of this path.
+     *
+     * @return The initial state if no mutation occured, otherwise sends the state after last mutation event.
+     */
+    size_t getFinalState() const {
+      if (states_.size() == 0) return initialState_;
+      else return states_[states_.size() - 1];
+    }
 };
 
 /**
@@ -203,62 +203,62 @@ class MutationPath
  */
 class MutationProcess
 {
-	public:
-		MutationProcess() {};
-		virtual ~MutationProcess() {};
-	
-	public:
-		
+  public:
+    MutationProcess() {};
+    virtual ~MutationProcess() {};
+  
+  public:
+    
     /**
      * @brief Mutate a character in state i.
-		 *
-		 * @param state The current state of the character.
+     *
+     * @param state The current state of the character.
      */
-    virtual int mutate(int state) const = 0;
+    virtual size_t mutate(size_t state) const = 0;
 
     /**
      * @brief Mutate a character in state i n times.
      * 
-		 * @param state The current state of the character.
-		 * @param n The number of mutations to perform.
+     * @param state The current state of the character.
+     * @param n The number of mutations to perform.
+     */
+    virtual size_t mutate(size_t state, unsigned int n) const = 0;
+  
+    /**
+     * @brief Get the time before next mutation event.
+     *
+     * @param state The actual state of the chain;
+     * @return A random time before next mutation event.
+     */
+    virtual double getTimeBeforeNextMutationEvent(size_t state) const = 0;
+    
+    /**
+     * @brief Simulation a character evolution during a specified time
+     * according to the given substitution model and send the final state.
+     *
+     * @param initialState The state before beginning evolution.
+     * @param time         The time during which evolution must occure.
+     * @return The resulting state after evolution is completed.
+     */
+    virtual size_t evolve(size_t initialState, double time) const = 0;
+  
+    /**
+     * @brief Simulation a character evolution during a specified time
+     * according to the given substitution model and send the total path
+     * with all intermediate states and times between mutation events.
+     *
+     * @param initialState The state before beginning evolution.
+     * @param time         The time during which evolution must occure.
+     * @return The resulting mutation path.
+     */
+    virtual MutationPath detailedEvolve(size_t initialState, double time) const = 0;
+
+    /**
+     * @brief Get the substitution model associated to the mutation process.
+     *
+     * @return The SubstitutionModel associated to this instance.
      */
-    virtual int mutate(int state, unsigned int n) const = 0;
-	
-		/**
-		 * @brief Get the time before next mutation event.
-		 *
-		 * @param state The actual state of the chain;
-		 * @return A random time before next mutation event.
-		 */
-		virtual double getTimeBeforeNextMutationEvent(int state) const = 0;
-		
-		/**
-		 * @brief Simulation a character evolution during a specified time
-		 * according to the given substitution model and send the final state.
-		 *
-		 * @param initialState The state before beginning evolution.
-		 * @param time         The time during which evolution must occure.
-		 * @return The resulting state after evolution is completed.
-		 */
-		virtual int evolve(int initialState, double time) const = 0;
-	
-		/**
-		 * @brief Simulation a character evolution during a specified time
-		 * according to the given substitution model and send the total path
-		 * with all intermediate states and times between mutation events.
-		 *
-		 * @param initialState The state before beginning evolution.
-		 * @param time         The time during which evolution must occure.
-		 * @return The resulting mutation path.
-		 */
-		virtual MutationPath detailedEvolve(int initialState, double time) const = 0;
-
-		/**
-		 * @brief Get the substitution model associated to the mutation process.
-		 *
-		 * @return The SubstitutionModel associated to this instance.
-		 */
-		virtual const SubstitutionModel* getSubstitutionModel() const = 0;
+    virtual const SubstitutionModel* getSubstitutionModel() const = 0;
 };
 
 /**
@@ -277,28 +277,28 @@ class MutationProcess
 class AbstractMutationProcess :
   public virtual MutationProcess
 {
-	protected:
-		
-		/**
-		 * @brief The substitution model to use:
-		 */
-		const SubstitutionModel* model_;
-	
-		/**
-		 * @brief The number of states allowed for the character to mutate.
-		 */
+  protected:
+    
+    /**
+     * @brief The substitution model to use:
+     */
+    const SubstitutionModel* model_;
+  
+    /**
+     * @brief The number of states allowed for the character to mutate.
+     */
     size_t size_;
-	
-		/**
-		 * @brief The repartition function for states probabilities.
-		 *
-		 * repartition_[i][j] = probability that, being in state i at time t,
-		 * we'll be in state <= j at time t+1.
-		 */
+  
+    /**
+     * @brief The repartition function for states probabilities.
+     *
+     * repartition_[i][j] = probability that, being in state i at time t,
+     * we'll be in state <= j at time t+1.
+     */
     VVdouble repartition_;
-	
-	public:
-		AbstractMutationProcess(const SubstitutionModel* model) :
+  
+  public:
+    AbstractMutationProcess(const SubstitutionModel* model) :
       model_(model), size_(), repartition_()
     {}
 
@@ -314,15 +314,15 @@ class AbstractMutationProcess :
       return *this;
     }
 
-		virtual ~AbstractMutationProcess() {}
-	
-	public:
-    int mutate(int state) const;
-    int mutate(int state, unsigned int n) const;
-		double getTimeBeforeNextMutationEvent(int state) const;
-		int evolve(int initialState, double time) const;
-		MutationPath detailedEvolve(int initialState, double time) const;
-		const SubstitutionModel* getSubstitutionModel() const { return model_; }
+    virtual ~AbstractMutationProcess() {}
+  
+  public:
+    size_t mutate(size_t state) const;
+    size_t mutate(size_t state, unsigned int n) const;
+    double getTimeBeforeNextMutationEvent(size_t state) const;
+    size_t evolve(size_t initialState, double time) const;
+    MutationPath detailedEvolve(size_t initialState, double time) const;
+    const SubstitutionModel* getSubstitutionModel() const { return model_; }
 };
 
 /**
@@ -340,25 +340,25 @@ class AbstractMutationProcess :
  */
 class SimpleMutationProcess : public AbstractMutationProcess
 {
-	public: // Constructor and destructor:
-		
-		/**
-		 * @brief Build a new SimpleMutationProcess object.
-		 *
-		 * @param model The substitution model to use.
-		 */
-  	SimpleMutationProcess(const SubstitutionModel* model);
-	
-		virtual ~SimpleMutationProcess();
+  public: // Constructor and destructor:
+    
+    /**
+     * @brief Build a new SimpleMutationProcess object.
+     *
+     * @param model The substitution model to use.
+     */
+    SimpleMutationProcess(const SubstitutionModel* model);
+  
+    virtual ~SimpleMutationProcess();
 
     /**
      * @brief Method redefinition for better performance.
      *
-		 * @param initialState The state before beginning evolution.
-		 * @param time         The time during which evolution must occure.
-		 * @return The resulting state after evolution is completed.
-		 */
-		int evolve(int initialState, double time) const;
+     * @param initialState The state before beginning evolution.
+     * @param time         The time during which evolution must occure.
+     * @return The resulting state after evolution is completed.
+     */
+    size_t evolve(size_t initialState, double time) const;
 };
 
 /**
@@ -367,13 +367,13 @@ class SimpleMutationProcess : public AbstractMutationProcess
  */
 class SelfMutationProcess : public AbstractMutationProcess
 {
-  	public:
-  		SelfMutationProcess(int alphabetSize);
-	
-			virtual ~SelfMutationProcess();
+    public:
+      SelfMutationProcess(size_t alphabetSize);
+  
+      virtual ~SelfMutationProcess();
 };
 
 } //end of namespace bpp.
 
-#endif	//_MUTATIONPROCESS_H_
+#endif  //_MUTATIONPROCESS_H_
 
diff --git a/src/Bpp/Phyl/Simulation/NonHomogeneousSequenceSimulator.cpp b/src/Bpp/Phyl/Simulation/NonHomogeneousSequenceSimulator.cpp
index 527d5d0..249d29c 100644
--- a/src/Bpp/Phyl/Simulation/NonHomogeneousSequenceSimulator.cpp
+++ b/src/Bpp/Phyl/Simulation/NonHomogeneousSequenceSimulator.cpp
@@ -60,6 +60,7 @@ NonHomogeneousSequenceSimulator::NonHomogeneousSequenceSimulator(
   const Tree* tree) throw (Exception) :
   modelSet_(modelSet),
   alphabet_(modelSet_->getAlphabet()),
+  supportedStates_(modelSet_->getAlphabetStates()),
   rate_(rate),
   templateTree_(tree),
   tree_(*tree),
@@ -84,6 +85,7 @@ NonHomogeneousSequenceSimulator::NonHomogeneousSequenceSimulator(
   const Tree* tree) :
   modelSet_(0),
   alphabet_(model->getAlphabet()),
+  supportedStates_(model->getAlphabetStates()),
   rate_(rate),
   templateTree_(tree),
   tree_(*tree),
@@ -95,13 +97,14 @@ NonHomogeneousSequenceSimulator::NonHomogeneousSequenceSimulator(
   nbStates_(model->getNumberOfStates()),
   continuousRates_(false)
 {
-  FixedFrequenciesSet* fSet = new FixedFrequenciesSet(model->getAlphabet(), model->getFrequencies());
+  FixedFrequenciesSet* fSet = new FixedFrequenciesSet(model->getStateMap().clone(), model->getFrequencies());
   fSet->setNamespace("anc.");
   modelSet_ = SubstitutionModelSetTools::createHomogeneousModelSet(dynamic_cast<SubstitutionModel*>(model->clone()), fSet, templateTree_);
   init();
 }
 
 /******************************************************************************/
+
 void NonHomogeneousSequenceSimulator::init()
 {
   seqNames_.resize(leaves_.size());
@@ -141,10 +144,11 @@ void NonHomogeneousSequenceSimulator::init()
 }
 
 /******************************************************************************/
-Site* NonHomogeneousSequenceSimulator::simulate() const
+
+Site* NonHomogeneousSequenceSimulator::simulateSite() const
 {
   // Draw an initial state randomly according to equilibrum frequencies:
-  int initialState = 0;
+  size_t initialStateIndex = 0;
   double r = RandomTools::giveRandomNumberBetweenZeroAndEntry(1.);
   double cumprob = 0;
   vector<double> freqs = modelSet_->getRootFrequencies();
@@ -153,57 +157,60 @@ Site* NonHomogeneousSequenceSimulator::simulate() const
     cumprob += freqs[i];
     if (r <= cumprob)
     {
-      initialState = static_cast<int>(i);
+      initialStateIndex = i;
       break;
     }
   }
-  return simulate(initialState);
+  return simulateSite(initialStateIndex);
 }
 
 /******************************************************************************/
-Site* NonHomogeneousSequenceSimulator::simulate(int initialState) const
+
+Site* NonHomogeneousSequenceSimulator::simulateSite(size_t ancestralStateIndex) const
 {
   if (continuousRates_)
   {
     // Draw a random rate:
     double rate = rate_->randC();
     // Make this state evolve:
-    return simulate(initialState, rate);
+    return simulateSite(ancestralStateIndex, rate);
   }
   else
   {
     // Draw a random rate:
-    size_t rateClass = static_cast<size_t>(RandomTools::giveIntRandomNumberBetweenZeroAndEntry(static_cast<int>(rate_->getNumberOfCategories())));
+    size_t rateClass = RandomTools::giveIntRandomNumberBetweenZeroAndEntry<size_t>(rate_->getNumberOfCategories());
     // Make this state evolve:
-    return simulate(initialState, rateClass);
+    return simulateSite(ancestralStateIndex, rateClass);
   }
 }
 
 /******************************************************************************/
-Site* NonHomogeneousSequenceSimulator::simulate(int initialState, size_t rateClass) const
+
+Site* NonHomogeneousSequenceSimulator::simulateSite(size_t ancestralStateIndex, size_t rateClass) const
 {
   // Launch recursion:
   SNode* root = tree_.getRootNode();
-  root->getInfos().state = initialState;
-  for (size_t i = 0; i < root->getNumberOfSons(); i++)
+  root->getInfos().state = ancestralStateIndex;
+  for (size_t i = 0; i < root->getNumberOfSons(); ++i)
   {
     evolveInternal(root->getSon(i), rateClass);
   }
   // Now create a Site object:
   Vint site(leaves_.size());
-  for (size_t i = 0; i < leaves_.size(); i++)
+  for (size_t i = 0; i < leaves_.size(); ++i)
   {
-    site[i] = leaves_[i]->getInfos().model->getAlphabetChar(leaves_[i]->getInfos().state);
+    site[i] = leaves_[i]->getInfos().model->getAlphabetStateAsInt(leaves_[i]->getInfos().state);
   }
   return new Site(site, alphabet_);
 }
 
 /******************************************************************************/
-Site* NonHomogeneousSequenceSimulator::simulate(int initialState, double rate) const
+
+Site* NonHomogeneousSequenceSimulator::simulateSite(size_t ancestralStateIndex, double rate) const
 {
   // Launch recursion:
   SNode* root = tree_.getRootNode();
-  root->getInfos().state = initialState;
+  root->getInfos().state = ancestralStateIndex;
   for (size_t i = 0; i < root->getNumberOfSons(); i++)
   {
     evolveInternal(root->getSon(i), rate);
@@ -212,16 +219,17 @@ Site* NonHomogeneousSequenceSimulator::simulate(int initialState, double rate) c
   Vint site(leaves_.size());
   for (size_t i = 0; i < leaves_.size(); i++)
   {
-    site[i] = leaves_[i]->getInfos().model->getAlphabetChar(leaves_[i]->getInfos().state);
+    site[i] = leaves_[i]->getInfos().model->getAlphabetStateAsInt(leaves_[i]->getInfos().state);
   }
   return new Site(site, alphabet_);
 }
 
 /******************************************************************************/
-Site* NonHomogeneousSequenceSimulator::simulate(double rate) const
+
+Site* NonHomogeneousSequenceSimulator::simulateSite(double rate) const
 {
   // Draw an initial state randomly according to equilibrum frequencies:
-  int initialState = 0;
+  size_t ancestralStateIndex = 0;
   double r = RandomTools::giveRandomNumberBetweenZeroAndEntry(1.);
   double cumprob = 0;
   vector<double> freqs = modelSet_->getRootFrequencies();
@@ -230,18 +238,19 @@ Site* NonHomogeneousSequenceSimulator::simulate(double rate) const
     cumprob += freqs[i];
     if (r <= cumprob)
     {
-      initialState = (int)i;
+      ancestralStateIndex = i;
       break;
     }
   }
   // Make this state evolve:
-  return simulate(initialState, rate);
+  return simulateSite(ancestralStateIndex, rate);
 }
 
 /******************************************************************************/
+
 SiteContainer* NonHomogeneousSequenceSimulator::simulate(size_t numberOfSites) const
 {
-  Vint initialStates(numberOfSites, 0);
+  vector<size_t> ancestralStateIndices(numberOfSites, 0);
   for (size_t j = 0; j < numberOfSites; j++)
   {
     double r = RandomTools::giveRandomNumberBetweenZeroAndEntry(1.);
@@ -252,7 +261,7 @@ SiteContainer* NonHomogeneousSequenceSimulator::simulate(size_t numberOfSites) c
       cumprob += freqs[i];
       if (r <= cumprob)
       {
-        initialStates[j] = (int)i;
+        ancestralStateIndices[j] = i;
         break;
       }
     }
@@ -263,7 +272,7 @@ SiteContainer* NonHomogeneousSequenceSimulator::simulate(size_t numberOfSites) c
     sites->setSequencesNames(seqNames_);
     for (size_t j = 0; j < numberOfSites; j++)
     {
-      Site* site = simulate();
+      Site* site = simulateSite();
       site->setPosition(static_cast<int>(j));
       sites->addSite(*site);
       delete site;
@@ -278,19 +287,20 @@ SiteContainer* NonHomogeneousSequenceSimulator::simulate(size_t numberOfSites) c
     size_t nCat = rate_->getNumberOfCategories();
     for (size_t j = 0; j < numberOfSites; j++)
     {
-      rateClasses[j] = static_cast<size_t>(RandomTools::giveIntRandomNumberBetweenZeroAndEntry(static_cast<int>(nCat)));
+      rateClasses[j] = RandomTools::giveIntRandomNumberBetweenZeroAndEntry<size_t>(nCat);
     }
     // Make these states evolve:
-    SiteContainer* sites = multipleEvolve(initialStates, rateClasses);
+    SiteContainer* sites = multipleEvolve(ancestralStateIndices, rateClasses);
     return sites;
   }
 }
 
 /******************************************************************************/
-RASiteSimulationResult* NonHomogeneousSequenceSimulator::dSimulate() const
+
+RASiteSimulationResult* NonHomogeneousSequenceSimulator::dSimulateSite() const
 {
   // Draw an initial state randomly according to equilibrum frequencies:
-  int initialState = 0;
+  size_t ancestralStateIndex = 0;
   double r = RandomTools::giveRandomNumberBetweenZeroAndEntry(1.);
   double cumprob = 0;
   vector<double> freqs = modelSet_->getRootFrequencies();
@@ -299,51 +309,55 @@ RASiteSimulationResult* NonHomogeneousSequenceSimulator::dSimulate() const
     cumprob += freqs[i];
     if (r <= cumprob)
     {
-      initialState = static_cast<int>(i);
+      ancestralStateIndex = i;
       break;
     }
   }
 
-  return dSimulate(initialState);
+  return dSimulateSite(ancestralStateIndex);
 }
 
 /******************************************************************************/
-RASiteSimulationResult* NonHomogeneousSequenceSimulator::dSimulate(int initialState) const
+
+RASiteSimulationResult* NonHomogeneousSequenceSimulator::dSimulateSite(size_t ancestralStateIndex) const
 {
   // Draw a random rate:
   if (continuousRates_)
   {
     double rate = rate_->randC();
-    return dSimulate(initialState, rate);
+    return dSimulateSite(ancestralStateIndex, rate);
   }
   else
   {
-    size_t rateClass = static_cast<size_t>(RandomTools::giveIntRandomNumberBetweenZeroAndEntry(static_cast<int>(rate_->getNumberOfCategories())));
-    return dSimulate(initialState, rateClass);
+    size_t rateClass = RandomTools::giveIntRandomNumberBetweenZeroAndEntry<size_t>(rate_->getNumberOfCategories());
+    return dSimulateSite(ancestralStateIndex, rateClass);
     // NB: this is more efficient than dSimulate(initialState, rDist_->rand())
   }
 }
 
 /******************************************************************************/
-RASiteSimulationResult* NonHomogeneousSequenceSimulator::dSimulate(int initialState, double rate) const
+
+RASiteSimulationResult* NonHomogeneousSequenceSimulator::dSimulateSite(size_t ancestralStateIndex, double rate) const
 {
   // Make this state evolve:
-  RASiteSimulationResult* hssr = new RASiteSimulationResult(templateTree_, modelSet_->getAlphabet(), initialState, rate);
-  dEvolve(initialState, rate, *hssr);
+  RASiteSimulationResult* hssr = new RASiteSimulationResult(templateTree_, modelSet_->getAlphabet(), ancestralStateIndex, rate);
+  dEvolve(ancestralStateIndex, rate, *hssr);
   return hssr;
 }
 
 /******************************************************************************/
-RASiteSimulationResult* NonHomogeneousSequenceSimulator::dSimulate(int initialState, size_t rateClass) const
+
+RASiteSimulationResult* NonHomogeneousSequenceSimulator::dSimulateSite(size_t ancestralStateIndex, size_t rateClass) const
 {
-  return dSimulate(initialState, rate_->getCategory(rateClass));
+  return dSimulateSite(ancestralStateIndex, rate_->getCategory(rateClass));
 }
 
 /******************************************************************************/
-RASiteSimulationResult* NonHomogeneousSequenceSimulator::dSimulate(double rate) const
+
+RASiteSimulationResult* NonHomogeneousSequenceSimulator::dSimulateSite(double rate) const
 {
   // Draw an initial state randomly according to equilibrum frequencies:
-  int initialState = 0;
+  size_t ancestralStateIndex = 0;
   double r = RandomTools::giveRandomNumberBetweenZeroAndEntry(1.);
   double cumprob = 0;
   vector<double> freqs = modelSet_->getRootFrequencies();
@@ -352,59 +366,61 @@ RASiteSimulationResult* NonHomogeneousSequenceSimulator::dSimulate(double rate)
     cumprob += freqs[i];
     if (r <= cumprob)
     {
-      initialState = static_cast<int>(i);
+      ancestralStateIndex = i;
       break;
     }
   }
-  return dSimulate(initialState, rate);
+  return dSimulateSite(ancestralStateIndex, rate);
 }
 
 /******************************************************************************/
-int NonHomogeneousSequenceSimulator::evolve(const SNode* node, int initialState, size_t rateClass) const
+
+size_t NonHomogeneousSequenceSimulator::evolve(const SNode* node, size_t initialStateIndex, size_t rateClass) const
 {
-  const Vdouble* cumpxy_node_c_x_ = &node->getInfos().cumpxy[rateClass][initialState];
+  const Vdouble* cumpxy_node_c_x_ = &node->getInfos().cumpxy[rateClass][initialStateIndex];
   double rand = RandomTools::giveRandomNumberBetweenZeroAndEntry(1.);
-  for (int y = 0; y < static_cast<int>(nbStates_); y++)
+  for (size_t y = 0; y < nbStates_; y++)
   {
     if (rand < (*cumpxy_node_c_x_)[y]) return y;
   }
-  cerr << "DEBUG: This message should never happen! (HomogeneousSequenceSimulator::evolve)" << endl;
-  cout << "   rand = " << rand << endl;
-  return -1;
+  throw Exception("HomogeneousSequenceSimulator::evolve. The impossible happened! rand = " + TextTools::toString(rand) + ".");
 }
 
 /******************************************************************************/
-int NonHomogeneousSequenceSimulator::evolve(const SNode* node, int initialState, double rate) const
+
+size_t NonHomogeneousSequenceSimulator::evolve(const SNode* node, size_t initialStateIndex, double rate) const
 {
   double cumpxy = 0;
   double rand = RandomTools::giveRandomNumberBetweenZeroAndEntry(1.);
   double l = rate * node->getDistanceToFather();
   const SubstitutionModel* model = node->getInfos().model;
-  for (int y = 0; y < static_cast<int>(nbStates_); y++)
+  for (size_t y = 0; y < nbStates_; y++)
   {
-    cumpxy += model->Pij_t(initialState, y, l);
+    cumpxy += model->Pij_t(initialStateIndex, y, l);
     if (rand < cumpxy) return y;
   }
-  cerr << "DEBUG: This message should never happen! (NonHomogeneousSequenceSimulator::evolve)" << endl;
-  cout << "  rand = " << rand << endl;
-  cout << "cumpxy = " << cumpxy << endl;
   MatrixTools::print(model->getPij_t(l));
-  return -1;
+  throw Exception("HomogeneousSequenceSimulator::evolve. The impossible happened! rand = " + TextTools::toString(rand) + ".");
 }
 
 /******************************************************************************/
-void NonHomogeneousSequenceSimulator::multipleEvolve(const SNode* node, const Vint& initialStates, const vector<size_t>& rateClasses, Vint& finalStates) const
+
+void NonHomogeneousSequenceSimulator::multipleEvolve(
+    const SNode* node,
+    const std::vector<size_t>& initialStateIndices,
+    const vector<size_t>& rateClasses,
+    std::vector<size_t>& finalStateIndices) const
 {
   const VVVdouble* cumpxy_node_ = &node->getInfos().cumpxy;
-  for (size_t i = 0; i < initialStates.size(); i++)
+  for (size_t i = 0; i < initialStateIndices.size(); i++)
   {
-    const Vdouble* cumpxy_node_c_x_ = &(*cumpxy_node_)[rateClasses[i]][initialStates[i]];
+    const Vdouble* cumpxy_node_c_x_ = &(*cumpxy_node_)[rateClasses[i]][initialStateIndices[i]];
     double rand = RandomTools::giveRandomNumberBetweenZeroAndEntry(1.);
     for (size_t y = 0; y < nbStates_; y++)
     {
       if (rand < (*cumpxy_node_c_x_)[y])
       {
-        finalStates[i] = (int)y;
+        finalStateIndices[i] = y;
         break;
       }
     }
@@ -412,6 +428,7 @@ void NonHomogeneousSequenceSimulator::multipleEvolve(const SNode* node, const Vi
 }
 
 /******************************************************************************/
+
 void NonHomogeneousSequenceSimulator::evolveInternal(SNode* node, size_t rateClass) const
 {
   if (!node->hasFather())
@@ -427,6 +444,7 @@ void NonHomogeneousSequenceSimulator::evolveInternal(SNode* node, size_t rateCla
 }
 
 /******************************************************************************/
+
 void NonHomogeneousSequenceSimulator::evolveInternal(SNode* node, double rate) const
 {
   if (!node->hasFather())
@@ -442,6 +460,7 @@ void NonHomogeneousSequenceSimulator::evolveInternal(SNode* node, double rate) c
 }
 
 /******************************************************************************/
+
 void NonHomogeneousSequenceSimulator::multipleEvolveInternal(SNode* node, const vector<size_t>& rateClasses) const
 {
   if (!node->hasFather())
@@ -449,7 +468,7 @@ void NonHomogeneousSequenceSimulator::multipleEvolveInternal(SNode* node, const
     cerr << "DEBUG: NonHomogeneousSequenceSimulator::multipleEvolveInternal. Forbidden call of method on root node." << endl;
     return;
   }
-  const vector<int>* initialStates = &node->getFather()->getInfos().states;
+  const vector<size_t>* initialStates = &node->getFather()->getInfos().states;
   size_t n = initialStates->size();
   node->getInfos().states.resize(n); // allocation.
   multipleEvolve(node, node->getFather()->getInfos().states, rateClasses, node->getInfos().states);
@@ -460,11 +479,14 @@ void NonHomogeneousSequenceSimulator::multipleEvolveInternal(SNode* node, const
 }
 
 /******************************************************************************/
-SiteContainer* NonHomogeneousSequenceSimulator::multipleEvolve(const Vint& initialStates, const vector<size_t>& rateClasses) const
+
+SiteContainer* NonHomogeneousSequenceSimulator::multipleEvolve(
+    const std::vector<size_t>& initialStateIndices,
+    const vector<size_t>& rateClasses) const
 {
   // Launch recursion:
   SNode* root = tree_.getRootNode();
-  root->getInfos().states = initialStates;
+  root->getInfos().states = initialStateIndices;
   for (size_t i = 0; i < root->getNumberOfSons(); i++)
   {
     multipleEvolveInternal(root->getSon(i), rateClasses);
@@ -472,16 +494,16 @@ SiteContainer* NonHomogeneousSequenceSimulator::multipleEvolve(const Vint& initi
   // Now create a SiteContainer object:
   AlignedSequenceContainer* sites = new AlignedSequenceContainer(alphabet_);
   size_t n = leaves_.size();
-  size_t nbSites = initialStates.size();
+  size_t nbSites = initialStateIndices.size();
   const SubstitutionModel* model = 0;
   for (size_t i = 0; i < n; i++)
   {
     vector<int> content(nbSites);
-    vector<int>* states = &leaves_[i]->getInfos().states;
+    vector<size_t>& states = leaves_[i]->getInfos().states;
     model = leaves_[i]->getInfos().model;
     for (size_t j = 0; j < nbSites; j++)
     {
-      content[j] = model->getAlphabetChar((*states)[j]);
+      content[j] = model->getAlphabetStateAsInt(states[j]);
     }
     sites->addSequence(BasicSequence(leaves_[i]->getName(), content, alphabet_), false);
   }
@@ -489,7 +511,8 @@ SiteContainer* NonHomogeneousSequenceSimulator::multipleEvolve(const Vint& initi
 }
 
 /******************************************************************************/
-void NonHomogeneousSequenceSimulator::dEvolve(int initialState, double rate, RASiteSimulationResult& rassr) const
+
+void NonHomogeneousSequenceSimulator::dEvolve(size_t initialState, double rate, RASiteSimulationResult& rassr) const
 {
   // Launch recursion:
   SNode* root = tree_.getRootNode();
@@ -501,6 +524,7 @@ void NonHomogeneousSequenceSimulator::dEvolve(int initialState, double rate, RAS
 }
 
 /******************************************************************************/
+
 void NonHomogeneousSequenceSimulator::dEvolveInternal(SNode* node, double rate, RASiteSimulationResult& rassr) const
 {
   if (!node->hasFather())
diff --git a/src/Bpp/Phyl/Simulation/NonHomogeneousSequenceSimulator.h b/src/Bpp/Phyl/Simulation/NonHomogeneousSequenceSimulator.h
index 08890bc..7b7edcf 100644
--- a/src/Bpp/Phyl/Simulation/NonHomogeneousSequenceSimulator.h
+++ b/src/Bpp/Phyl/Simulation/NonHomogeneousSequenceSimulator.h
@@ -67,8 +67,8 @@ namespace bpp
 class SimData
 {
   public:
-    int state;
-    std::vector<int> states;
+    size_t state;
+    std::vector<size_t> states;
     VVVdouble cumpxy;
     const SubstitutionModel* model;
 
@@ -96,48 +96,49 @@ class NonHomogeneousSequenceSimulator:
   public DetailedSiteSimulator,
   public virtual SequenceSimulator
 {
-	private:
-		const SubstitutionModelSet* modelSet_;
-		const Alphabet            * alphabet_;
-		const DiscreteDistribution* rate_;
-		const Tree                * templateTree_;
-		mutable TreeTemplate<SNode> tree_;
+  private:
+    const SubstitutionModelSet* modelSet_;
+    const Alphabet            * alphabet_;
+    std::vector<int>            supportedStates_;
+    const DiscreteDistribution* rate_;
+    const Tree                * templateTree_;
+    mutable TreeTemplate<SNode> tree_;
     bool ownModelSet_;
-	
-		/**
-		 * @brief This stores once for all all leaves in a given order.
-		 * This order will be used during site creation.
-		 */
+  
+    /**
+     * @brief This stores once for all all leaves in a given order.
+     * This order will be used during site creation.
+     */
     std::vector<SNode*> leaves_;
-	
+  
     std::vector<std::string> seqNames_;
 
-		size_t nbNodes_;
-		size_t nbClasses_;
-		size_t nbStates_;
+    size_t nbNodes_;
+    size_t nbClasses_;
+    size_t nbStates_;
 
     bool continuousRates_;
-	
-		/**
-		 * @name Stores intermediate results.
+  
+    /**
+     * @name Stores intermediate results.
      *
      * @{
-		 */
+     */
 
-	public:		
-		NonHomogeneousSequenceSimulator(
-			const SubstitutionModelSet* modelSet,
-			const DiscreteDistribution* rate,
-			const Tree* tree
-		) throw (Exception);
+  public:    
+    NonHomogeneousSequenceSimulator(
+      const SubstitutionModelSet* modelSet,
+      const DiscreteDistribution* rate,
+      const Tree* tree
+    ) throw (Exception);
 
     NonHomogeneousSequenceSimulator(
-			const SubstitutionModel* model,
-			const DiscreteDistribution* rate,
-			const Tree* tree
-		);
-			
-		virtual ~NonHomogeneousSequenceSimulator()
+      const SubstitutionModel* model,
+      const DiscreteDistribution* rate,
+      const Tree* tree
+    );
+      
+    virtual ~NonHomogeneousSequenceSimulator()
     {
       if (ownModelSet_ && modelSet_) delete modelSet_;
     }
@@ -145,6 +146,7 @@ class NonHomogeneousSequenceSimulator:
     NonHomogeneousSequenceSimulator(const NonHomogeneousSequenceSimulator& nhss) :
       modelSet_       (nhss.modelSet_),
       alphabet_       (nhss.alphabet_),
+      supportedStates_(nhss.supportedStates_),
       rate_           (nhss.rate_),
       templateTree_   (nhss.templateTree_),
       tree_           (nhss.tree_),
@@ -161,6 +163,7 @@ class NonHomogeneousSequenceSimulator:
     {
       modelSet_        = nhss.modelSet_;
       alphabet_        = nhss.alphabet_;
+      supportedStates_ = nhss.supportedStates_;
       rate_            = nhss.rate_;
       templateTree_    = nhss.templateTree_;
       tree_            = nhss.tree_;
@@ -189,81 +192,83 @@ class NonHomogeneousSequenceSimulator:
      */
     void init();
 
-	public:
-	
-		/**
-		 * @name The SiteSimulator interface
-		 *
-		 * @{
-		 */
-		Site* simulate() const;
-		Site* simulate(int ancestralState) const;
-		Site* simulate(int ancestralState, double rate) const;
-		Site* simulate(double rate) const;
+  public:
+  
+    /**
+     * @name The SiteSimulator interface
+     *
+     * @{
+     */
+    Site* simulateSite() const;
+
+    Site* simulateSite(size_t ancestralStateIndex) const;
+
+    Site* simulateSite(size_t ancestralStateIndex, double rate) const;
+    
+    Site* simulateSite(double rate) const;
+
     std::vector<std::string> getSequencesNames() const { return seqNames_; }
-		/** @} */
+    /** @} */
     
-		/**
-		 * @name The PreciseSiteSimulator interface.
-		 *
-		 * @{
-		 */
-    RASiteSimulationResult* dSimulate() const;
+    /**
+     * @name The DetailedSiteSimulator interface.
+     *
+     * @{
+     */
+    RASiteSimulationResult* dSimulateSite() const;
     
-    RASiteSimulationResult* dSimulate(int ancestralState) const;
+    RASiteSimulationResult* dSimulateSite(size_t ancestralStateIndex) const;
     
-    RASiteSimulationResult* dSimulate(int ancestralState, double rate) const;
-
-    RASiteSimulationResult* dSimulate(double rate) const;
-		/** @} */
+    RASiteSimulationResult* dSimulateSite(size_t ancestralStateIndex, double rate) const;
+    
+    RASiteSimulationResult* dSimulateSite(double rate) const;
+    /** @} */
 
     /**
-		 * @name The SequenceSimulator interface
-		 *
-		 * @{
-		 */
-		SiteContainer* simulate(size_t numberOfSites) const;
-		/** @} */
+     * @name The SequenceSimulator interface
+     *
+     * @{
+     */
+    SiteContainer* simulate(size_t numberOfSites) const;
+    /** @} */
     
-		/**
-		 * @name SiteSimulator and SequenceSimulator interface
-		 *
-		 * @{
-		 */
-		const Alphabet* getAlphabet() const { return alphabet_; }
-		/** @} */
+    /**
+     * @name SiteSimulator and SequenceSimulator interface
+     *
+     * @{
+     */
+    const Alphabet* getAlphabet() const { return alphabet_; }
+    /** @} */
 
     /**
      * @name Functions with rate classes instead of absolute rates.
      *
      * @{
      */
-		virtual Site* simulate(int ancestralState, size_t rateClass) const;
-    virtual	RASiteSimulationResult* dSimulate(int ancestralState, size_t rateClass) const;
+    virtual Site* simulateSite(size_t ancestralStateIndex, size_t rateClass) const;
+    virtual RASiteSimulationResult* dSimulateSite(size_t ancestralStateIndex, size_t rateClass) const;
     /** @} */
-	
-		/**
-		 * @brief Get the mutation process associated to this instance.
-		 *
-		 * @return The MutationProcess object associated to this instance.
-		 */
-		const SubstitutionModelSet* getSubstitutionModelSet() const { return modelSet_; }
-		
-	
-		
-		/**
-		 * @brief Get the rate distribution associated to this instance.
-		 *
-		 * @return The DiscreteDistribution object associated to this instance.
-		 */
-		const DiscreteDistribution* getRateDistribution() const { return rate_; }
-
-		/**
-		 * @brief Get the tree associated to this instance.
-		 *
-		 * @return The Tree object associated to this instance.
-		 */
-		const Tree* getTree() const { return templateTree_; }
+  
+    /**
+     * @brief Get the substitution model associated to this instance.
+     *
+     * @return The substitution model associated to this instance.
+     */
+    const SubstitutionModelSet* getSubstitutionModelSet() const { return modelSet_; }
+    
+    /**
+     * @brief Get the rate distribution associated to this instance.
+     *
+     * @return The DiscreteDistribution object associated to this instance.
+     */
+    const DiscreteDistribution* getRateDistribution() const { return rate_; }
+
+    /**
+     * @brief Get the tree associated to this instance.
+     *
+     * @return The Tree object associated to this instance.
+     */
+    const Tree* getTree() const { return templateTree_; }
 
     /**
      * @brief Enable the use of continuous rates instead of discrete rates.
@@ -273,35 +278,41 @@ class NonHomogeneousSequenceSimulator:
      * @param yn Tell if we should use continuous rates.
      */
     void enableContinuousRates(bool yn) { continuousRates_ = yn; }
-	
-	protected:
-		
-		/**
-		 * @brief Evolve from an initial state along a branch, knowing the evolutionary rate class.
-		 *
-		 * This method is fast since all pijt have been computed in the constructor of the class.
+  
+  protected:
+    
+    /**
+     * @brief Evolve from an initial state along a branch, knowing the evolutionary rate class.
+     *
+     * This method is fast since all pijt have been computed in the constructor of the class.
      * This method is used for the implementation of the SiteSimulator interface.
-		 */
-		int evolve(const SNode * node, int initialState, size_t rateClass) const;
-		
-		/**
-		 * @brief Evolve from an initial state along a branch, knowing the evolutionary rate.
-		 *
-		 * This method is slower than the previous one since exponential terms must be computed.
+     */
+    size_t evolve(const SNode* node, size_t initialStateIndex, size_t rateClass) const;
+    
+    /**
+     * @brief Evolve from an initial state along a branch, knowing the evolutionary rate.
+     *
+     * This method is slower than the previous one since exponential terms must be computed.
      * This method is used for the implementation of the SiteSimulator interface.
-		 */
-		int evolve(const SNode * node, int initialState, double rate) const;
-		
+     */
+    size_t evolve(const SNode* node, size_t initialStateIndex, double rate) const;
+    
     /**
      * @brief The same as the evolve(initialState, rateClass) function, but for several sites at a time.
      *
      * This method is used for the implementation of the SequenceSimulator interface.
      */
-		void multipleEvolve(const SNode* node, const Vint& initialState, const std::vector<size_t>& rateClasses, Vint& finalStates) const;
-		SiteContainer* multipleEvolve(const Vint& initialStates, const std::vector<size_t>& rateClasses) const;
-		
-    void dEvolve(int initialState, double rate, RASiteSimulationResult& rassr) const;
-		
+    void multipleEvolve(
+        const SNode* node,
+        const std::vector<size_t>& initialStateIndices,
+        const std::vector<size_t>& rateClasses,
+        std::vector<size_t>& finalStates) const;
+    SiteContainer* multipleEvolve(
+        const std::vector<size_t>& initialStates,
+        const std::vector<size_t>& rateClasses) const;
+    
+    void dEvolve(size_t initialState, double rate, RASiteSimulationResult& rassr) const;
+    
     /**
      * @name The 'Internal' methods.
      *
@@ -315,16 +326,16 @@ class NonHomogeneousSequenceSimulator:
     /**
      * This method uses the states_ variable for saving ancestral states.
      */
-		void evolveInternal(SNode* node, double rate) const;
+    void evolveInternal(SNode* node, double rate) const;
     /**
      * This method uses the multipleStates_ variable for saving ancestral states.
      */
- 		void multipleEvolveInternal(SNode* node, const std::vector<size_t>& rateClasses) const;
+     void multipleEvolveInternal(SNode* node, const std::vector<size_t>& rateClasses) const;
 
     /**
      * This method uses the states_ variable for saving ancestral states.
      */
-		void dEvolveInternal(SNode * node, double rate, RASiteSimulationResult & rassr) const;
+    void dEvolveInternal(SNode * node, double rate, RASiteSimulationResult & rassr) const;
     /** @} */
 
 };
diff --git a/src/Bpp/Phyl/Simulation/SequenceSimulationTools.cpp b/src/Bpp/Phyl/Simulation/SequenceSimulationTools.cpp
index 6ae1b44..602a315 100644
--- a/src/Bpp/Phyl/Simulation/SequenceSimulationTools.cpp
+++ b/src/Bpp/Phyl/Simulation/SequenceSimulationTools.cpp
@@ -39,7 +39,7 @@
 
 #include "SequenceSimulationTools.h"
 
-// From SeqLib:
+// From bpp-seq:
 #include <Bpp/Seq/Container/VectorSiteContainer.h>
 
 using namespace bpp;
@@ -51,8 +51,8 @@ SiteContainer* SequenceSimulationTools::simulateSites(const SiteSimulator& simul
   vector<const Site*> vs(numberOfSites);
   for (size_t i = 0; i < numberOfSites; i++)
   {
-    Site* s = simulator.simulate(rates[i]);
-    s->setPosition((int)i);
+    Site* s = simulator.simulateSite(rates[i]);
+    s->setPosition(static_cast<int>(i));
     vs[i] = s;
   }
   SiteContainer* sites = new VectorSiteContainer(vs, simulator.getAlphabet());
@@ -66,7 +66,7 @@ SiteContainer* SequenceSimulationTools::simulateSites(const SiteSimulator& simul
   return sites;
 }
 
-SiteContainer* SequenceSimulationTools::simulateSites(const SiteSimulator& simulator, const vector<double>& rates, const vector<int>& states)
+SiteContainer* SequenceSimulationTools::simulateSites(const SiteSimulator& simulator, const vector<double>& rates, const vector<size_t>& states)
 throw (Exception)
 {
   size_t numberOfSites = rates.size();
@@ -75,8 +75,30 @@ throw (Exception)
   vector<const Site*> vs(numberOfSites);
   for (size_t i = 0; i < numberOfSites; i++)
   {
-    Site* s = simulator.simulate(states[i], rates[i]);
-    s->setPosition((int)i);
+    Site* s = simulator.simulateSite(states[i], rates[i]);
+    s->setPosition(static_cast<int>(i));
+    vs[i] = s;
+  }
+  SiteContainer* sites = new VectorSiteContainer(vs, simulator.getAlphabet());
+  sites->setSequencesNames(simulator.getSequencesNames(), false);
+  // Freeing memory:
+  for (size_t i = 0; i < numberOfSites; i++)
+  {
+    delete vs[i];
+  }
+
+  return sites;
+}
+
+SiteContainer* SequenceSimulationTools::simulateSites(const SiteSimulator& simulator, const vector<size_t>& states)
+throw (Exception)
+{
+  size_t numberOfSites = states.size();
+  vector<const Site*> vs(numberOfSites);
+  for (size_t i = 0; i < numberOfSites; i++)
+  {
+    Site* s = simulator.simulateSite(states[i]);
+    s->setPosition(static_cast<int>(i));
     vs[i] = s;
   }
   SiteContainer* sites = new VectorSiteContainer(vs, simulator.getAlphabet());
diff --git a/src/Bpp/Phyl/Simulation/SequenceSimulationTools.h b/src/Bpp/Phyl/Simulation/SequenceSimulationTools.h
index 867dc4d..2e7ed5a 100755
--- a/src/Bpp/Phyl/Simulation/SequenceSimulationTools.h
+++ b/src/Bpp/Phyl/Simulation/SequenceSimulationTools.h
@@ -5,7 +5,7 @@
 //
 
 /*
-Copyright or © or Copr. CNRS, (November 16, 2004)
+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.
@@ -56,45 +56,57 @@ namespace bpp
  */
 class SequenceSimulationTools
 {
-	public:
-		SequenceSimulationTools() {}
-		~SequenceSimulationTools() {}
-
-	public:
-		
-		/**
-		 * @brief Simulate a set of sites knowing their rate.
-		 *
-		 * This method is rather slow.
-		 * consider using a discrete rate distribution and a SequenceSimulator,
-		 * which is realy faster.
-		 * This method should be used only for continuous rate distribution, or
-		 * as estimated from posterior rates for instance.
-		 *
-		 * @see SequenceSimulator
-		 * @param simulator A SiteSimulator object to use to simulate sites.
-		 * @param rates     the rates to use, one for each site to simulate.
-		 * @return          A container with all simulated sites.
-		 */
-		static SiteContainer * simulateSites(const SiteSimulator & simulator, const std::vector<double> & rates);
-
-		/**
-		 * @brief Simulate a set of sites knowing their rate and ancestral state.
-		 *
-		 * This method is rather slow.
-		 * consider using a discrete rate distribution and a SequenceSimulator,
-		 * which is realy faster.
-		 * This method should be used only for continuous rate distribution, or
-		 * as estimated from posterior rates for instance.
-		 *
-		 * @see SequenceSimulator
-		 * @param simulator A SiteSimulator object to use to simulate sites.
-		 * @param rates     the rates to use, one for each site to simulate.
-		 * @param states    the ancestral states to use, one for each site to simulate.
-		 * @return          A container with all simulated sites.
-		 */
-		static SiteContainer * simulateSites(const SiteSimulator & simulator, const std::vector<double> & rates, const std::vector<int> & states)
-			throw (Exception);
+  public:
+    SequenceSimulationTools() {}
+    ~SequenceSimulationTools() {}
+
+  public:
+    
+    /**
+     * @brief Simulate a set of sites knowing their rate.
+     *
+     * This method is rather slow.
+     * consider using a discrete rate distribution and a SequenceSimulator,
+     * which is realy faster.
+     * This method should be used only for continuous rate distribution, or
+     * as estimated from posterior rates for instance.
+     *
+     * @see SequenceSimulator
+     * @param simulator A SiteSimulator object to use to simulate sites.
+     * @param rates     the rates to use, one for each site to simulate.
+     * @return          A container with all simulated sites.
+     */
+    static SiteContainer* simulateSites(const SiteSimulator& simulator, const std::vector<double>& rates);
+
+    /**
+     * @brief Simulate a set of sites knowing their rate and ancestral state.
+     *
+     * This method is rather slow.
+     * consider using a discrete rate distribution and a SequenceSimulator,
+     * which is realy faster.
+     * This method should be used only for continuous rate distribution, or
+     * as estimated from posterior rates for instance.
+     *
+     * @see SequenceSimulator
+     * @param simulator A SiteSimulator object to use to simulate sites.
+     * @param rates     the rates to use, one for each site to simulate.
+     * @param states    the ancestral states to use, one for each site to simulate.
+     * @return          A container with all simulated sites.
+     */
+    static SiteContainer* simulateSites(const SiteSimulator& simulator, const std::vector<double>& rates, const std::vector<size_t>& states)
+      throw (Exception);
+
+    /**
+     * @brief Simulate a set of sites knowing ancestral state.
+     *
+     * @see SequenceSimulator
+     * @param simulator A SiteSimulator object to use to simulate sites.
+     * @param states    the ancestral states to use, one for each site to simulate.
+     * @return          A container with all simulated sites.
+     */
+    static SiteContainer* simulateSites(const SiteSimulator& simulator, const std::vector<size_t>& states)
+      throw (Exception);
+
 };
 
 } //end of namespace bpp.
diff --git a/src/Bpp/Phyl/Simulation/SequenceSimulator.h b/src/Bpp/Phyl/Simulation/SequenceSimulator.h
index 599c3db..ef0fa94 100755
--- a/src/Bpp/Phyl/Simulation/SequenceSimulator.h
+++ b/src/Bpp/Phyl/Simulation/SequenceSimulator.h
@@ -40,9 +40,10 @@ knowledge of the CeCILL license and that you accept its terms.
 #ifndef _SEQUENCESIMULATOR_H_
 #define _SEQUENCESIMULATOR_H_
 
+// From bpp-core:
 #include <Bpp/Clonable.h>
 
-// From SeqLib:
+// From bpp-seq:
 #include <Bpp/Seq/Container/SiteContainer.h>
 
 namespace bpp
@@ -60,12 +61,12 @@ class SequenceSimulator:
     virtual ~SequenceSimulator() {}
 
 #ifndef NO_VIRTUAL_COV
-    SequenceSimulator * clone() const = 0;
+    SequenceSimulator* clone() const = 0;
 #endif
   
   public:
-    virtual SiteContainer * simulate(size_t numberOfSites) const = 0;
-    virtual const Alphabet * getAlphabet() const = 0;  
+    virtual SiteContainer* simulate(size_t numberOfSites) const = 0;
+    virtual const Alphabet* getAlphabet() const = 0;  
 };
 
 } //end of namespace bpp.
diff --git a/src/Bpp/Phyl/Simulation/SiteSimulator.h b/src/Bpp/Phyl/Simulation/SiteSimulator.h
index e5c5361..736a6ce 100755
--- a/src/Bpp/Phyl/Simulation/SiteSimulator.h
+++ b/src/Bpp/Phyl/Simulation/SiteSimulator.h
@@ -40,7 +40,7 @@ knowledge of the CeCILL license and that you accept its terms.
 #ifndef _SITESIMULATOR_H_
 #define _SITESIMULATOR_H_
 
-// From SeqLib:
+// From bpp-seq:
 #include <Bpp/Seq/Site.h>
 
 namespace bpp
@@ -59,12 +59,12 @@ class SiteSimulator
     virtual ~SiteSimulator() {}
     
   public:
-    virtual Site * simulate() const = 0;
-    virtual Site * simulate(int ancestralState) const = 0;
-    virtual Site * simulate(int ancestralState, double rate) const = 0;
-    virtual Site * simulate(double rate) const = 0;
+    virtual Site* simulateSite() const = 0;
+    virtual Site* simulateSite(size_t ancestralStateIndex) const = 0;
+    virtual Site* simulateSite(size_t ancestralStateIndex, double rate) const = 0;
+    virtual Site* simulateSite(double rate) const = 0;
     virtual std::vector<std::string> getSequencesNames() const = 0;
-    virtual const Alphabet * getAlphabet() const = 0;
+    virtual const Alphabet* getAlphabet() const = 0;
 };
 
 } //end of namespace bpp.
diff --git a/src/Bpp/Phyl/TreeTemplate.h b/src/Bpp/Phyl/TreeTemplate.h
index 040ea7d..60ca3d7 100644
--- a/src/Bpp/Phyl/TreeTemplate.h
+++ b/src/Bpp/Phyl/TreeTemplate.h
@@ -388,7 +388,7 @@ public:
   void swapNodes(int parentId, size_t i1, size_t i2) throw (NodeNotFoundException, IndexOutOfBoundsException)
   {
     std::vector<N*> nodes = TreeTemplateTools::searchNodeWithId<N>(*root_, parentId);
-    if (nodes.size() == 0) throw NodeNotFoundException("TreeTemplate:swapNodes(): Node with id not found.", "" + parentId);
+    if (nodes.size() == 0) throw NodeNotFoundException("TreeTemplate:swapNodes(): Node with id not found.", TextTools::toString(parentId));
     for (size_t i = 0; i < nodes.size(); i++) { nodes[i]->swap(i1, i2); }
   }
 
diff --git a/src/Bpp/Phyl/TreeTemplateTools.cpp b/src/Bpp/Phyl/TreeTemplateTools.cpp
index 83e23b4..f0633fc 100644
--- a/src/Bpp/Phyl/TreeTemplateTools.cpp
+++ b/src/Bpp/Phyl/TreeTemplateTools.cpp
@@ -253,7 +253,7 @@ TreeTemplateTools::Element TreeTemplateTools::getElement(const string& elt) thro
 
 Node* TreeTemplateTools::parenthesisToNode(const string& description, bool bootstrap, const string& propertyName, bool withId)
 {
-  //cout << "NODE: " << description << endl;
+  // cout << "NODE: " << description << endl;
   Element elt = getElement(description);
 
   // New node:
@@ -292,13 +292,13 @@ Node* TreeTemplateTools::parenthesisToNode(const string& description, bool boots
 
   if (elt.isLeaf)
   {
-    //This is a leaf:
+    // This is a leaf:
     string name = TextTools::removeSurroundingWhiteSpaces(elements[0]);
     if (withId)
     {
       StringTokenizer st(name, "_", true, true);
       ostringstream realName;
-      for (int i = 0; i < static_cast<int>(st.numberOfRemainingTokens()) - 1; i++)
+      for (size_t i = 0; i < st.numberOfRemainingTokens() - 1; ++i)
       {
         if (i != 0)
         {
@@ -409,7 +409,7 @@ string TreeTemplateTools::nodeToParenthesis(const Node& node, bool bootstrap, co
       if (node.hasBranchProperty(propertyName))
       {
         const BppString* ppt = dynamic_cast<const BppString*>(node.getBranchProperty(propertyName));
-        if (ppt) 
+        if (ppt)
           s << *ppt;
         else
           throw Exception("TreeTemplateTools::nodeToParenthesis. Property should be a BppString.");
@@ -428,7 +428,7 @@ string TreeTemplateTools::treeToParenthesis(const TreeTemplate<Node>& tree, bool
   ostringstream s;
   s << "(";
   const Node* node = tree.getRootNode();
-  if (node->isLeaf() && node->hasName()) //In case we have a tree like ((A:1.0)); where the root node is an unamed leaf!
+  if (node->isLeaf() && node->hasName()) // In case we have a tree like ((A:1.0)); where the root node is an unamed leaf!
   {
     s << node->getName();
     for (size_t i = 0; i < node->getNumberOfSons(); ++i)
@@ -482,8 +482,9 @@ string TreeTemplateTools::treeToParenthesis(const TreeTemplate<Node>& tree, bool
   }
   else
   {
-    if (node->hasBranchProperty(propertyName)) {
-      const BppString* ppt =dynamic_cast<const BppString*>(node->getBranchProperty(propertyName));
+    if (node->hasBranchProperty(propertyName))
+    {
+      const BppString* ppt = dynamic_cast<const BppString*>(node->getBranchProperty(propertyName));
       if (ppt)
         s << *ppt;
       else
@@ -578,7 +579,7 @@ void TreeTemplateTools::scaleTree(Node& node, double factor) throw (NodePExcepti
 TreeTemplate<Node>* TreeTemplateTools::getRandomTree(vector<string>& leavesNames, bool rooted)
 {
   if (leavesNames.size() == 0)
-    return 0;  // No taxa.
+    return 0;                                // No taxa.
   // This vector will contain all nodes.
   // Start with all leaves, and then group nodes randomly 2 by 2.
   // Att the end, contains only the root node of the tree.
@@ -592,12 +593,12 @@ TreeTemplate<Node>* TreeTemplateTools::getRandomTree(vector<string>& leavesNames
   while (nodes.size() > (rooted ? 2 : 3))
   {
     // Select random nodes:
-    int pos1 = RandomTools::giveIntRandomNumberBetweenZeroAndEntry(static_cast<int>(nodes.size()));
+    size_t pos1 = RandomTools::giveIntRandomNumberBetweenZeroAndEntry<size_t>(nodes.size());
     Node* node1 = nodes[pos1];
-    nodes.erase(nodes.begin() + pos1);
-    int pos2 = RandomTools::giveIntRandomNumberBetweenZeroAndEntry(static_cast<int>(nodes.size()));
+    nodes.erase(nodes.begin() + static_cast<ptrdiff_t>(pos1));
+    size_t pos2 = RandomTools::giveIntRandomNumberBetweenZeroAndEntry<size_t>(nodes.size());
     Node* node2 = nodes[pos2];
-    nodes.erase(nodes.begin() + pos2);
+    nodes.erase(nodes.begin() + static_cast<ptrdiff_t>(pos2));
     // Add new node:
     Node* parent = new Node();
     parent->addSon(node1);
@@ -638,27 +639,40 @@ vector<Node*> TreeTemplateTools::getPathBetweenAnyTwoNodes(Node& node1, Node& no
     nodeUp = nodeUp->getFather();
   }
   pathMatrix2.push_back(nodeUp); // The root.
-  // Must check that the two nodes have the same root!!!
-
-  size_t tmp1 = pathMatrix1.size() - 1;
-  size_t tmp2 = pathMatrix2.size() - 1;
 
-  while (pathMatrix1[tmp1] == pathMatrix2[tmp2]
-         and tmp1 > 0
-         and tmp2 > 0)
-  {
-    tmp1--; tmp2--;
-  }
+  size_t pos1 = pathMatrix1.size() - 1;
+  size_t pos2 = pathMatrix2.size() - 1;
+  // Must check that the two nodes have the same root!!!
+  if (pathMatrix1[pos1] != pathMatrix2[pos2])
+    throw Exception("TreeTemplateTools::getPathBetweenAnyTwoNodes(). The two nodes do not have any ancestor in common / do not belong to the same tree.");
+
+  if (pos1 == 0 && pos2 == 0) {
+    //Node 1 and 2 are the root node!
+    path.push_back(pathMatrix1[0]);
+  } else if (pos1 == 0) {
+    //Node 1 is the root node
+    //Note: we need to use push_back here as the insert method does not work with reverse iterators.
+    for (size_t i = pathMatrix2.size(); i > 0; --i)
+      path.push_back(pathMatrix2[i-1]);
+  } else if (pos2 == 0) {
+    //Node 2 is the root node
+    path.insert(path.end(), pathMatrix1.begin(), pathMatrix1.end());
+  } else {
+    Node* commonAnc = 0;
+    while (pathMatrix1[pos1] == pathMatrix2[pos2] && pos1 > 0 && pos2 > 0)
+    {
+      commonAnc = pathMatrix1[pos1];
+      pos1--; pos2--;
+    }
 
-  for (size_t y = 0; y < tmp1; ++y)
-  {
-    path.push_back(pathMatrix1[y]);
-  }
-  if (includeAncestor)
-    path.push_back(pathMatrix1[tmp1]);  // pushing once, the Node that was common to both.
-  for (size_t j = tmp2; j > 0; --j)
-  {
-    path.push_back(pathMatrix2[j - 1]);
+    path.insert(path.end(), pathMatrix1.begin(), pathMatrix1.begin() + static_cast<ptrdiff_t>(pos1 + 1));
+    if (includeAncestor && commonAnc)
+      path.push_back(commonAnc); // pushing once the Node that was common to both.
+                                 // note: if node1 or node2 is the common ancestor, then commonAnc is null
+                                 // and will be added as node1 or node2, respectively, even if includeAncestor is false.
+    //Note: we need to use push_back here as the insert method does not work with reverse iterators.
+    for (size_t i = pos2 + 1; i > 0; --i)
+      path.push_back(pathMatrix2[i-1]);
   }
   return path;
 }
@@ -686,27 +700,40 @@ vector<const Node*> TreeTemplateTools::getPathBetweenAnyTwoNodes(const Node& nod
     nodeUp = nodeUp->getFather();
   }
   pathMatrix2.push_back(nodeUp); // The root.
-  // Must check that the two nodes have the same root!!!
 
-  size_t tmp1 = pathMatrix1.size() - 1;
-  size_t tmp2 = pathMatrix2.size() - 1;
+  size_t pos1 = pathMatrix1.size() - 1;
+  size_t pos2 = pathMatrix2.size() - 1;
+  // Must check that the two nodes have the same root!!!
+  if (pathMatrix1[pos1] != pathMatrix2[pos2])
+    throw Exception("TreeTemplateTools::getPathBetweenAnyTwoNodes(). The two nodes do not have any ancestor in common / do not belong to the same tree.");
+
+  if (pos1 == 0 && pos2 == 0) {
+    //Node 1 and 2 are the root node!
+    path.push_back(pathMatrix1[0]);
+  } else if (pos1 == 0) {
+    //Node 1 is the root node
+    //Note: we need to use push_back here as the insert method does not work with reverse iterators.
+    for (size_t i = pathMatrix2.size(); i > 0; --i)
+      path.push_back(pathMatrix2[i-1]);
+  } else if (pos2 == 0) {
+    //Node 2 is the root node
+    path.insert(path.end(), pathMatrix1.begin(), pathMatrix1.end());
+  } else {
+    const Node* commonAnc = 0;
+    while (pathMatrix1[pos1] == pathMatrix2[pos2] && pos1 > 0 && pos2 > 0)
+    {
+      commonAnc = pathMatrix1[pos1];
+      pos1--; pos2--;
+    }
 
-  while (pathMatrix1[tmp1] == pathMatrix2[tmp2]
-         and tmp1 > 0
-         and tmp2 > 0)
-  {
-    tmp1--; tmp2--;
-  }
-
-  for (size_t y = 0; y < tmp1; ++y)
-  {
-    path.push_back(pathMatrix1[y]);
-  }
-  if (includeAncestor)
-    path.push_back(pathMatrix1[tmp1]);  // pushing once, the Node that was common to both.
-  for (size_t j = tmp2; j > 0; --j)
-  {
-    path.push_back(pathMatrix2[j - 1]);
+    path.insert(path.end(), pathMatrix1.begin(), pathMatrix1.begin() + static_cast<ptrdiff_t>(pos1 + 1));
+    if (includeAncestor && commonAnc)
+      path.push_back(commonAnc); // pushing once the Node that was common to both.
+                                 // note: if node1 or node2 is the common ancestor, then commonAnc is null
+                                 // and will be added as node1 or node2, respectively, even if includeAncestor is false.
+    //Note: we need to use push_back here as the insert method does not work with reverse iterators.
+    for (size_t i = pos2 + 1; i > 0; --i)
+      path.push_back(pathMatrix2[i-1]);
   }
   return path;
 }
@@ -717,7 +744,7 @@ double TreeTemplateTools::getDistanceBetweenAnyTwoNodes(const Node& node1, const
 {
   vector<const Node*> path = getPathBetweenAnyTwoNodes(node1, node2, false);
   double d = 0;
-  for (size_t i = 0; i < path.size(); i++)
+  for (size_t i = 0; i < path.size(); ++i)
   {
     d += path[i]->getDistanceToFather();
   }
@@ -1007,39 +1034,41 @@ TreeTemplateTools::OrderTreeData_ TreeTemplateTools::orderTree_(Node& node, bool
 }
 
 /******************************************************************************/
+const short TreeTemplateTools::MIDROOT_VARIANCE = 0;
+const short TreeTemplateTools::MIDROOT_SUM_OF_SQUARES = 1;
 
-void TreeTemplateTools::midRoot (TreeTemplate<Node>& tree, const string& criterion)
+void TreeTemplateTools::midRoot(TreeTemplate<Node>& tree, short criterion, bool forceBranchRoot)
 {
-  if(not (criterion == "variance" || "sum of squares"))
-    throw Exception("TreeTemplateTools::reRoot Illegal criterion value '" + criterion + "'");
+  if (criterion != MIDROOT_VARIANCE && criterion != MIDROOT_SUM_OF_SQUARES)
+    throw Exception("TreeTemplateTools::midRoot(). Illegal criterion value '" + TextTools::toString(criterion) + "'");
 
-  if(tree.isRooted())
+  if (tree.isRooted())
     tree.unroot();
   Node* ref_root = tree.getRootNode();
-   /*
-   * The bestRoot object records :
-   * -- the current best branch : .first
-   * -- the current best value of the criterion : .second["value"]
-   * -- the best position of the root on the branch : .second["position"]
-   *      0 is toward the original root, 1 is away from it
-   */
+  //
+  // The bestRoot object records :
+  // -- the current best branch : .first
+  // -- the current best value of the criterion : .second["value"]
+  // -- the best position of the root on the branch : .second["position"]
+  //      0 is toward the original root, 1 is away from it
+  //
   pair<Node*, map<string, double> > best_root_branch;
   best_root_branch.first = ref_root; // nota: the root does not correspond to a branch as it has no father
   best_root_branch.second ["position"] = -1;
   best_root_branch.second ["score"] = numeric_limits<double>::max();
 
   // find the best root
-  TreeTemplateTools::getBestRootInSubtree(tree, criterion, ref_root, best_root_branch);
+  getBestRootInSubtree_(tree, criterion, ref_root, best_root_branch);
   tree.rootAt(ref_root); // back to the original root
 
   // reroot
   const double pos = best_root_branch.second["position"];
-  if(pos<1e-6 or pos>1-1e-6)
+  if (pos < 1e-6 or pos > 1 - 1e-6)
     // The best root position is on a node (this is often the case with the sum of squares criterion)
-    tree.rootAt(pos<1e-6 ? best_root_branch.first->getFather() : best_root_branch.first);
+    tree.rootAt(pos < 1e-6 ? best_root_branch.first->getFather() : best_root_branch.first);
   else
-    // The best root position is somewhere on a branch (a new Node is created)
-    {
+  // The best root position is somewhere on a branch (a new Node is created)
+  {
     Node* new_root = new Node();
     new_root->setId( TreeTools::getMPNUId(tree, tree.getRootId()) );
 
@@ -1051,43 +1080,109 @@ void TreeTemplateTools::midRoot (TreeTemplate<Node>& tree, const string& criteri
     new_root->addSon(best_root_branch.first);
 
     new_root->setDistanceToFather(max(pos * root_branch_length, 1e-6));
-    best_root_branch.first->setDistanceToFather(max((1-pos) * root_branch_length, 1e-6));
+    best_root_branch.first->setDistanceToFather(max((1 - pos) * root_branch_length, 1e-6));
 
     // The two branches leaving the root must have the same branch properties
     const vector<string> branch_properties = best_root_branch.first->getBranchPropertyNames();
-    for(vector<string>::const_iterator p = branch_properties.begin(); p!=branch_properties.end(); ++p)
+    for (vector<string>::const_iterator p = branch_properties.begin(); p != branch_properties.end(); ++p)
+    {
       new_root->setBranchProperty(*p, *best_root_branch.first->getBranchProperty(*p));
+    }
 
     tree.rootAt(new_root);
+  }
+
+  if (forceBranchRoot) // if we want the root to be on a branch, not on a node
+  {
+    Node* orig_root = tree.getRootNode();
+    vector<Node*> root_sons = orig_root->getSons();
+    if (root_sons.size() > 2)
+    {
+      Node* nearest = root_sons.at(0);
+      for (vector<Node*>::iterator n = root_sons.begin(); n !=
+           root_sons.end(); ++n)
+      {
+        if ((**n).getDistanceToFather() < nearest->getDistanceToFather())
+          nearest = *n;
+      }
+      const double d = nearest->getDistanceToFather();
+      Node* new_root = new Node();
+      new_root->setId( TreeTools::getMPNUId(tree, tree.getRootId()) );
+      orig_root->removeSon(nearest);
+      orig_root->addSon(new_root);
+      new_root->addSon(nearest);
+      new_root->setDistanceToFather(d / 2.);
+      nearest->setDistanceToFather(d / 2.);
+      const vector<string> branch_properties = nearest->getBranchPropertyNames();
+      for (vector<string>::const_iterator p = branch_properties.begin(); p != branch_properties.end(); ++p)
+      {
+        new_root->setBranchProperty(*p, *nearest->getBranchProperty(*p));
+      }
+      tree.rootAt(new_root);
     }
+  }
 }
 
 /******************************************************************************/
 
-double TreeTemplateTools::getRadius (TreeTemplate<Node>& tree)
+double TreeTemplateTools::getRadius(TreeTemplate<Node>& tree)
 {
-  TreeTemplateTools::midRoot(tree, "sum of squares");
-  Moments_ moments = getSubtreeMoments(tree.getRootNode());
+  TreeTemplateTools::midRoot(tree, MIDROOT_SUM_OF_SQUARES, false);
+  Moments_ moments = getSubtreeMoments_(tree.getRootNode());
   double radius = moments.sum / moments.numberOfLeaves;
   return radius;
 }
 
 /******************************************************************************/
 
-void TreeTemplateTools::getBestRootInSubtree (TreeTemplate<Node>& tree, const string& criterion, Node* node, pair<Node*, map<string, double> >& bestRoot)
+void TreeTemplateTools::unresolveUncertainNodes(Node& subtree, double threshold, const std::string& property)
+{
+  for (size_t i = 0; i < subtree.getNumberOfSons(); ++i)
+  {
+    Node* son = subtree.getSon(i);
+    if (son->getNumberOfSons() > 0)
+    {
+      // Recursion:
+      unresolveUncertainNodes(*son, threshold, property);
+      // Deal with this node:
+      if (son->hasBranchProperty(property))
+      {
+        double value = dynamic_cast<Number<double>*>(son->getBranchProperty(property))->getValue();
+        if (value < threshold)
+        {
+          // We remove this branch:
+          double brlen = son->getDistanceToFather();
+          for (size_t j = 0; j < son->getNumberOfSons(); ++j)
+          {
+            Node* grandSon = son->getSon(j);
+            grandSon->setDistanceToFather(grandSon->getDistanceToFather() + brlen);
+            subtree.addSon(i, grandSon);
+          }
+          subtree.removeSon(son);
+          delete son;
+        }
+      }
+    }
+  }
+}
+
+
+/******************************************************************************/
+
+void TreeTemplateTools::getBestRootInSubtree_(TreeTemplate<Node>& tree, short criterion, Node* node, pair<Node*, map<string, double> >& bestRoot)
 {
   const vector<Node*> sons = node->getSons(); // copy
   tree.rootAt(node);
 
   // Try to place the root on each branch downward node
-  for(vector<Node*>::const_iterator son=sons.begin(); son!=sons.end(); ++son)
-    {
+  for (vector<Node*>::const_iterator son = sons.begin(); son != sons.end(); ++son)
+  {
     // Compute the moment of the subtree on son's side
-    Moments_ son_moment = getSubtreeMoments(*son);
+    Moments_ son_moment = getSubtreeMoments_(*son);
 
     // Compute the moment of the subtree on node's side
     tree.rootAt(*son);
-    Moments_ node_moment = getSubtreeMoments(node);
+    Moments_ node_moment = getSubtreeMoments_(node);
     tree.rootAt(node);
 
     /*
@@ -1105,81 +1200,81 @@ void TreeTemplateTools::getBestRootInSubtree (TreeTemplate<Node>& tree, const st
     const double n1 = m1.numberOfLeaves;
     const double n2 = m2.numberOfLeaves;
 
-    double A=0, B=0, C=0;
-    if(criterion == "sum of squares")
-      {
+    double A = 0, B = 0, C = 0;
+    if (criterion == MIDROOT_SUM_OF_SQUARES)
+    {
       A = (n1 + n2) * d * d;
       B = 2 * d * (m1.sum - m2.sum) - 2 * n2 * d * d;
       C = m1.squaresSum + m2.squaresSum
           + 2 * m2.sum * d
           + n2 * d * d;
-      }
-    else if(criterion == "variance")
-      {
-      A = 4 * n1 * n2 * d*d;
+    }
+    else if (criterion == MIDROOT_VARIANCE)
+    {
+      A = 4 * n1 * n2 * d * d;
       B = 4 * d * ( n2 * m1.sum - n1 * m2.sum - d * n1 * n2);
       C = (n1 + n2) * (m1.squaresSum + m2.squaresSum) + n1 * d * n2 * d
           + 2 * n1 * d * m2.sum - 2 * n2 * d * m1.sum
           - (m1.sum + m2.sum) * (m1.sum + m2.sum);
-      }
+    }
 
-    if(A < 1e-20)
-      {
+    if (A < 1e-20)
+    {
       min_criterion_value = numeric_limits<double>::max();
       best_position = 0.5;
-      }
+    }
     else
+    {
+      min_criterion_value = C - B * B / (4 * A);
+      best_position = -B / (2 * A);
+      if (best_position < 0)
       {
-      min_criterion_value = C - B*B / (4*A);
-      best_position = - B / (2*A);
-      if(best_position < 0)
-        {
         best_position = 0;
         min_criterion_value = C;
-        }
-      else if(best_position > 1)
-        {
+      }
+      else if (best_position > 1)
+      {
         best_position = 1;
-        min_criterion_value = A+B+C;
-        }
+        min_criterion_value = A + B + C;
       }
+    }
 
     // Is this branch is the best seen, update 'bestRoot'
-    if(min_criterion_value < bestRoot.second["score"])
-      {
+    if (min_criterion_value < bestRoot.second["score"])
+    {
       bestRoot.first = *son;
       bestRoot.second["position"] = best_position;
       bestRoot.second["score"] = min_criterion_value;
-      }
+    }
 
     // Recurse
-    TreeTemplateTools::getBestRootInSubtree(tree, criterion, *son, bestRoot);
-    }
+    TreeTemplateTools::getBestRootInSubtree_(tree, criterion, *son, bestRoot);
+  }
 }
 
 /******************************************************************************/
 
-TreeTemplateTools::Moments_ TreeTemplateTools::getSubtreeMoments (const Node* node)
+TreeTemplateTools::Moments_ TreeTemplateTools::getSubtreeMoments_(const Node* node)
 {
-  TreeTemplateTools::Moments_ moments = {0,0,0};
+  TreeTemplateTools::Moments_ moments = {0, 0, 0};
 
-  if(node->isLeaf())
-    {
+  if (node->isLeaf())
+  {
     moments.numberOfLeaves = 1;
-    }
+  }
   else
-    {
+  {
     const size_t nsons = node->getNumberOfSons();
-    for(size_t i=0; i<nsons; ++i)
-      {
+    for (size_t i = 0; i < nsons; ++i)
+    {
       const Node* son = node->getSon(i);
-      const TreeTemplateTools::Moments_ son_moments = TreeTemplateTools::getSubtreeMoments(son);
+      const TreeTemplateTools::Moments_ son_moments = TreeTemplateTools::getSubtreeMoments_(son);
       const double d = son->getDistanceToFather();
       moments.numberOfLeaves += son_moments.numberOfLeaves;
       moments.sum += son_moments.sum + d * son_moments.numberOfLeaves;
-      moments.squaresSum += son_moments.squaresSum + 2 * d * son_moments.sum + son_moments.numberOfLeaves * d*d;
-      }
+      moments.squaresSum += son_moments.squaresSum + 2 * d * son_moments.sum + son_moments.numberOfLeaves * d * d;
     }
+  }
 
   return moments;
 }
diff --git a/src/Bpp/Phyl/TreeTemplateTools.h b/src/Bpp/Phyl/TreeTemplateTools.h
index 8e23145..4bb8844 100644
--- a/src/Bpp/Phyl/TreeTemplateTools.h
+++ b/src/Bpp/Phyl/TreeTemplateTools.h
@@ -7,37 +7,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.
-*/
+   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 _TREETEMPLATETOOLS_H_
 #define _TREETEMPLATETOOLS_H_
@@ -45,13 +45,12 @@ knowledge of the CeCILL license and that you accept its terms.
 #include "TreeTools.h"
 #include <Bpp/Numeric/Random/RandomTools.h>
 
-//From the STL:
+// From the STL:
 #include <string>
 #include <vector>
 
 namespace bpp
 {
-
 template<class N> class TreeTemplate;
 
 
@@ -62,80 +61,81 @@ template<class N> class TreeTemplate;
  */
 class TreeTemplateTools
 {
-  public:
-    TreeTemplateTools() {}
-    virtual ~TreeTemplateTools() {}
-
-  public:
-    
-    /**
-     * @name Retrieve topology information
-     *
-     * @{
-     */
-
-    /**
-     * @brief Retrieve all leaves from a subtree.
-     *
-     * @param node The node that defines the subtree.
-     * @return A vector of pointers toward each leaf in the subtree.
-     */
-    template<class N>
-    static std::vector<N*> getLeaves(N& node)
+public:
+  TreeTemplateTools() {}
+  virtual ~TreeTemplateTools() {}
+
+public:
+  /**
+   * @name Retrieve topology information
+   *
+   * @{
+   */
+
+  /**
+   * @brief Retrieve all leaves from a subtree.
+   *
+   * @param node The node that defines the subtree.
+   * @return A vector of pointers toward each leaf in the subtree.
+   */
+  template<class N>
+  static std::vector<N*> getLeaves(N& node)
+  {
+    std::vector<N*> leaves;
+    getLeaves<N>(node, leaves);
+    return leaves;
+  }
+
+  /**
+   * @brief Retrieve all leaves from a subtree.
+   *
+   * @param node The node that defines the subtree.
+   * @param leaves A vector of pointers toward each leaf in the subtree.
+   */
+  template<class N>
+  static void getLeaves(N& node, std::vector<N*>& leaves)
+  {
+    if (node.isLeaf())
     {
-      std::vector<N*> leaves;
-      getLeaves<N>(node, leaves);
-      return leaves;
+      leaves.push_back(&node);
     }
-
-    /**
-     * @brief Retrieve all leaves from a subtree.
-     *
-     * @param node The node that defines the subtree.
-     * @param leaves A vector of pointers toward each leaf in the subtree.
-     */
-    template<class N>
-    static void getLeaves(N & node, std::vector<N *> & leaves)
+    for (size_t i = 0; i < node.getNumberOfSons(); i++)
     {
-      if(node.isLeaf())
-      {
-        leaves.push_back(& node);
-      }
-      for(size_t i = 0; i < node.getNumberOfSons(); i++)
-      {
-        getLeaves<N>(* node.getSon(i), leaves);
-      }
+      getLeaves<N>(*node.getSon(i), leaves);
     }
+  }
+
+  /**
+   * @brief Retrieve all leaves ids from a subtree.
+   *
+   * @param node The node that defines the subtree.
+   * @return A vector of ids.
+   */
+  static std::vector<int> getLeavesId(const Node& node)
+  {
+    std::vector<int> ids;
+    getLeavesId(node, ids);
+    return ids;
+  }
 
-    /**
-     * @brief Retrieve all leaves ids from a subtree.
-     *
-     * @param node The node that defines the subtree.
-     * @return A vector of ids.
-     */
-    static std::vector<int> getLeavesId(const Node& node)
+  /**
+   * @brief Retrieve all leaves ids from a subtree.
+   *
+   * @param node The node that defines the subtree.
+   * @param ids A vector of ids.
+   */
+  static void getLeavesId(const Node& node, std::vector<int>& ids)
+  {
+    if (node.isLeaf())
     {
-      std::vector<int> ids;
-      getLeavesId(node, ids);
-      return ids;
+      ids.push_back(node.getId());
     }
-
-    /**
-     * @brief Retrieve all leaves ids from a subtree.
-     *
-     * @param node The node that defines the subtree.
-     * @param ids A vector of ids.
-     */
-    static void getLeavesId(const Node& node, std::vector<int>& ids)
+    for (size_t i = 0; i < node.getNumberOfSons(); i++)
     {
-      if(node.isLeaf()) {
-        ids.push_back(node.getId());
-      }
-      for(size_t i = 0; i < node.getNumberOfSons(); i++) {
-        getLeavesId(* node.getSon(i), ids);
-      }
+      getLeavesId(*node.getSon(i), ids);
     }
-    
+  }
+
   /**
    * @brief Retrieve all nodes ids that are ancestors of a node.
    *
@@ -146,1101 +146,1136 @@ class TreeTemplateTools
   {
     std::vector<int> ids;
     const Node* n = &node;
-    while (n->hasFather()) {
+    while (n->hasFather())
+    {
       n = n->getFather();
       ids.push_back(n->getId());
     }
     return ids;
   }
 
-    /**
-     * @brief Get the id of a leaf given its name in a subtree.
-     *
-     * @param node The node defining the subtree to search.
-     * @param name The name of the node.
-     * @return The id of the node.
-     * @throw NodeNotFoundException If the node is not found.
-     */
-    static int getLeafId(const Node& node, const std::string& name) throw (NodeNotFoundException)
+  /**
+   * @brief Get the id of a leaf given its name in a subtree.
+   *
+   * @param node The node defining the subtree to search.
+   * @param name The name of the node.
+   * @return The id of the node.
+   * @throw NodeNotFoundException If the node is not found.
+   */
+  static int getLeafId(const Node& node, const std::string& name) throw (NodeNotFoundException)
+  {
+    int* id = 0;
+    searchLeaf(node, name, id);
+    if (id == 0) throw NodeNotFoundException("TreeTemplateTools::getLeafId().", name);
+    else
     {
-      int* id = 0;
-      searchLeaf(node, name, id);
-      if (id == 0) throw NodeNotFoundException("TreeTemplateTools::getLeafId().", name);
-      else
-      {
-        int i = *id;
-        delete id;
-        return i;
-      }
+      int i = *id;
+      delete id;
+      return i;
     }
+  }
 
-    /**
-     * @brief Get the id of a leaf given its name in a subtree.
-     *
-     * @param node The node defining the subtree to search.
-     * @param name The name of the node.
-     * @param id The id of the node.
-     * @throw NodeNotFoundException If the node is not found.
-     */
-    static void searchLeaf(const Node& node, const std::string& name, int*& id) throw (NodeNotFoundException)
+  /**
+   * @brief Get the id of a leaf given its name in a subtree.
+   *
+   * @param node The node defining the subtree to search.
+   * @param name The name of the node.
+   * @param id The id of the node.
+   * @throw NodeNotFoundException If the node is not found.
+   */
+  static void searchLeaf(const Node& node, const std::string& name, int*& id) throw (NodeNotFoundException)
+  {
+    if (node.isLeaf())
     {
-      if (node.isLeaf())
+      if (node.getName() == name)
       {
-        if (node.getName() == name)
-        {
-          id = new int(node.getId());
-          return;
-        }
-      }
-      for (size_t i = 0; i < node.getNumberOfSons(); i++)
-      {
-        searchLeaf(* node.getSon(i), name, id);
+        id = new int(node.getId());
+        return;
       }
     }
+    for (size_t i = 0; i < node.getNumberOfSons(); i++)
+    {
+      searchLeaf(*node.getSon(i), name, id);
+    }
+  }
 
-    /**
-     * @brief Remove a leaf node and its parent node, while correcting for branch lengths.
-     *
-     * @param tree The tree to edit.
-     * @param leafName The name of the leaf node.
-     * @throw NodeNotFoundException If the node is not found.
-     */
-    template<class N>
-    static void dropLeaf(TreeTemplate<N>& tree, const std::string& leafName) throw (NodeNotFoundException, Exception)
+  /**
+   * @brief Remove a leaf node and its parent node, while correcting for branch lengths.
+   *
+   * @param tree The tree to edit.
+   * @param leafName The name of the leaf node.
+   * @throw NodeNotFoundException If the node is not found.
+   */
+  template<class N>
+  static void dropLeaf(TreeTemplate<N>& tree, const std::string& leafName) throw (NodeNotFoundException, Exception)
+  {
+    N* leaf = tree.getNode(leafName);
+    if (!leaf->hasFather())
+      throw Exception("TreeTemplateTools::dropLeaf(). Leaf is the only node in the tree, can't remove it.");
+    N* parent = leaf->getFather();
+    if (parent->getNumberOfSons() > 2)
     {
-      N* leaf = tree.getNode(leafName);
-      if (!leaf->hasFather())
-        throw Exception("TreeTemplateTools::dropLeaf(). Leaf is the only node in the tree, can't remove it.");
-      N* parent = leaf->getFather();
-      if (parent->getNumberOfSons() > 2)
-      {
-        //The easy case:
-        parent->removeSon(leaf);
-        delete leaf;
-      }
-      else if (parent->getNumberOfSons() == 2)
+      // The easy case:
+      parent->removeSon(leaf);
+      delete leaf;
+    }
+    else if (parent->getNumberOfSons() == 2)
+    {
+      // We have to delete the parent node as well:
+      N* brother = parent->getSon(0);
+      if (brother == leaf) brother = parent->getSon(1);
+      if (!parent->hasFather())
       {
-        //We have to delete the parent node as well:
-        N* brother = parent->getSon(0);
-        if (brother == leaf) brother = parent->getSon(1);
-        if (!parent->hasFather())
-        {
-          //The brother becomes the root:
-          if (leaf->hasDistanceToFather() && brother->hasDistanceToFather())
-          {
-            brother->setDistanceToFather(brother->getDistanceToFather() + leaf->getDistanceToFather());
-          }
-          brother->removeFather();
-          tree.setRootNode(brother);
-          delete parent;
-          delete leaf;
-        }
-        else
+        // The brother becomes the root:
+        if (leaf->hasDistanceToFather() && brother->hasDistanceToFather())
         {
-          N* gParent = parent->getFather();
-          if (brother->hasDistanceToFather() && parent->hasDistanceToFather())
-          {
-            brother->setDistanceToFather(brother->getDistanceToFather() + parent->getDistanceToFather());
-          }
-          size_t pos = gParent->getSonPosition(parent);
-          gParent->setSon(pos, brother);
-          delete parent;
-          delete leaf;
+          brother->setDistanceToFather(brother->getDistanceToFather() + leaf->getDistanceToFather());
         }
+        brother->removeFather();
+        tree.setRootNode(brother);
+        delete parent;
+        delete leaf;
       }
       else
       {
-        //Dunno what to do in that case :(
-        throw Exception("TreeTemplateTools::dropLeaf. Parent node as only one child, I don't know what to do in that case :(");
+        N* gParent = parent->getFather();
+        if (brother->hasDistanceToFather() && parent->hasDistanceToFather())
+        {
+          brother->setDistanceToFather(brother->getDistanceToFather() + parent->getDistanceToFather());
+        }
+        size_t pos = gParent->getSonPosition(parent);
+        gParent->setSon(pos, brother);
+        delete parent;
+        delete leaf;
       }
     }
+    else
+    {
+      // Dunno what to do in that case :(
+      throw Exception("TreeTemplateTools::dropLeaf. Parent node as only one child, I don't know what to do in that case :(");
+    }
+  }
 
-    /**
-     * @brief Remove a subtree defined by its root node and its parent node, while correcting for branch lengths.
-     *
-     * @param tree The tree to edit.
-     * @param subtree The subtree to remove, defined by its root node.
-     * @throw Exception If something unexpected happens :s 
-     */
-    template<class N>
-    static void dropSubtree(TreeTemplate<N>& tree, Node* subtree) throw (Exception)
+  /**
+   * @brief Remove a subtree defined by its root node and its parent node, while correcting for branch lengths.
+   *
+   * @param tree The tree to edit.
+   * @param subtree The subtree to remove, defined by its root node.
+   * @throw Exception If something unexpected happens :s
+   */
+  template<class N>
+  static void dropSubtree(TreeTemplate<N>& tree, Node* subtree) throw (Exception)
+  {
+    if (!subtree->hasFather())
+      throw Exception("TreeTemplateTools::dropSubtree(). Trying to remove the full tree!");
+    N* parent = subtree->getFather();
+    if (parent->getNumberOfSons() > 2)
     {
-      if (!subtree->hasFather())
-        throw Exception("TreeTemplateTools::dropSubtree(). Trying to remove the full tree!");
-      N* parent = subtree->getFather();
-      if (parent->getNumberOfSons() > 2)
-      {
-        //The easy case:
-        parent->removeSon(subtree);
-        deleteSubtree(subtree);
-      }
-      else if (parent->getNumberOfSons() == 2)
+      // The easy case:
+      parent->removeSon(subtree);
+      deleteSubtree(subtree);
+    }
+    else if (parent->getNumberOfSons() == 2)
+    {
+      // We have to delete the parent node as well:
+      N* brother = parent->getSon(0);
+      if (brother == subtree) brother = parent->getSon(1);
+      if (!parent->hasFather())
       {
-        //We have to delete the parent node as well:
-        N* brother = parent->getSon(0);
-        if (brother == subtree) brother = parent->getSon(1);
-        if (!parent->hasFather())
+        // The brother becomes the root:
+        if (subtree->hasDistanceToFather() && brother->hasDistanceToFather())
         {
-          //The brother becomes the root:
-          if (subtree->hasDistanceToFather() && brother->hasDistanceToFather())
-          {
-            brother->setDistanceToFather(brother->getDistanceToFather() + subtree->getDistanceToFather());
-          }
-          tree.setRootNode(brother);
-          delete parent;
-          deleteSubtree(subtree);
-        }
-        else
-        {
-          N* gParent = parent->getFather();
-          if (brother->hasDistanceToFather() && parent->hasDistanceToFather())
-          {
-            brother->setDistanceToFather(brother->getDistanceToFather() + parent->getDistanceToFather());
-          }
-          size_t pos = gParent->getSonPosition(parent);
-          gParent->setSon(pos, brother);
-          delete parent;
-          deleteSubtree(subtree);
+          brother->setDistanceToFather(brother->getDistanceToFather() + subtree->getDistanceToFather());
         }
+        tree.setRootNode(brother);
+        delete parent;
+        deleteSubtree(subtree);
       }
       else
       {
-        //Dunno what to do in that case :(
-        throw Exception("TreeTemplateTools::dropSubtree. Parent node as only one child, I don't know what to do in that case :(");
+        N* gParent = parent->getFather();
+        if (brother->hasDistanceToFather() && parent->hasDistanceToFather())
+        {
+          brother->setDistanceToFather(brother->getDistanceToFather() + parent->getDistanceToFather());
+        }
+        size_t pos = gParent->getSonPosition(parent);
+        gParent->setSon(pos, brother);
+        delete parent;
+        deleteSubtree(subtree);
       }
     }
-
-    /**
-     * @brief Sample a subtree by removing leaves randomly.
-     *
-     * @param tree The tree to edit.
-     * @param leaves The leafs names that should be sampled. They must be found in the tree otherwise an exception will be thrown.
-     * @param size The number of leaves in the final sample. If greater or equal to the number of leaf names, the function returns without doing anything.
-     */
-    template<class N>
-    static void sampleSubtree(TreeTemplate<N>& tree, const std::vector<std::string>& leaves, size_t size)
+    else
     {
-      std::vector<std::string> names = leaves;
-      for (size_t n = names.size(); n > size; --n) {
-        size_t i = RandomTools::giveIntRandomNumberBetweenZeroAndEntry(n);
-        dropLeaf(tree, names[i]);
-        names.erase(names.begin() + i);
-      }
+      // Dunno what to do in that case :(
+      throw Exception("TreeTemplateTools::dropSubtree. Parent node as only one child, I don't know what to do in that case :(");
     }
+  }
 
-    /**
-     * @brief Retrieve all son nodes from a subtree.
-     *
-     * @param node The node that defines the subtree.
-     * @return A vector of pointers toward each son node in the subtree.
-     */
-    template<class N>
-    static std::vector<N*> getNodes(N& node)
+  /**
+   * @brief Sample a subtree by removing leaves randomly.
+   *
+   * @param tree The tree to edit.
+   * @param leaves The leafs names that should be sampled. They must be found in the tree otherwise an exception will be thrown.
+   * @param size The number of leaves in the final sample. If greater or equal to the number of leaf names, the function returns without doing anything.
+   */
+  template<class N>
+  static void sampleSubtree(TreeTemplate<N>& tree, const std::vector<std::string>& leaves, size_t size)
+  {
+    std::vector<std::string> names = leaves;
+    for (size_t n = names.size(); n > size; --n)
     {
-      std::vector<N *> nodes;
-      getNodes<N>(node, nodes);
-      return nodes;
+      size_t i = RandomTools::giveIntRandomNumberBetweenZeroAndEntry(n);
+      dropLeaf(tree, names[i]);
+      names.erase(names.begin() + static_cast<ptrdiff_t>(i));
     }
+  }
 
-    /**
-     * @brief Retrieve all son nodes from a subtree.
-     *
-     * @param node The node that defines the subtree.
-     * @param nodes A vector of pointers toward each son node in the subtree.
-     */
-    template<class N>
-    static void getNodes(N & node, std::vector<N*> & nodes)
-    {
-      for(size_t i = 0; i < node.getNumberOfSons(); i++)
-      {
-        getNodes<N>(*node.getSon(i), nodes);
-      }
-      nodes.push_back(& node);
-    }
+  /**
+   * @brief Retrieve all son nodes from a subtree.
+   *
+   * @param node The node that defines the subtree.
+   * @return A vector of pointers toward each son node in the subtree.
+   */
+  template<class N>
+  static std::vector<N*> getNodes(N& node)
+  {
+    std::vector<N*> nodes;
+    getNodes<N>(node, nodes);
+    return nodes;
+  }
 
-    /**
-     * @brief Retrieve all nodes ids from a subtree.
-     *
-     * @param node The node that defines the subtree.
-     * @return A vector of ids.
-     */
-    static std::vector<int> getNodesId(const Node& node)
+  /**
+   * @brief Retrieve all son nodes from a subtree.
+   *
+   * @param node The node that defines the subtree.
+   * @param nodes A vector of pointers toward each son node in the subtree.
+   */
+  template<class N>
+  static void getNodes(N& node, std::vector<N*>& nodes)
+  {
+    for (size_t i = 0; i < node.getNumberOfSons(); i++)
     {
-      std::vector<int> ids;
-      getNodesId(node, ids);
-      return ids;
+      getNodes<N>(*node.getSon(i), nodes);
     }
+    nodes.push_back(&node);
+  }
 
-    /**
-     * @brief Retrieve all branches ids from a subtree.
-     *
-     * @param node The node that defines the subtree.
-     * @return A vector of ids.
-     */
-    static std::vector<int> getBranchesId(const Node& node)
-    {
-      std::vector<int> ids;
-      getBranchesId(node, ids);
-      return ids;
-    }
+  /**
+   * @brief Retrieve all nodes ids from a subtree.
+   *
+   * @param node The node that defines the subtree.
+   * @return A vector of ids.
+   */
+  static std::vector<int> getNodesId(const Node& node)
+  {
+    std::vector<int> ids;
+    getNodesId(node, ids);
+    return ids;
+  }
 
-    /**
-     * @brief Retrieve all nodes ids from a subtree.
-     *
-     * @param node The node that defines the subtree.
-     * @param ids A vector of ids.
-     */
-    static void getNodesId(const Node& node, std::vector<int>& ids)
-    {
-      for (size_t i = 0; i < node.getNumberOfSons(); i++)
-      {
-        getNodesId(*node.getSon(i), ids);
-      }
-      ids.push_back(node.getId());
-    }
+  /**
+   * @brief Retrieve all branches ids from a subtree.
+   *
+   * @param node The node that defines the subtree.
+   * @return A vector of ids.
+   */
+  static std::vector<int> getBranchesId(const Node& node)
+  {
+    std::vector<int> ids;
+    getBranchesId(node, ids);
+    return ids;
+  }
 
-    /**
-     * @brief Retrieve all branches ids from a subtree.
-     *
-     * @param node The node that defines the subtree.
-     * @param ids A vector of ids.
-     */
-    static void getBranchesId(const Node& node, std::vector<int>& ids)
+  /**
+   * @brief Retrieve all nodes ids from a subtree.
+   *
+   * @param node The node that defines the subtree.
+   * @param ids A vector of ids.
+   */
+  static void getNodesId(const Node& node, std::vector<int>& ids)
+  {
+    for (size_t i = 0; i < node.getNumberOfSons(); i++)
     {
-      for (size_t i = 0; i < node.getNumberOfSons(); i++)
-      {
-        getNodesId(*node.getSon(i), ids);
-      }
+      getNodesId(*node.getSon(i), ids);
     }
+    ids.push_back(node.getId());
+  }
 
-    /**
-     * @brief Retrieve all inner nodes from a subtree.
-     *
-     * @param node The node that defines the subtree.
-     * @return A vector of pointers toward each inner node in the subtree.
-     */
-    template<class N>
-    static std::vector<N*> getInnerNodes(N& node)
+  /**
+   * @brief Retrieve all branches ids from a subtree.
+   *
+   * @param node The node that defines the subtree.
+   * @param ids A vector of ids.
+   */
+  static void getBranchesId(const Node& node, std::vector<int>& ids)
+  {
+    for (size_t i = 0; i < node.getNumberOfSons(); i++)
     {
-      std::vector<N *> nodes;
-      getInnerNodes<N>(node, nodes);
-      return nodes;
+      getNodesId(*node.getSon(i), ids);
     }
+  }
 
-    /**
-     * @brief Retrieve all inner nodes from a subtree.
-     *
-     * A inner node is a node with degree > 1, that is, all nodes but the leaves, be they terminal or not.
-     *
-     * @param node The node that defines the subtree.
-     * @param nodes A vector to be filled with pointers toward each inner node in the subtree.
-     */
-    template<class N>
-    static void getInnerNodes(N& node, std::vector<N*>& nodes)
-    {
-      for(size_t i = 0; i < node.getNumberOfSons(); i++)
-      {
-        getInnerNodes<N>(* node.getSon(i), nodes);
-      }
-      if (!node.isLeaf()) 
-        nodes.push_back(&node); //Do not add leaves!
-    }
+  /**
+   * @brief Retrieve all inner nodes from a subtree.
+   *
+   * @param node The node that defines the subtree.
+   * @return A vector of pointers toward each inner node in the subtree.
+   */
+  template<class N>
+  static std::vector<N*> getInnerNodes(N& node)
+  {
+    std::vector<N*> nodes;
+    getInnerNodes<N>(node, nodes);
+    return nodes;
+  }
 
-    /**
-     * @brief Retrieve all inner nodes ids from a subtree.
-     *
-     * A inner node is a node with degree > 1, that is, all nodes but the leaves, be they terminal or not.
-     *
-     * @param node The node that defines the subtree.
-     * @return A vector of ids.
-     */
-    static std::vector<int> getInnerNodesId(const Node& node)
+  /**
+   * @brief Retrieve all inner nodes from a subtree.
+   *
+   * A inner node is a node with degree > 1, that is, all nodes but the leaves, be they terminal or not.
+   *
+   * @param node The node that defines the subtree.
+   * @param nodes A vector to be filled with pointers toward each inner node in the subtree.
+   */
+  template<class N>
+  static void getInnerNodes(N& node, std::vector<N*>& nodes)
+  {
+    for (size_t i = 0; i < node.getNumberOfSons(); i++)
     {
-      std::vector<int> ids;
-      getInnerNodesId(node, ids);
-      return ids;
+      getInnerNodes<N>(*node.getSon(i), nodes);
     }
+    if (!node.isLeaf())
+      nodes.push_back(&node);  // Do not add leaves!
+  }
 
-    /**
-     * @brief Retrieve all inner nodes ids from a subtree.
-     *
-     * @param node The node that defines the subtree.
-     * @param ids  A vector to be filled with the resulting ids.
-     */
-    static void getInnerNodesId(const Node& node, std::vector<int> & ids)
+  /**
+   * @brief Retrieve all inner nodes ids from a subtree.
+   *
+   * A inner node is a node with degree > 1, that is, all nodes but the leaves, be they terminal or not.
+   *
+   * @param node The node that defines the subtree.
+   * @return A vector of ids.
+   */
+  static std::vector<int> getInnerNodesId(const Node& node)
+  {
+    std::vector<int> ids;
+    getInnerNodesId(node, ids);
+    return ids;
+  }
+
+  /**
+   * @brief Retrieve all inner nodes ids from a subtree.
+   *
+   * @param node The node that defines the subtree.
+   * @param ids  A vector to be filled with the resulting ids.
+   */
+  static void getInnerNodesId(const Node& node, std::vector<int>& ids)
+  {
+    for (size_t i = 0; i < node.getNumberOfSons(); i++)
     {
-      for (size_t i = 0; i < node.getNumberOfSons(); i++)
-      {
-        getInnerNodesId(* node.getSon(i), ids);
-      }
-      if (!node.isLeaf())
-        ids.push_back(node.getId()); //Do not add leaves!
+      getInnerNodesId(*node.getSon(i), ids);
     }
+    if (!node.isLeaf())
+      ids.push_back(node.getId());  // Do not add leaves!
+  }
+
+  /**
+   * @param node The node defining the subtree to be searched.
+   * @param id   The id to search for.
+   * @return     Nodes with the specified id.
+   */
+  template<class N>
+  static std::vector<N*> searchNodeWithId(N& node, int id)
+  {
+    std::vector<N*> nodes;
+    searchNodeWithId<N>(node, id, nodes);
+    return nodes;
+  }
 
-    /**
-     * @param node The node defining the subtree to be searched.
-     * @param id   The id to search for.
-     * @return     Nodes with the specified id.
-     */
-    template<class N>
-    static std::vector<N*> searchNodeWithId(N& node, int id)
+  /**
+   * @param node  The node defining the subtree to be searched.
+   * @param id    The id to search for.
+   * @param nodes A vector to be filled with the matching nodes.
+   */
+  template<class N>
+  static void searchNodeWithId(N& node, int id, std::vector<N*>& nodes)
+  {
+    for (size_t i = 0; i < node.getNumberOfSons(); ++i)
     {
-      std::vector<N*> nodes;
-      searchNodeWithId<N>(node, id, nodes);
-      return nodes;    
+      searchNodeWithId<N>(*node.getSon(i), id, nodes);
     }
+    if (node.getId() == id) nodes.push_back(&node);
+  }
 
-    /**
-     * @param node  The node defining the subtree to be searched.
-     * @param id    The id to search for.
-     * @param nodes A vector to be filled with the matching nodes.
-     */
-    template<class N>
-    static void searchNodeWithId(N& node, int id, std::vector<N*>& nodes)
+  /**
+   * @param node  The node defining the subtree to be searched.
+   * @param id    The id to search for.
+   * @return The first node encountered with the given id, or 0 if no node with the given id is found.
+   */
+  static Node* searchFirstNodeWithId(Node& node, int id)
+  {
+    if (node.getId() == id)
+      return &node;
+    else
     {
       for (size_t i = 0; i < node.getNumberOfSons(); ++i)
       {
-        searchNodeWithId<N>(*node.getSon(i), id, nodes);
+        Node* result = searchFirstNodeWithId(*node.getSon(i), id);
+        if (result)
+          return result;
       }
-      if (node.getId() == id) nodes.push_back(&node);
-    }
-
-    /**
-     * @param node  The node defining the subtree to be searched.
-     * @param id    The id to search for.
-     * @return The first node encountered with the given id, or 0 if no node with the given id is found.
-     */
-    static Node* searchFirstNodeWithId(Node& node, int id)
-    {
-      if (node.getId() == id) 
-        return &node;
-      else {
-        for (size_t i = 0; i < node.getNumberOfSons(); ++i)
-        {
-          Node* result = searchFirstNodeWithId(*node.getSon(i), id);
-          if (result)
-            return result;
-        }
-      }
-      return 0;
     }
+    return 0;
+  }
 
-    /**
-     * @param node  The node defining the subtree to be searched.
-     * @param id    The id to search for.
-     * @return The first node encountered with the given id, or 0 if no node with the given id is found.
-     */
-    static const Node* searchFirstNodeWithId(const Node& node, int id)
+  /**
+   * @param node  The node defining the subtree to be searched.
+   * @param id    The id to search for.
+   * @return The first node encountered with the given id, or 0 if no node with the given id is found.
+   */
+  static const Node* searchFirstNodeWithId(const Node& node, int id)
+  {
+    if (node.getId() == id)
+      return &node;
+    else
     {
-      if (node.getId() == id) 
-        return &node;
-      else {
-        for (size_t i = 0; i < node.getNumberOfSons(); ++i)
-        {
-          const Node* result = searchFirstNodeWithId(*node.getSon(i), id);
-          if (result)
-            return result;
-        }
+      for (size_t i = 0; i < node.getNumberOfSons(); ++i)
+      {
+        const Node* result = searchFirstNodeWithId(*node.getSon(i), id);
+        if (result)
+          return result;
       }
-      return 0;
     }
+    return 0;
+  }
 
-    /**
-     * @param node The node defining the subtree to be searched.
-     * @param id   The id to search for.
-     * @return     True if the subtree contains a node with the specified id.
-     */
-    template<class N>
-    static bool hasNodeWithId(const N& node, int id)
+  /**
+   * @param node The node defining the subtree to be searched.
+   * @param id   The id to search for.
+   * @return     True if the subtree contains a node with the specified id.
+   */
+  template<class N>
+  static bool hasNodeWithId(const N& node, int id)
+  {
+    if (node.getId() == id) return true;
+    else
     {
-      if (node.getId() == id) return true;
-      else
+      for (size_t i = 0; i < node.getNumberOfSons(); i++)
       {
-        for(size_t i = 0; i < node.getNumberOfSons(); i++)
-        {
-          if(hasNodeWithId(*node.getSon(i), id)) return true;
-        }
-        return false;
+        if (hasNodeWithId(*node.getSon(i), id)) return true;
       }
+      return false;
     }
+  }
 
-    /**
-     * @param node The node defining the subtree to be searched.
-     * @param name The name to search for.
-     * @return     Nodes with the specified name.
-     */
-    template<class N>
-    static std::vector<N*> searchNodeWithName(N& node, const std::string& name)
-    {
-      std::vector<N*> nodes;
-      searchNodeWithId<N>(node, name, nodes);
-      return nodes;    
-    }
+  /**
+   * @param node The node defining the subtree to be searched.
+   * @param name The name to search for.
+   * @return     Nodes with the specified name.
+   */
+  template<class N>
+  static std::vector<N*> searchNodeWithName(N& node, const std::string& name)
+  {
+    std::vector<N*> nodes;
+    searchNodeWithId<N>(node, name, nodes);
+    return nodes;
+  }
 
-    /**
-     * @param node  The node defining the subtree to be searched.
-     * @param name  The name to search for.
-     * @param nodes A vector to be filled with the matching nodes.
-     */
-    template<class N>
-    static void searchNodeWithName(N& node, const std::string& name, std::vector<N*> & nodes)
+  /**
+   * @param node  The node defining the subtree to be searched.
+   * @param name  The name to search for.
+   * @param nodes A vector to be filled with the matching nodes.
+   */
+  template<class N>
+  static void searchNodeWithName(N& node, const std::string& name, std::vector<N*>& nodes)
+  {
+    for (size_t i = 0; i < node.getNumberOfSons(); i++)
     {
-      for(size_t i = 0; i < node.getNumberOfSons(); i++)
-      {
-        searchNodeWithName<N>(*node.getSon(i), name, nodes);
-      }
-      if(node.hasName() && node.getName() == name) nodes.push_back(&node);
+      searchNodeWithName<N>(*node.getSon(i), name, nodes);
     }
+    if (node.hasName() && node.getName() == name) nodes.push_back(&node);
+  }
 
-    /**
-     * @param node The node defining the subtree to be searched.
-     * @param name The name to search for.
-     * @return     True if the subtree contains a node with the specified name.
-     */
-    template<class N>
-    static bool hasNodeWithName(const N& node, const std::string& name)
+  /**
+   * @param node The node defining the subtree to be searched.
+   * @param name The name to search for.
+   * @return     True if the subtree contains a node with the specified name.
+   */
+  template<class N>
+  static bool hasNodeWithName(const N& node, const std::string& name)
+  {
+    if (node.hasName() & node.getName() == name) return true;
+    else
     {
-      if(node.hasName() & node.getName() == name) return true;
-      else
+      for (size_t i = 0; i < node.getNumberOfSons(); i++)
       {
-        for(size_t i = 0; i < node.getNumberOfSons(); i++)
-        {
-          if(hasNodeWithName(*node.getSon(i), name)) return true;
-        }
-        return false;
+        if (hasNodeWithName(*node.getSon(i), name)) return true;
       }
+      return false;
     }
+  }
 
-    /**
-     * @brief Tell if a particular node is the root of a tree
-     * i.e. if it has a father node.
-     *
-     * @param node The node to check.
-     * @return True if node does not have a father.
-     */
-    static bool isRoot(const Node& node) { return !node.hasFather(); }
-
-    /**
-     * @brief Get the number of leaves of a subtree defined by a particular node.
-     *
-     * @param node The node defining the subtree to check.
-     * @return The number of leaves.
-     */
-    static unsigned int getNumberOfLeaves(const Node& node);
-
-    /**
-     * @brief Get the number of nodes of a subtree defined by a particular node.
-     *
-     * @param node The node defining the subtree to check.
-     * @return The number of nodes.
-     */
-    static unsigned int getNumberOfNodes(const Node& node);
-
-    /**
-     * @brief Get the leaves names of a subtree defined by a particular node.
-     *
-     * @param node The node defining the subtree to check.
-     * @return The list of all leaves names.
-     */
-    static std::vector<std::string> getLeavesNames(const Node& node);
-
-    /**
-     * @brief Get the depth of the subtree defined by node 'node', i.e. the maximum
-     * number of sons 'generations'.
-     *
-     * ex:
-     * @verbatim
-     *    +----------A
-     *    |
-     * ---+ N1     +-------B
-     *    |        |
-     *    +--------+ N2
-     *             |
-     *             +------C
-     * @endverbatim
-     * Depth of node 'N1' id 2, depth of node 'N2' is 1, depth of leaves is 0.
-     *
-     * @param node The node defining the subtree to check.
-     * @return The depth of the subtree.
-     */
-    static unsigned int getDepth(const Node& node);
-
-    /**
-     * @brief Get the depths for all nodes of the subtree defined by node 'node', i.e. the maximum
-     * number of sons 'generations'.
-     *
-     * ex:
-     * @verbatim
-     *    +----------A
-     *    |
-     * ---+ N1     +-------B
-     *    |        |
-     *    +--------+ N2
-     *             |
-     *             +------C
-     * @endverbatim
-     * Depth of node 'N1' id 2, depth of node 'N2' is 1, depth of leaves is 0.
-     *
-     * @param node The node defining the subtree to check.
-     * @param depths The map that will contain all the depths of the nodes, with node pointers as keys.
-     * @return The depth of the subtree.
-     */
-    static unsigned int getDepths(const Node& node, std::map<const Node*, unsigned int>& depths);
-
-    /**
-     * @brief Get the height of the subtree defined by node 'node', i.e. the maximum
-     * distance between leaves and the root of the subtree.
-     *
-     * The distance do not include the branch length of the subtree root node.
-     * The height of a leaf is hence 0.
-     *
-     * @param node The node defining the subtree to check.
-     * @return The height of the subtree.
-     * @throw NodePException If a branch length is lacking.
-     */ 
-    static double getHeight(const Node& node);
-
-    /**
-     * @brief Get the heights of all nodes within a subtree defined by node 'node', i.e. the maximum
-     * distance between leaves and the root of the subtree.
-     *
-     * The height of a leaf is 0.
-     *
-     * @param node The node defining the subtree to check.
-     * @param heights The map that will contain all the heights of the nodes, with node pointers as keys.
-     * @return The height of the subtree.
-     * @throw NodePException If a branch length is lacking.
-     */ 
-    static double getHeights(const Node& node, std::map<const Node*, double>& heights);
-
-    /**
-     * @brief Tell is a subtree is multifurcating.
-     *
-     * @param node The root node of the subtree.
-     * @return True is the subtree contains at least one multifurcating
-     * node (including the root node).
-     */
-    static bool isMultifurcating(const Node& node);
-
-    /**
-     * @brief Tells if two subtrees have the same topology.
-     *
-     * The comparison is based on parental relationships and leaf names only, node ids and all branch/node properties are ignored.
-     * The ordering of son nodes is taken into account so that ((A,B),C) will be considered different from ((B,A),C). Considerer
-     * ordering the trees first if you want to perform a strict topological comparison.
-     *
-     * @param n1 Root node of the first subtree.
-     * @param n2 Root node of the second subtree.
-     * @return true if the two subtrees have the same topology.
-     */
-    static bool haveSameOrderedTopology(const Node& n1, const Node& n2);
-
-    static std::vector<Node*> getPathBetweenAnyTwoNodes(Node& node1, Node& node2, bool includeAncestor = true);
-    
-    static std::vector<const Node*> getPathBetweenAnyTwoNodes(const Node & node1, const Node & node2, bool includeAncestor = true);
-    
-    /**
-     * @brief Recursively clone a subtree structure.
-     *
-     * This is a template function allowing to specify the class of the copy.
-     * The template class has to have a constructor accepting const Node& as single argument.
-     *
-     * @param node The basal node of the subtree.
-     * @return The basal node of the new copy.
-     */
-    template<class N>
-    static N* cloneSubtree(const Node& node) 
-    {
-      //First we copy this node using default copy constuctor:
-      N* clone = new N(node);
-      //We remove the link toward the father:
-      //clone->removeFather();
+  /**
+   * @brief Tell if a particular node is the root of a tree
+   * i.e. if it has a father node.
+   *
+   * @param node The node to check.
+   * @return True if node does not have a father.
+   */
+  static bool isRoot(const Node& node) { return !node.hasFather(); }
 
-      //Now we perform a hard copy:
-      for (int i = 0; i < static_cast<int>(node.getNumberOfSons()); i++)
-      {
-        clone->addSon(cloneSubtree<N>(*node[i]));
-      }
-      return clone;
+  /**
+   * @brief Get the number of leaves of a subtree defined by a particular node.
+   *
+   * @param node The node defining the subtree to check.
+   * @return The number of leaves.
+   */
+  static unsigned int getNumberOfLeaves(const Node& node);
+
+  /**
+   * @brief Get the number of nodes of a subtree defined by a particular node.
+   *
+   * @param node The node defining the subtree to check.
+   * @return The number of nodes.
+   */
+  static unsigned int getNumberOfNodes(const Node& node);
+
+  /**
+   * @brief Get the leaves names of a subtree defined by a particular node.
+   *
+   * @param node The node defining the subtree to check.
+   * @return The list of all leaves names.
+   */
+  static std::vector<std::string> getLeavesNames(const Node& node);
+
+  /**
+   * @brief Get the depth of the subtree defined by node 'node', i.e. the maximum
+   * number of sons 'generations'.
+   *
+   * ex:
+   * @verbatim
+   *    +----------A
+   *    |
+   * ---+ N1     +-------B
+   *    |        |
+   *    +--------+ N2
+   *             |
+   *             +------C
+   * @endverbatim
+   * Depth of node 'N1' id 2, depth of node 'N2' is 1, depth of leaves is 0.
+   *
+   * @param node The node defining the subtree to check.
+   * @return The depth of the subtree.
+   */
+  static unsigned int getDepth(const Node& node);
+
+  /**
+   * @brief Get the depths for all nodes of the subtree defined by node 'node', i.e. the maximum
+   * number of sons 'generations'.
+   *
+   * ex:
+   * @verbatim
+   *    +----------A
+   *    |
+   * ---+ N1     +-------B
+   *    |        |
+   *    +--------+ N2
+   *             |
+   *             +------C
+   * @endverbatim
+   * Depth of node 'N1' id 2, depth of node 'N2' is 1, depth of leaves is 0.
+   *
+   * @param node The node defining the subtree to check.
+   * @param depths The map that will contain all the depths of the nodes, with node pointers as keys.
+   * @return The depth of the subtree.
+   */
+  static unsigned int getDepths(const Node& node, std::map<const Node*, unsigned int>& depths);
+
+  /**
+   * @brief Get the height of the subtree defined by node 'node', i.e. the maximum
+   * distance between leaves and the root of the subtree.
+   *
+   * The distance do not include the branch length of the subtree root node.
+   * The height of a leaf is hence 0.
+   *
+   * @param node The node defining the subtree to check.
+   * @return The height of the subtree.
+   * @throw NodePException If a branch length is lacking.
+   */
+  static double getHeight(const Node& node);
+
+  /**
+   * @brief Get the heights of all nodes within a subtree defined by node 'node', i.e. the maximum
+   * distance between leaves and the root of the subtree.
+   *
+   * The height of a leaf is 0.
+   *
+   * @param node The node defining the subtree to check.
+   * @param heights The map that will contain all the heights of the nodes, with node pointers as keys.
+   * @return The height of the subtree.
+   * @throw NodePException If a branch length is lacking.
+   */
+  static double getHeights(const Node& node, std::map<const Node*, double>& heights);
+
+  /**
+   * @brief Tell is a subtree is multifurcating.
+   *
+   * @param node The root node of the subtree.
+   * @return True is the subtree contains at least one multifurcating
+   * node (including the root node).
+   */
+  static bool isMultifurcating(const Node& node);
+
+  /**
+   * @brief Tells if two subtrees have the same topology.
+   *
+   * The comparison is based on parental relationships and leaf names only, node ids and all branch/node properties are ignored.
+   * The ordering of son nodes is taken into account so that ((A,B),C) will be considered different from ((B,A),C). Considerer
+   * ordering the trees first if you want to perform a strict topological comparison.
+   *
+   * @param n1 Root node of the first subtree.
+   * @param n2 Root node of the second subtree.
+   * @return true if the two subtrees have the same topology.
+   */
+  static bool haveSameOrderedTopology(const Node& n1, const Node& n2);
+
+  static std::vector<Node*> getPathBetweenAnyTwoNodes(Node& node1, Node& node2, bool includeAncestor = true);
+
+  static std::vector<const Node*> getPathBetweenAnyTwoNodes(const Node& node1, const Node& node2, bool includeAncestor = true);
+
+  /**
+   * @brief Recursively clone a subtree structure.
+   *
+   * This is a template function allowing to specify the class of the copy.
+   * The template class has to have a constructor accepting const Node& as single argument.
+   *
+   * @param node The basal node of the subtree.
+   * @return The basal node of the new copy.
+   */
+  template<class N>
+  static N* cloneSubtree(const Node& node)
+  {
+    // First we copy this node using default copy constuctor:
+    N* clone = new N(node);
+    // We remove the link toward the father:
+    // clone->removeFather();
+
+    // Now we perform a hard copy:
+    for (int i = 0; i < static_cast<int>(node.getNumberOfSons()); i++)
+    {
+      clone->addSon(cloneSubtree<N>(*node[i]));
     }
+    return clone;
+  }
 
-    /**
-     * @brief Recursively delete a subtree structure.
-     *
-     * @param node The basal node of the subtree.
-     */
-    template<class N>
-    static void deleteSubtree(N* node)
+  /**
+   * @brief Recursively delete a subtree structure.
+   *
+   * @param node The basal node of the subtree.
+   */
+  template<class N>
+  static void deleteSubtree(N* node)
+  {
+    for (size_t i = 0; i < node->getNumberOfSons(); ++i)
     {
-      for (size_t i = 0; i < node->getNumberOfSons(); ++i)
-      {
-        N* son = node->getSon(i);
-        deleteSubtree(son);
-        delete son;
-      }
+      N* son = node->getSon(i);
+      deleteSubtree(son);
+      delete son;
     }
+  }
+
 
-    
-    template<class N>
-    static N* cloneSubtree(const Tree& tree, int nodeId) 
+  template<class N>
+  static N* cloneSubtree(const Tree& tree, int nodeId)
+  {
+    // First we copy this node using default copy constuctor:
+    N* clone = tree.hasNodeName(nodeId) ? new N(nodeId, tree.getNodeName(nodeId)) : new N(nodeId);
+    // Then we set the length:
+    if (tree.hasDistanceToFather(nodeId))
+      clone->setDistanceToFather(tree.getDistanceToFather(nodeId));
+    // Now we copy all sons:
+    std::vector<int> sonsId = tree.getSonsId(nodeId);
+    for (size_t i = 0; i < sonsId.size(); i++)
     {
-      //First we copy this node using default copy constuctor:
-      N* clone = tree.hasNodeName(nodeId) ? new N(nodeId, tree.getNodeName(nodeId)) : new N(nodeId);
-      //Then we set the length:
-      if (tree.hasDistanceToFather(nodeId))
-        clone->setDistanceToFather(tree.getDistanceToFather(nodeId));
-      //Now we copy all sons:
-      std::vector<int> sonsId = tree.getSonsId(nodeId);
-      for (size_t i = 0; i < sonsId.size(); i++)
-      {
-        clone->addSon(cloneSubtree<N>(tree, sonsId[i]));
-      }
-      //Must copy all properties too:
-      std::vector<std::string> names;
-      names = tree.getNodePropertyNames(nodeId);
-      for (size_t i = 0; i < names.size(); i++)
-      {
-        clone->setNodeProperty(names[i], *tree.getNodeProperty(nodeId, names[i]));
-      }
-      names = tree.getBranchPropertyNames(nodeId);
-      for (size_t i = 0; i < names.size(); i++)
-      {
-        clone->setBranchProperty(names[i], *tree.getBranchProperty(nodeId, names[i]));
-      }
-      
-      return clone;
+      clone->addSon(cloneSubtree<N>(tree, sonsId[i]));
     }
-    /** @} */
- 
-    /**
-     * @name Act on branch lengths.
-     *
-     * @{
-     */
-    
-    /**
-     * @brief Get all the branch lengths of a subtree.
-     *
-     * @param node The root node of the subtree.
-     * @return A vector with all branch lengths.
-     * @throw NodePException If a branch length is lacking.
-     */
-    static Vdouble getBranchLengths(const Node& node) throw (NodePException);
-
-    /**
-     * @brief Get the total length (sum of all branch lengths) of a subtree.
-     *
-     * @param node The root node of the subtree.
-     * @param includeAncestor Tell if the branch length of the most ancient node should be included in the counting.
-     * (this should be set to false if this node is the root of the tree for instance).
-      * @return The total length of the subtree.
-     * @throw NodePException If a branch length is lacking.
-     */
-    static double getTotalLength(const Node& node, bool includeAncestor = true) throw (NodePException);
-    
-    /**
-     * @brief Set all the branch lengths of a subtree.
-     *
-     * @param node  The root node of the subtree.
-     * @param brLen The branch length to apply.
-     */
-    static void setBranchLengths(Node& node, double brLen);
-     
-    /**
-     * @brief Remove all the branch lengths of a subtree.
-     *
-     * @param node  The root node of the subtree.
-     */
-    static void deleteBranchLengths(Node& node);
-
-    /**
-     * @brief Give a length to branches that don't have one in a subtree.
-     *
-     * @param node  The root node of the subtree.
-     * @param brLen The branch length to apply.
-     */
-    static void setVoidBranchLengths(Node& node, double brLen);
-        
-    /**
-     * @brief Scale a given tree.
-     *
-     * Multiply all branch lengths by a given factor.
-     *
-     * @param node   The root node of the subtree to scale.
-     * @param factor The factor to multiply all branch lengths with.
-     * @throw NodePException If a branch length is lacking.
-     */
-    static void scaleTree(Node& node, double factor) throw (NodePException);
-   
-    /**
-     * @brief Get the total distance between to nodes.
-     *
-     * Sum all branch lengths between two nodes.
-     *
-     * @param node1 The first node.
-     * @param node2 The second node.
-     * @return The sum of all branch lengths between the two nodes.
-     */
-    static double getDistanceBetweenAnyTwoNodes(const Node& node1, const Node& node2);
-
-    /**
-     * @brief Compute a distance matrix from a tree.
-     *
-     * Compute all distances between each leaves and store them in a matrix.
-     * A new DistanceMatrix object is created, and a pointer toward it is returned.
-     * The destruction of this matrix is left up to the user.
-     *
-     * From version 1.9 of Bio++, this function has been rewritten in a more efficient way
-     * and does not use getDistanceBetweenAnyTwoNodes anymore, but makes use of a more clever
-     * pass on the tree. The new function now works well on trees with thousands of leaves.
-     *
-     * @see getDistanceBetweenAnyTwoNodes
-     *
-     * @author Nicolas Rochette
-     *
-     * @param tree The tree to use.
-     * @return The distance matrix computed from tree.
-     */
-    static DistanceMatrix* getDistanceMatrix(const TreeTemplate<Node>& tree);
-
-  private:
-    /**
-     * @brief Inner function used by getDistanceMatrix.
-     *
-     * (1) Retrieves leaf-leaf distances in node's subtree and
-     *  writes them in the distance matrix.
-     * (2) Returns distances from node's father to those leaves.
-     *
-     * @param node The current node in the recursion.
-     * @param matrix The output matrix which will be filled.
-     * @param distsToNodeFather Intermediate computations contianing the distances of the node to the leaves.
-     */
-    static void processDistsInSubtree_(const Node* node, DistanceMatrix& matrix, std::vector< std::pair<std::string, double> >& distsToNodeFather);
-
-  public:
-    /** @} */
-
-    /**
-     * @name Conversion tools.
-     *
-     * Convert from Newick standard tree description.
-     * The description is for a node, and hence is to be surrounded with
-     * parenthesis. ex: (A:0.001, (B:0.001, C:0.02)90:0.005)50:0.0005
-     *
-     * @{
-     */
-
-    struct Element
+    // Must copy all properties too:
+    std::vector<std::string> names;
+    names = tree.getNodePropertyNames(nodeId);
+    for (size_t i = 0; i < names.size(); i++)
     {
-      public:
-        std::string content;
-        std::string length;
-        std::string bootstrap;
-        bool isLeaf;
-
-      public:
-        Element() : content(), length(), bootstrap(), isLeaf(false) {}
-    };
-
-    static Element getElement(const std::string& elt) throw (IOException);
-
-    /**
-     * @brief Parse a string in the parenthesis format and convert it to
-     * a subtree.
-     *
-     * @param description the string to parse;
-     * @param bootstrap Tell is real bootstrap values are expected. If so, a property with name TreeTools::BOOTSTRAP will be created and stored at the corresponding node.
-     * The property value will be of type Number<double>. Otherwise, an object of type String will be created and stored with the property name propertyName.
-     * @param propertyName The name of the property to store. Only used if bootstrap = false.
-     * @param withId Tells if node ids have been stored in the tree. If set at "true", no bootstrap or property values can be read. Node ids are positioned as bootstrap values for internal nodes, and are concatenated to leaf names after a "_" sign.
-     * @return A pointer toward a dynamically created subtree.
-     */
-    static Node* parenthesisToNode(const std::string& description, bool bootstrap=true, const std::string& propertyName=TreeTools::BOOTSTRAP, bool withId=false);
-  
-    /**
-     * @brief Parse a string in the parenthesis format and convert it to
-     * a tree.
-     *
-     * @param description the string to parse;
-     * @param bootstrap Tells if real bootstrap values are expected. If so, a property with name TreeTools::BOOTSTRAP will be created and stored at the corresponding node.
-     * The property value will be of type Number<double>. Otherwise, an object of type String will be created and stored with the property name propertyName.
-     * @param propertyName The name of the property to store. Only used if bootstrap = false.
-     * @param withId Tells if node ids have been stored in the tree. If set at "true", no bootstrap or property values can be read. Node ids are positioned as bootstrap values for internal nodes, and are concatenated to leaf names after a "_" sign.
-     * @return A pointer toward a dynamically created tree.
-     * @throw Exception in case of bad format.
-     */
-    static TreeTemplate<Node>* parenthesisToTree(const std::string& description, bool bootstrap = true, const std::string& propertyName = TreeTools::BOOTSTRAP, bool withId = false) throw (Exception);
-    
-    /**
-     * @brief Get the parenthesis description of a subtree.
-     *
-     * @param node The node defining the subtree.
-     * @param writeId Tells if node ids must be printed.
-     *                This will overwrite bootstrap values if there are ones.
-     *                Leaves id will be added to the leave names, separated by a '_' character.
-     * @return A string in the parenthesis format.
-     */
-    static std::string nodeToParenthesis(const Node & node, bool writeId = false);
-
-    /**
-     * @brief Get the parenthesis description of a subtree.
-     *
-     * @param node The node defining the subtree.
-     * @param bootstrap Tell is bootstrap values must be writen.
-     * If so, the content of the property with name TreeTools::BOOTSTRAP will be written as bootstrap value.
-     * The property should be a Number<double> object.
-     * Otherwise, the content of the property with name 'propertyName' will be written.
-     * In this later case, the property should be a String object.
-     * @param propertyName The name of the property to use. Only used if bootstrap = false.
-     * @return A string in the parenthesis format.
-     */
-    static std::string nodeToParenthesis(const Node & node, bool bootstrap, const std::string & propertyName);
-
-    /**
-     * @brief Get the parenthesis description of a tree.
-     *
-     * @param tree The tree to convert.
-     * @param writeId Tells if node ids must be printed.
-     *                This will overwrite bootstrap values if there are ones.
-     *                Leaves id will be added to the leave names, separated by a '_' character.
-     * @return A string in the parenthesis format.
-     */
-    static std::string treeToParenthesis(const TreeTemplate<Node>& tree, bool writeId = false);
-    
-    /**
-     * @brief Get the parenthesis description of a tree.
-     *
-     * @param tree The tree to convert.
-     * @param bootstrap Tell is bootstrap values must be writen.
-     * If so, the content of the property with name TreeTools::BOOTSTRAP will be written as bootstrap value.
-     * The property should be a Number<double> object.
-     * Otherwise, the content of the property with name 'propertyName' will be written.
-     * In this later case, the property should be a String object.
-     * @param propertyName The name of the property to use. Only used if bootstrap = false.
-     * @return A string in the parenthesis format.
-     */
-    static std::string treeToParenthesis(const TreeTemplate<Node> & tree, bool bootstrap, const std::string& propertyName);
-  
-    /** @} */
-
-    /**
-     * @name Random trees
-     *
-     * @{
-     */
-
-    /**
-     * @brief Draw a random tree from a list of taxa, using a Yule process.
-     *
-     * @param leavesNames A list of taxa.
-     * @param rooted Tell is the output tree should be rooted.
-     * @return A random tree with all corresponding taxa.
-     */
-    static TreeTemplate<Node>* getRandomTree(std::vector<std::string>& leavesNames, bool rooted=true);
-
-    /** @} */
-    
-    /**
-     * @brief Get a subset of node neighbors.
-     *
-     * Get all neighbors of node node1 that are neither node1 nor node2.
-     * This method is useful for topology manipulations, like NNI.
-     *
-     * @param node1 The node whose neighbors must be retrieved.
-     * @param node2 One neighbor to exclude.
-     * @param node3 Another neighbor to exclude.
-     * @return A vector of neighbors.
-     */
-    static std::vector<const Node*> getRemainingNeighbors(const Node* node1, const Node* node2, const Node* node3);
-
-    /**
-     * @brief This method will add a given value (possibly negative) to all identifiers in a (sub)tree.
-     *
-     * @param node The root node of the (sub)tree to use.
-     * @param increment The value to add.
-     */
-    static void incrementAllIds(Node* node, int increment);
-
-    /**
-     * @name Retrieve properties from a (sub)tree.
-     *
-     * @{
-     */
-
-    /**
-     * @brief Retrieve the names of all available node properties in the tree.
-     *
-     * @param node [in] The root node of the (sub)tree to use.
-     * @param propertyNames [out] a vector where names will be added.
-     */
-    static void getNodePropertyNames(const Node& node, std::vector<std::string>& propertyNames);
-
-    /**
-     * @brief Retrieve all node property objects with a given name over a (sub) tree (const version).
-     *
-     * @param node [in] The root node of the (sub)tree to use.
-     * @param propertyName [in] The name of the property to retrieve.
-     * @param properties [out] A map with pointers toward the properties as values, and node ids as key.
-     * If a node does not contain the given property, then no entry in the map is created.
-     * If an entry already exists in the map, it will be replaced, but the underlying property will not be destroyed.
-     * Property objects are not cloned when added to the map, but passed as pointers.
-     */
-    static void getNodeProperties(const Node& node, const std::string& propertyName, std::map<int, const Clonable*>& properties);
-    
-    /**
-     * @brief Retrieve all node property objects with a given name over a (sub) tree.
-     *
-     * @param node [in] The root node of the (sub)tree to use.
-     * @param propertyName [in] The name of the property to retrieve.
-     * @param properties [out] A map with pointers toward the properties as values, and node ids as key.
-     * If a node does not contain the given property, then no entry in the map is created.
-     * If an entry already exists in the map, it will be replaced, but the underlying property will not be destroyed.
-     * Property objects are not cloned when added to the map, but passed as pointers.
-     */
-    static void getNodeProperties(Node& node, const std::string& propertyName, std::map<int, Clonable*>& properties);
-
-    /**
-     * @brief Retrieve the names of all available branch properties in the tree.
-     *
-     * @param node [in] The root node of the (sub)tree to use.
-     * @param propertyNames [out] a vector where names will be added.
-     */
-    static void getBranchPropertyNames(const Node& node, std::vector<std::string>& propertyNames);
-
-    /**
-     * @brief Retrieve all branch property objects with a given name over a (sub) tree (const version).
-     *
-     * @param node [in] The root node of the (sub)tree to use.
-     * @param propertyName [in] The name of the property to retrieve.
-     * @param properties [out] A map with pointers toward the properties as values, and node ids as key.
-     * If a node does not contain the given property, then no entry in the map is created.
-     * If an entry already exists in the map, it will be replaced, but the underlying property will not be destroyed.
-     * Property objects are not cloned when added to the map, but passed as pointers.
-     */
-    static void getBranchProperties(const Node& node, const std::string& propertyName, std::map<int, const Clonable*>& properties);
-    
-    /**
-     * @brief Retrieve all branch property objects with a given name over a (sub) tree.
-     *
-     * @param node [in] The root node of the (sub)tree to use.
-     * @param propertyName [in] The name of the property to retrieve.
-     * @param properties [out] A map with pointers toward the properties as values, and node ids as key.
-     * If a node does not contain the given property, then no entry in the map is created.
-     * If an entry already exists in the map, it will be replaced, but the underlying property will not be destroyed.
-     * Property objects are not cloned when added to the map, but passed as pointers.
-     */
-    static void getBranchProperties(Node& node, const std::string& propertyName, std::map<int, Clonable*>& properties);
-
-    /**
-     * @brief Swap nodes in the subtree so that they are ordered according to the underlying number of leaves.
-     *
-     * @param node The root node of the (sub)tree to use.
-     * @param downward If yes, biggest subtrees (in terms of number of leaves) will come first. Otherwise, the smallest subtrees will come first.
-     * @param orderLeaves Tell if leaves have to be ordered alphabetically. This ensures that two identical topology will always have the same ordered tree, whatever the initial ordering of nodes.
-     */
-    static void orderTree(Node& node, bool downward = true, bool orderLeaves = false) {
-      orderTree_(node, downward, orderLeaves);
+      clone->setNodeProperty(names[i], *tree.getNodeProperty(nodeId, names[i]));
     }
-    /** @} */
-
-    /**
-     * @brief Midroot the tree by minimizing a given criterion ("variance" or "sum of squares")
-     *
-     * @details
-     * For each branch, the best root position, according to the given criterion, is computed analytically.
-     *
-     * For the 'variance' criterion :
-     * \f[
-     *  (n_1+n_2)^2 V(x)
-     *   = (n_1+n_2) \left[ \sum_{F_1} (d_i + x \delta )^2 + \sum_{F_2} (d_i + (1-x) \delta )^2 \right]
-     *     - \left[ \sum_{F_1} (d_i + x \delta) + \sum_{F_2} (d_i + (1-x) \delta) \right]^2
-     *   = A x^2 + B x + C
-     * \f]
-     * With
-     * \f[ \begin{array}{rcl}
-     * A &=& 4 n_1 n_2 \delta^2 \\
-     * B &=& 4 \delta ( n_2 S_1 - n_1 S_2 - n_1 n_2 \delta ) \\
-     * C &=& (n_1+n_2) (C_1+C_2) + n_1 n_2 \delta^2 + 2 n_1 S_2 \delta - 2 n_2 S_1 \delta - (S_1+S_2)^2 \\
-     * \end{array} \f]
-     *
-     * Where \f$F_1\f$ and \f$F_2\f$ are the sets of leaves on either side of
-     * the root branch,
-     * \f$d_i\f$ is the distance of leaf \f$i\f$ to the nearest end of the root branch,
-     * \f$\delta\f$ is the length of the root branch, and \f$S_k\f$ and \f$C_k\f$ are respectively
-     * \f$\sum_{F_k} d_i\f$ and \f$\sum_{F_k} d_i^2\f$
-     *
-     * ~
-     *
-     * @param tree
-     * @param criterion The criterion upon which to reroot. Legal values : "variance"
-     *   to minimize root-leaf distance variance (molecular clock assumption) or
-     *   "sum of squares" to minimize the sum of root-leaf distance squares.
-     *
-     * @author Nicolas Rochette
-     */
-    static void midRoot (bpp::TreeTemplate<bpp::Node>& tree, const std::string& criterion);
-
-    /**
-     * @brief Get the caracteristic radius of a tree (average distance to the root minimizing the sum of squared distances).
-     *
-     * @param tree The tree (which is rerooted in the process).
-     */
-    static double getRadius (bpp::TreeTemplate<bpp::Node>& tree);
-
-  private:
-    struct OrderTreeData_ {
-      size_t size;
-      std::string firstLeaf;
-      OrderTreeData_(): size(0), firstLeaf("") {}
-    };
-
-    static OrderTreeData_ orderTree_(Node& node, bool downward, bool orderLeaves);
-
-    /**
-     * @brief
-     * A <i>structure</i> recording, for a subtree, the sum of root-leaf distances, the sum of their squares,
-     * and the number of elements in these sums (ie. the number of leaves).
-     *
-     * @details
-     * The branch at the base of the subtree should never be included,
-     * as the subtree of the root does not have one.
-     *
-     */
-    struct Moments_
+    names = tree.getBranchPropertyNames(nodeId);
+    for (size_t i = 0; i < names.size(); i++)
     {
-      double sum;
-      double squaresSum;
-      int numberOfLeaves;
-    };
-
-    /**
-     * @brief
-     * Computes the moment of a subtree
-     *
-     * @param node The root of the subtree
-     * @return A Moments_ structure
-     */
-    static Moments_ getSubtreeMoments (const Node* node);
-
-    /**
-     * @brief Find, in the branches of a subtree, the root that minimizes a criterion over the tree.
-     *
-     * @details
-     * The branches are explored recursively. For each branch leaving the input node, the method
-     * computes the best root position, possibly updates the bestRoot parameter, then recurses.
-     *
-     * @param tree The tree to which the subtree belongs. (The root is moved.)
-     * @param criterion The criterion to minimize. Legal values are "variance" and "sum of squares".
-     * @param node The root of the subtree.
-     * @param bestRoot The object storing the best root found, if it is better than the initial one, or otherwise left unchanged.
-     *
-     * @author Nicolas Rochette, Manolo Gouy
-     */
-    static void getBestRootInSubtree (bpp::TreeTemplate<bpp::Node>& tree, const std::string& criterion,  bpp::Node* node, std::pair<bpp::Node*, std::map<std::string, double> >& bestRoot);
+      clone->setBranchProperty(names[i], *tree.getBranchProperty(nodeId, names[i]));
+    }
 
-};
+    return clone;
+  }
+  /** @} */
+
+  /**
+   * @name Act on branch lengths.
+   *
+   * @{
+   */
+
+  /**
+   * @brief Get all the branch lengths of a subtree.
+   *
+   * @param node The root node of the subtree.
+   * @return A vector with all branch lengths.
+   * @throw NodePException If a branch length is lacking.
+   */
+  static Vdouble getBranchLengths(const Node& node) throw (NodePException);
+
+  /**
+   * @brief Get the total length (sum of all branch lengths) of a subtree.
+   *
+   * @param node The root node of the subtree.
+   * @param includeAncestor Tell if the branch length of the most ancient node should be included in the counting.
+   * (this should be set to false if this node is the root of the tree for instance).
+   * @return The total length of the subtree.
+   * @throw NodePException If a branch length is lacking.
+   */
+  static double getTotalLength(const Node& node, bool includeAncestor = true) throw (NodePException);
+
+  /**
+   * @brief Set all the branch lengths of a subtree.
+   *
+   * @param node  The root node of the subtree.
+   * @param brLen The branch length to apply.
+   */
+  static void setBranchLengths(Node& node, double brLen);
+
+  /**
+   * @brief Remove all the branch lengths of a subtree.
+   *
+   * @param node  The root node of the subtree.
+   */
+  static void deleteBranchLengths(Node& node);
+
+  /**
+   * @brief Give a length to branches that don't have one in a subtree.
+   *
+   * @param node  The root node of the subtree.
+   * @param brLen The branch length to apply.
+   */
+  static void setVoidBranchLengths(Node& node, double brLen);
+
+  /**
+   * @brief Scale a given tree.
+   *
+   * Multiply all branch lengths by a given factor.
+   *
+   * @param node   The root node of the subtree to scale.
+   * @param factor The factor to multiply all branch lengths with.
+   * @throw NodePException If a branch length is lacking.
+   */
+  static void scaleTree(Node& node, double factor) throw (NodePException);
+
+  /**
+   * @brief Get the total distance between to nodes.
+   *
+   * Sum all branch lengths between two nodes.
+   *
+   * @param node1 The first node.
+   * @param node2 The second node.
+   * @return The sum of all branch lengths between the two nodes.
+   */
+  static double getDistanceBetweenAnyTwoNodes(const Node& node1, const Node& node2);
+
+  /**
+   * @brief Compute a distance matrix from a tree.
+   *
+   * Compute all distances between each leaves and store them in a matrix.
+   * A new DistanceMatrix object is created, and a pointer toward it is returned.
+   * The destruction of this matrix is left up to the user.
+   *
+   * From version 1.9 of Bio++, this function has been rewritten in a more efficient way
+   * and does not use getDistanceBetweenAnyTwoNodes anymore, but makes use of a more clever
+   * pass on the tree. The new function now works well on trees with thousands of leaves.
+   *
+   * @see getDistanceBetweenAnyTwoNodes
+   *
+   * @author Nicolas Rochette
+   *
+   * @param tree The tree to use.
+   * @return The distance matrix computed from tree.
+   */
+  static DistanceMatrix* getDistanceMatrix(const TreeTemplate<Node>& tree);
+
+private:
+  /**
+   * @brief Inner function used by getDistanceMatrix.
+   *
+   * (1) Retrieves leaf-leaf distances in node's subtree and
+   *  writes them in the distance matrix.
+   * (2) Returns distances from node's father to those leaves.
+   *
+   * @param node The current node in the recursion.
+   * @param matrix The output matrix which will be filled.
+   * @param distsToNodeFather Intermediate computations contianing the distances of the node to the leaves.
+   */
+  static void processDistsInSubtree_(const Node* node, DistanceMatrix& matrix, std::vector< std::pair<std::string, double> >& distsToNodeFather);
+
+public:
+  /** @} */
+
+  /**
+   * @name Conversion tools.
+   *
+   * Convert from Newick standard tree description.
+   * The description is for a node, and hence is to be surrounded with
+   * parenthesis. ex: (A:0.001, (B:0.001, C:0.02)90:0.005)50:0.0005
+   *
+   * @{
+   */
 
-} //end of namespace bpp.
+  struct Element
+  {
+public:
+    std::string content;
+    std::string length;
+    std::string bootstrap;
+    bool isLeaf;
+
+public:
+    Element() : content(),
+      length(),
+      bootstrap(),
+      isLeaf(false) {}
+  };
+
+  static Element getElement(const std::string& elt) throw (IOException);
+
+  /**
+   * @brief Parse a string in the parenthesis format and convert it to
+   * a subtree.
+   *
+   * @param description the string to parse;
+   * @param bootstrap Tell is real bootstrap values are expected. If so, a property with name TreeTools::BOOTSTRAP will be created and stored at the corresponding node.
+   * The property value will be of type Number<double>. Otherwise, an object of type String will be created and stored with the property name propertyName.
+   * @param propertyName The name of the property to store. Only used if bootstrap = false.
+   * @param withId Tells if node ids have been stored in the tree. If set at "true", no bootstrap or property values can be read. Node ids are positioned as bootstrap values for internal nodes, and are concatenated to leaf names after a "_" sign.
+   * @return A pointer toward a dynamically created subtree.
+   */
+  static Node* parenthesisToNode(const std::string& description, bool bootstrap = true, const std::string& propertyName = TreeTools::BOOTSTRAP, bool withId = false);
+
+  /**
+   * @brief Parse a string in the parenthesis format and convert it to
+   * a tree.
+   *
+   * @param description the string to parse;
+   * @param bootstrap Tells if real bootstrap values are expected. If so, a property with name TreeTools::BOOTSTRAP will be created and stored at the corresponding node.
+   * The property value will be of type Number<double>. Otherwise, an object of type String will be created and stored with the property name propertyName.
+   * @param propertyName The name of the property to store. Only used if bootstrap = false.
+   * @param withId Tells if node ids have been stored in the tree. If set at "true", no bootstrap or property values can be read. Node ids are positioned as bootstrap values for internal nodes, and are concatenated to leaf names after a "_" sign.
+   * @return A pointer toward a dynamically created tree.
+   * @throw Exception in case of bad format.
+   */
+  static TreeTemplate<Node>* parenthesisToTree(const std::string& description, bool bootstrap = true, const std::string& propertyName = TreeTools::BOOTSTRAP, bool withId = false) throw (Exception);
+
+  /**
+   * @brief Get the parenthesis description of a subtree.
+   *
+   * @param node The node defining the subtree.
+   * @param writeId Tells if node ids must be printed.
+   *                This will overwrite bootstrap values if there are ones.
+   *                Leaves id will be added to the leave names, separated by a '_' character.
+   * @return A string in the parenthesis format.
+   */
+  static std::string nodeToParenthesis(const Node& node, bool writeId = false);
+
+  /**
+   * @brief Get the parenthesis description of a subtree.
+   *
+   * @param node The node defining the subtree.
+   * @param bootstrap Tell is bootstrap values must be writen.
+   * If so, the content of the property with name TreeTools::BOOTSTRAP will be written as bootstrap value.
+   * The property should be a Number<double> object.
+   * Otherwise, the content of the property with name 'propertyName' will be written.
+   * In this later case, the property should be a String object.
+   * @param propertyName The name of the property to use. Only used if bootstrap = false.
+   * @return A string in the parenthesis format.
+   */
+  static std::string nodeToParenthesis(const Node& node, bool bootstrap, const std::string& propertyName);
+
+  /**
+   * @brief Get the parenthesis description of a tree.
+   *
+   * @param tree The tree to convert.
+   * @param writeId Tells if node ids must be printed.
+   *                This will overwrite bootstrap values if there are ones.
+   *                Leaves id will be added to the leave names, separated by a '_' character.
+   * @return A string in the parenthesis format.
+   */
+  static std::string treeToParenthesis(const TreeTemplate<Node>& tree, bool writeId = false);
+
+  /**
+   * @brief Get the parenthesis description of a tree.
+   *
+   * @param tree The tree to convert.
+   * @param bootstrap Tell is bootstrap values must be writen.
+   * If so, the content of the property with name TreeTools::BOOTSTRAP will be written as bootstrap value.
+   * The property should be a Number<double> object.
+   * Otherwise, the content of the property with name 'propertyName' will be written.
+   * In this later case, the property should be a String object.
+   * @param propertyName The name of the property to use. Only used if bootstrap = false.
+   * @return A string in the parenthesis format.
+   */
+  static std::string treeToParenthesis(const TreeTemplate<Node>& tree, bool bootstrap, const std::string& propertyName);
+
+  /** @} */
+
+  /**
+   * @name Random trees
+   *
+   * @{
+   */
+
+  /**
+   * @brief Draw a random tree from a list of taxa, using a Yule process.
+   *
+   * @param leavesNames A list of taxa.
+   * @param rooted Tell is the output tree should be rooted.
+   * @return A random tree with all corresponding taxa.
+   */
+  static TreeTemplate<Node>* getRandomTree(std::vector<std::string>& leavesNames, bool rooted = true);
+
+  /** @} */
+
+  /**
+   * @brief Get a subset of node neighbors.
+   *
+   * Get all neighbors of node node1 that are neither node1 nor node2.
+   * This method is useful for topology manipulations, like NNI.
+   *
+   * @param node1 The node whose neighbors must be retrieved.
+   * @param node2 One neighbor to exclude.
+   * @param node3 Another neighbor to exclude.
+   * @return A vector of neighbors.
+   */
+  static std::vector<const Node*> getRemainingNeighbors(const Node* node1, const Node* node2, const Node* node3);
+
+  /**
+   * @brief This method will add a given value (possibly negative) to all identifiers in a (sub)tree.
+   *
+   * @param node The root node of the (sub)tree to use.
+   * @param increment The value to add.
+   */
+  static void incrementAllIds(Node* node, int increment);
+
+  /**
+   * @name Retrieve properties from a (sub)tree.
+   *
+   * @{
+   */
+
+  /**
+   * @brief Retrieve the names of all available node properties in the tree.
+   *
+   * @param node [in] The root node of the (sub)tree to use.
+   * @param propertyNames [out] a vector where names will be added.
+   */
+  static void getNodePropertyNames(const Node& node, std::vector<std::string>& propertyNames);
+
+  /**
+   * @brief Retrieve all node property objects with a given name over a (sub) tree (const version).
+   *
+   * @param node [in] The root node of the (sub)tree to use.
+   * @param propertyName [in] The name of the property to retrieve.
+   * @param properties [out] A map with pointers toward the properties as values, and node ids as key.
+   * If a node does not contain the given property, then no entry in the map is created.
+   * If an entry already exists in the map, it will be replaced, but the underlying property will not be destroyed.
+   * Property objects are not cloned when added to the map, but passed as pointers.
+   */
+  static void getNodeProperties(const Node& node, const std::string& propertyName, std::map<int, const Clonable*>& properties);
+
+  /**
+   * @brief Retrieve all node property objects with a given name over a (sub) tree.
+   *
+   * @param node [in] The root node of the (sub)tree to use.
+   * @param propertyName [in] The name of the property to retrieve.
+   * @param properties [out] A map with pointers toward the properties as values, and node ids as key.
+   * If a node does not contain the given property, then no entry in the map is created.
+   * If an entry already exists in the map, it will be replaced, but the underlying property will not be destroyed.
+   * Property objects are not cloned when added to the map, but passed as pointers.
+   */
+  static void getNodeProperties(Node& node, const std::string& propertyName, std::map<int, Clonable*>& properties);
+
+  /**
+   * @brief Retrieve the names of all available branch properties in the tree.
+   *
+   * @param node [in] The root node of the (sub)tree to use.
+   * @param propertyNames [out] a vector where names will be added.
+   */
+  static void getBranchPropertyNames(const Node& node, std::vector<std::string>& propertyNames);
+
+  /**
+   * @brief Retrieve all branch property objects with a given name over a (sub) tree (const version).
+   *
+   * @param node [in] The root node of the (sub)tree to use.
+   * @param propertyName [in] The name of the property to retrieve.
+   * @param properties [out] A map with pointers toward the properties as values, and node ids as key.
+   * If a node does not contain the given property, then no entry in the map is created.
+   * If an entry already exists in the map, it will be replaced, but the underlying property will not be destroyed.
+   * Property objects are not cloned when added to the map, but passed as pointers.
+   */
+  static void getBranchProperties(const Node& node, const std::string& propertyName, std::map<int, const Clonable*>& properties);
+
+  /**
+   * @brief Retrieve all branch property objects with a given name over a (sub) tree.
+   *
+   * @param node [in] The root node of the (sub)tree to use.
+   * @param propertyName [in] The name of the property to retrieve.
+   * @param properties [out] A map with pointers toward the properties as values, and node ids as key.
+   * If a node does not contain the given property, then no entry in the map is created.
+   * If an entry already exists in the map, it will be replaced, but the underlying property will not be destroyed.
+   * Property objects are not cloned when added to the map, but passed as pointers.
+   */
+  static void getBranchProperties(Node& node, const std::string& propertyName, std::map<int, Clonable*>& properties);
+
+  /**
+   * @brief Swap nodes in the subtree so that they are ordered according to the underlying number of leaves.
+   *
+   * @param node The root node of the (sub)tree to use.
+   * @param downward If yes, biggest subtrees (in terms of number of leaves) will come first. Otherwise, the smallest subtrees will come first.
+   * @param orderLeaves Tell if leaves have to be ordered alphabetically. This ensures that two identical topology will always have the same ordered tree, whatever the initial ordering of nodes.
+   */
+  static void orderTree(Node& node, bool downward = true, bool orderLeaves = false)
+  {
+    orderTree_(node, downward, orderLeaves);
+  }
+  /** @} */
+
+  /**
+   * @brief Midroot the tree by minimizing a given criterion ("variance" or "sum of squares")
+   *
+   * @details
+   * For each branch, the best root position, according to the given criterion, is computed analytically.
+   *
+   * For the 'variance' criterion :
+   * \f[
+   *  (n_1+n_2)^2 V(x)
+   *   = (n_1+n_2) \left[ \sum_{F_1} (d_i + x \delta )^2 + \sum_{F_2} (d_i + (1-x) \delta )^2 \right]
+   *     - \left[ \sum_{F_1} (d_i + x \delta) + \sum_{F_2} (d_i + (1-x) \delta) \right]^2
+   *   = A x^2 + B x + C
+   * \f]
+   * With
+   * \f[ \begin{array}{rcl}
+   * A &=& 4 n_1 n_2 \delta^2 \\
+   * B &=& 4 \delta ( n_2 S_1 - n_1 S_2 - n_1 n_2 \delta ) \\
+   * C &=& (n_1+n_2) (C_1+C_2) + n_1 n_2 \delta^2 + 2 n_1 S_2 \delta - 2 n_2 S_1 \delta - (S_1+S_2)^2 \\
+   * \end{array} \f]
+   *
+   * Where \f$F_1\f$ and \f$F_2\f$ are the sets of leaves on either side of
+   * the root branch,
+   * \f$d_i\f$ is the distance of leaf \f$i\f$ to the nearest end of the root branch,
+   * \f$\delta\f$ is the length of the root branch, and \f$S_k\f$ and \f$C_k\f$ are respectively
+   * \f$\sum_{F_k} d_i\f$ and \f$\sum_{F_k} d_i^2\f$
+   *
+   * ~
+   *
+   * If force_branch_root==true, then the function will always root the tree on a branch.
+   * To do so, in cases where the root is placed on a node, a new node new_root is created between the root and its nearest child.
+   * If force_branch_root==false, it may be placed on a node.
+   *
+   *
+   * @param tree
+   * @param criterion The criterion upon which to reroot. Legal values : TreeTemplateTools::MIDROOT_VARIANCE
+   *   to minimize root-leaf distance variance (molecular clock assumption) or
+   *   TreeTemplateTools::MIDROOT_SUM_OF_SQUARES to minimize the sum of root-leaf distance squares.
+   * @param forceBranchRoot If true, the root must be placed on a branch, otherwise it may also be placed on a node. 
+   *
+   * @author Nicolas Rochette
+   */
+  static void midRoot(TreeTemplate<Node>& tree, short criterion, bool forceBranchRoot);
+
+  /**
+   * @brief Get the caracteristic radius of a tree (average distance to the root minimizing the sum of squared distances).
+   *
+   * @param tree The tree (which is rerooted in the process).
+   */
+  static double getRadius(TreeTemplate<Node>& tree);
+
+
+  /**
+   * @brief Unresolve nodes with low confidence value.
+   *
+   * The underlying branches will be removed, resulting in a multifurcation.
+   * the branch length of the removed node is added to the length of its son nodes,
+   * so that pairwise phylogenetic distances are conserved along the tree.
+   * Leaves are not checked. Node with missing values are ignored.
+   *
+   * @author Julien Dutheil.
+   *
+   * @param subtree   The node defining the subtree where nodes should be collapsed.
+   * @param threshold The minimum value for which a node is considered to be confident.
+   * @param property  The branch property to be considered as a confidence value (bootstrap values by default).
+   */
+  static void unresolveUncertainNodes(Node& subtree, double threshold, const std::string& property = TreeTools::BOOTSTRAP);
+
+private:
+  struct OrderTreeData_
+  {
+    size_t size;
+    std::string firstLeaf;
+    OrderTreeData_() : size(0),
+      firstLeaf("") {}
+  };
+
+  static OrderTreeData_ orderTree_(Node& node, bool downward, bool orderLeaves);
+
+  /**
+   * @brief
+   * A <i>structure</i> recording, for a subtree, the sum of root-leaf distances, the sum of their squares,
+   * and the number of elements in these sums (ie. the number of leaves).
+   *
+   * @details
+   * The branch at the base of the subtree should never be included,
+   * as the subtree of the root does not have one.
+   *
+   */
+  struct Moments_
+  {
+    double sum;
+    double squaresSum;
+    int numberOfLeaves;
+  };
+
+  /**
+   * @brief
+   * Computes the moment of a subtree
+   *
+   * @param node The root of the subtree
+   * @return A Moments_ structure
+   */
+  static Moments_ getSubtreeMoments_(const Node* node);
+
+  /**
+   * @brief Find, in the branches of a subtree, the root that minimizes a criterion over the tree.
+   *
+   * @details
+   * The branches are explored recursively. For each branch leaving the input node, the method
+   * computes the best root position, possibly updates the bestRoot parameter, then recurses.
+   *
+   * @param tree The tree to which the subtree belongs. (The root is moved.)
+   * @param criterion The criterion to minimize. Legal values are TreeTemplateTools::MIDROOT_VARIANCE and TreeTemplateTools::MIDROOT_SUM_OF_SQUARES.
+   * @param node The root of the subtree.
+   * @param bestRoot The object storing the best root found, if it is better than the initial one, or otherwise left unchanged.
+   *
+   * @author Nicolas Rochette, Manolo Gouy
+   */
+  static void getBestRootInSubtree_(bpp::TreeTemplate<bpp::Node>& tree, short criterion,  bpp::Node* node, std::pair<bpp::Node*, std::map<std::string, double> >& bestRoot);
+
+public:
+  static const short MIDROOT_VARIANCE;
+  static const short MIDROOT_SUM_OF_SQUARES;
+};
+} // end of namespace bpp.
 
-#endif //_TREETEMPLATETOOLS_H_
+#endif // _TREETEMPLATETOOLS_H_
 
diff --git a/src/Bpp/Phyl/TreeTools.cpp b/src/Bpp/Phyl/TreeTools.cpp
index cf9fd28..ae496b1 100644
--- a/src/Bpp/Phyl/TreeTools.cpp
+++ b/src/Bpp/Phyl/TreeTools.cpp
@@ -5,7 +5,7 @@
 //
 
 /*
-   Copyright or © or Copr. CNRS, (November 16, 2004)
+   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.
@@ -55,7 +55,7 @@
 #include <Bpp/Numeric/Prob/ConstantDistribution.h>
 #include <Bpp/Numeric/Matrix/MatrixTools.h>
 
-// From SeqLib:
+// From bpp-seq:
 #include <Bpp/Seq/Alphabet/DNA.h>
 #include <Bpp/Seq/Container/VectorSiteContainer.h>
 
@@ -718,10 +718,11 @@ DistanceMatrix* TreeTools::getDistanceMatrix(const Tree& tree)
 
 void TreeTools::midpointRooting(Tree& tree)
 {
+  throw Exception("TreeTools::midpointRooting(Tree). This function is deprecated, use TreeTemplateTools::midRoot instead!");
   if (tree.isRooted())
     tree.unroot();
   DistanceMatrix* dist = getDistanceMatrix(tree);
-  vector<size_t> pos = MatrixTools::whichMax(*dist);
+  vector<size_t> pos = MatrixTools::whichMax(dist->asMatrix());
   double dmid = (*dist)(pos[0], pos[1]) / 2;
   int id1 = tree.getLeafId(dist->getName(pos[0]));
   int id2 = tree.getLeafId(dist->getName(pos[1]));
@@ -817,6 +818,26 @@ VectorSiteContainer* TreeTools::MRPEncode(const vector<Tree*>& vecTr)
 
 /******************************************************************************/
 
+VectorSiteContainer* TreeTools::MRPEncodeMultilabel(const vector<Tree*>& vecTr)
+{
+    vector<BipartitionList*> vecBipL;
+    for (size_t i = 0; i < vecTr.size(); i++)
+    {
+        vecBipL.push_back(new BipartitionList(*vecTr[i]));
+    }
+    
+    VectorSiteContainer* cont = BipartitionTools::MRPEncodeMultilabel(vecBipL);
+    
+    for (size_t i = 0; i < vecTr.size(); i++)
+    {
+        delete vecBipL[i];
+    }
+    
+    return cont;
+}
+
+/******************************************************************************/
+
 bool TreeTools::haveSameTopology(const Tree& tr1, const Tree& tr2)
 {
   size_t jj, nbbip;
@@ -981,7 +1002,7 @@ BipartitionList* TreeTools::bipartitionOccurrences(const vector<Tree*>& vecTr, v
   {
     if (bipScore[i - 1] == 0)
     {
-      bipScore.erase(bipScore.begin() + i - 1);
+      bipScore.erase(bipScore.begin() + static_cast<ptrdiff_t>(i - 1));
       mergedBipL->deleteBipartition(i - 1);
     }
   }
@@ -1100,7 +1121,7 @@ Tree* TreeTools::MRP(const vector<Tree*>& vecTr)
 
 /******************************************************************************/
 
-void TreeTools::computeBootstrapValues(Tree& tree, const vector<Tree*>& vecTr, bool verbose)
+void TreeTools::computeBootstrapValues(Tree& tree, const vector<Tree*>& vecTr, bool verbose, int format)
 {
   vector<int> index;
   BipartitionList bpTree(tree, true, &index);
@@ -1117,7 +1138,7 @@ void TreeTools::computeBootstrapValues(Tree& tree, const vector<Tree*>& vecTr, b
     {
       if (BipartitionTools::areIdentical(bpTree, i, *bpList, j))
       {
-        bootstrapValues[i] = (double) occurences[j] * 100. / (double) vecTr.size();
+        bootstrapValues[i] = format >= 0 ? round(static_cast<double>(occurences[j]) * pow(10., 2 + format) / static_cast<double>(vecTr.size())) / pow(10., format) : static_cast<double>(occurences[j]);
         break;
       }
     }
@@ -1261,3 +1282,33 @@ TreeTools::Moments_ TreeTools::statFromNode_(Tree& tree, int rootId)
   return m;
 }
 
+/******************************************************************************/
+
+Tree* TreeTools::MRPMultilabel(const vector<Tree*>& vecTr)
+{
+    // matrix representation
+    VectorSiteContainer* sites = TreeTools::MRPEncode(vecTr);
+    
+    // starting bioNJ tree
+    const DNA* alphabet = dynamic_cast<const DNA*>(sites->getAlphabet());
+    JCnuc* jc = new JCnuc(alphabet);
+    ConstantDistribution* constRate = new ConstantDistribution(1.);
+    DistanceEstimation distFunc(jc, constRate, sites, 0, true);
+    BioNJ bionjTreeBuilder(false, false);
+    bionjTreeBuilder.setDistanceMatrix(*(distFunc.getMatrix()));
+    bionjTreeBuilder.computeTree();
+    if (ApplicationTools::message)
+        ApplicationTools::message->endLine();
+    TreeTemplate<Node>* startTree = new TreeTemplate<Node>(*bionjTreeBuilder.getTree());
+    
+    // MP optimization
+    DRTreeParsimonyScore* MPScore = new DRTreeParsimonyScore(*startTree, *sites, false);
+    MPScore = OptimizationTools::optimizeTreeNNI(MPScore, 0);
+    delete startTree;
+    Tree* retTree = new TreeTemplate<Node>(MPScore->getTree());
+    delete MPScore;
+    
+    return retTree;
+}
+
+
diff --git a/src/Bpp/Phyl/TreeTools.h b/src/Bpp/Phyl/TreeTools.h
index ae1ae0c..f15beb2 100755
--- a/src/Bpp/Phyl/TreeTools.h
+++ b/src/Bpp/Phyl/TreeTools.h
@@ -413,6 +413,7 @@ class TreeTools
      * The root is then set on the branch located at half this distance.
      *
      * @param tree The tree to (re)root.
+     * @deprecated Use TreeTemplateTools::midRoot instead!
      */
     static void midpointRooting(Tree& tree);
     /** @} */
@@ -563,10 +564,21 @@ class TreeTools
     static VectorSiteContainer* MRPEncode(const std::vector<Tree*>& vecTr);
 
     /**
+     * @brief Creates a sequence data set corresponding to the Matrix Representation of the input multilabel trees
+     *
+     * @author Nicolas Galtier and Bastien Boussau
+     * Trees can have distinct sets of elements - missing data will be represented as 'N'.
+     * The output alignment (DNA sequences including only A, C and N)) is ready for maximum parsimony analysis
+     * according to the MRP supertree method.
+     */
+    static VectorSiteContainer* MRPEncodeMultilabel(const std::vector<Tree*>& vecTr);
+
+    /**
      * @brief Tells whether two trees have the same unrooted topology
      *
-     * @author Nicolas Galtier
      * Note that the location of the root, if any, is ignored.
+     *
+     * @author Nicolas Galtier
      */
     static bool haveSameTopology(const Tree& tr1, const Tree& tr2);
 
@@ -667,11 +679,13 @@ class TreeTools
     /**
      * @brief Compute bootstrap values.
      *
-     * @param tree Input tree. the BOOTSTRAP banch property of the tree will be modified if it already exists.
-     * @param vecTr A list of trees to compare to 'tree'.
+     * @param tree    Input tree. the BOOTSTRAP banch property of the tree will be modified if it already exists.
+     * @param vecTr   A list of trees to compare to 'tree'.
      * @param verbose Tell if a progress bar should be displayed.
+     * @param format  If null or positive, bootstrap values are reported as percentage, with the given number of decimal digits.
+     *                If negative, bootstrap calues are the raw number of tree occurrences.
      */
-    static void computeBootstrapValues(Tree& tree, const std::vector<Tree*>& vecTr, bool verbose = true);
+    static void computeBootstrapValues(Tree& tree, const std::vector<Tree*>& vecTr, bool verbose = true, int format = 0);
 	
     /**
      * @brief Determine the mid-point position of the root along the branch that already contains the root. Consequently, the topology of the rooted tree remains identical.
@@ -682,6 +696,20 @@ class TreeTools
      * @param tree The rooted tree for which the root has to be moved to its mid-point position, along the branch where it already stands.
      */    
     static void constrainedMidPointRooting(Tree& tree);
+    
+    /**
+     * @brief Matrix Representation Parsimony supertree method for multilabel trees
+     *
+     * This implementation of the MRP method takes a BIONJ tree (Jukes-Cantor distances)
+     * as the starting tree and optimizes the parsimony score using only NNI (in a
+     * PHYML-like way).
+     *
+     * @author Nicolas Galtier slightly modified by Bastien Boussau
+     * @param vecTr A vector of trees.
+     * @return The MRP super tree.
+     */
+    static Tree* MRPMultilabel(const std::vector<Tree*>& vecTr);
+
 	
     /**
      * @name Some properties.
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 09f9a3c..c0c57df 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -53,6 +53,7 @@ SET(CPP_FILES
   Bpp/Phyl/Likelihood/TreeLikelihoodTools.cpp
   Bpp/Phyl/Likelihood/PairedSiteLikelihoods.cpp
   Bpp/Phyl/Likelihood/GlobalClockTreeLikelihoodFunctionWrapper.cpp
+  Bpp/Phyl/Mapping/SubstitutionRegister.cpp
   Bpp/Phyl/Mapping/LaplaceSubstitutionCount.cpp
   Bpp/Phyl/Mapping/OneJumpSubstitutionCount.cpp
   Bpp/Phyl/Mapping/ProbabilisticSubstitutionMapping.cpp
@@ -61,6 +62,9 @@ SET(CPP_FILES
   Bpp/Phyl/Mapping/UniformizationSubstitutionCount.cpp
   Bpp/Phyl/Mapping/WeightedSubstitutionCount.cpp
   Bpp/Phyl/Mapping/SubstitutionMappingTools.cpp
+  Bpp/Phyl/Mapping/DecompositionReward.cpp
+  Bpp/Phyl/Mapping/ProbabilisticRewardMapping.cpp
+  Bpp/Phyl/Mapping/RewardMappingTools.cpp
   Bpp/Phyl/Model/StateMap.cpp
   Bpp/Phyl/Model/BinarySubstitutionModel.cpp
   Bpp/Phyl/Model/AbstractSubstitutionModel.cpp
@@ -102,6 +106,7 @@ SET(CPP_FILES
   Bpp/Phyl/Model/Protein/LLG08_EX3.cpp
   Bpp/Phyl/Model/Protein/LLG08_UL2.cpp
   Bpp/Phyl/Model/Protein/LLG08_UL3.cpp
+  Bpp/Phyl/Model/Protein/LG10_EX_EHO.cpp
   Bpp/Phyl/Model/Protein/LGL08_CAT.cpp
   Bpp/Phyl/Model/Protein/Coala.cpp
   Bpp/Phyl/Model/Protein/CoalaCore.cpp
@@ -221,8 +226,14 @@ SET(H_FILES
   Bpp/Phyl/Mapping/UniformizationSubstitutionCount.h
   Bpp/Phyl/Mapping/SubstitutionRegister.h
   Bpp/Phyl/Mapping/SubstitutionCount.h
+  Bpp/Phyl/Mapping/Mapping.h
   Bpp/Phyl/Mapping/SubstitutionMapping.h
   Bpp/Phyl/Mapping/SubstitutionMappingTools.h
+  Bpp/Phyl/Mapping/Reward.h
+  Bpp/Phyl/Mapping/DecompositionReward.h
+  Bpp/Phyl/Mapping/RewardMapping.h
+  Bpp/Phyl/Mapping/RewardMappingTools.h
+  Bpp/Phyl/Mapping/ProbabilisticRewardMapping.h
   Bpp/Phyl/Model/StateMap.h
   Bpp/Phyl/Model/AbstractSubstitutionModel.h
   Bpp/Phyl/Model/BinarySubstitutionModel.h
@@ -270,6 +281,7 @@ SET(H_FILES
   Bpp/Phyl/Model/Protein/LLG08_EX3.h
   Bpp/Phyl/Model/Protein/LLG08_UL2.h
   Bpp/Phyl/Model/Protein/LLG08_UL3.h
+  Bpp/Phyl/Model/Protein/LG10_EX_EHO.h
   Bpp/Phyl/Model/Protein/LGL08_CAT.h
   Bpp/Phyl/Model/Protein/Coala.h
   Bpp/Phyl/Model/Protein/CoalaCore.h
diff --git a/test/test_detailed_simulations.cpp b/test/test_detailed_simulations.cpp
index 900c08a..a569a46 100644
--- a/test/test_detailed_simulations.cpp
+++ b/test/test_detailed_simulations.cpp
@@ -66,7 +66,7 @@ int main() {
   for (size_t j = 0; j < ids.size() - 1; ++j) //ignore root, the last id
     counts[ids[j]].resize(4, 4);
   for (unsigned int i = 0; i < n; ++i) {
-    RASiteSimulationResult* result = simulator.dSimulate();
+    RASiteSimulationResult* result = simulator.dSimulateSite();
     for (size_t j = 0; j < ids.size() - 1; ++j) { //ignore root, the last id
       result->getMutationPath(ids[j]).getEventCounts(counts[ids[j]]);
     }
diff --git a/test/test_likelihood.cpp b/test/test_likelihood.cpp
index fe5081e..c797bb6 100644
--- a/test/test_likelihood.cpp
+++ b/test/test_likelihood.cpp
@@ -42,6 +42,7 @@ knowledge of the CeCILL license and that you accept its terms.
 #include <Bpp/Seq/Alphabet/AlphabetTools.h>
 #include <Bpp/Phyl/TreeTemplate.h>
 #include <Bpp/Phyl/Model/Nucleotide/T92.h>
+#include <Bpp/Phyl/Model/RateDistribution/GammaDiscreteRateDistribution.h>
 #include <Bpp/Phyl/Simulation/HomogeneousSequenceSimulator.h>
 #include <Bpp/Phyl/Likelihood/RHomogeneousTreeLikelihood.h>
 #include <Bpp/Phyl/OptimizationTools.h>
@@ -50,7 +51,7 @@ knowledge of the CeCILL license and that you accept its terms.
 using namespace bpp;
 using namespace std;
 
-void fitModelH(SubstitutionModel* model, DiscreteDistribution* rdist, const Tree& tree, const SiteContainer& sites,
+void fitModelHSR(SubstitutionModel* model, DiscreteDistribution* rdist, const Tree& tree, const SiteContainer& sites,
     double initialValue, double finalValue) {
   RHomogeneousTreeLikelihood tl(tree, sites, model, rdist);
   tl.initialize();
@@ -68,16 +69,31 @@ void fitModelH(SubstitutionModel* model, DiscreteDistribution* rdist, const Tree
     throw Exception("Incorrect final value.");
 }
 
+void fitModelHDR(SubstitutionModel* model, DiscreteDistribution* rdist, const Tree& tree, const SiteContainer& sites,
+    double initialValue, double finalValue) {
+  DRHomogeneousTreeLikelihood tl(tree, sites, model, rdist);
+  tl.initialize();
+  ApplicationTools::displayResult("Test model", model->getName());
+  cout << setprecision(20) << tl.getValue() << endl;
+  ApplicationTools::displayResult("* initial likelihood", tl.getValue());
+  if (abs(tl.getValue() - initialValue) > 0.001)
+    throw Exception("Incorrect initial value.");
+  OptimizationTools::optimizeTreeScale(&tl);
+  ApplicationTools::displayResult("* likelihood after tree scale", tl.getValue());
+  OptimizationTools::optimizeNumericalParameters2(&tl, tl.getParameters(), 0, 0.000001, 10000, 0, 0);
+  cout << setprecision(20) << tl.getValue() << endl;
+  ApplicationTools::displayResult("* likelihood after full optimization", tl.getValue());
+  if (abs(tl.getValue() - finalValue) > 0.001)
+    throw Exception("Incorrect final value.");
+}
+
 int main() {
-  TreeTemplate<Node>* tree = TreeTemplateTools::parenthesisToTree("((A:0.01, B:0.02):0.03,C:0.01,D:0.1);");
+  auto_ptr<TreeTemplate<Node> > tree(TreeTemplateTools::parenthesisToTree("((A:0.01, B:0.02):0.03,C:0.01,D:0.1);"));
   vector<string> seqNames= tree->getLeavesNames();
   vector<int> ids = tree->getNodesId();
   //-------------
 
   const NucleicAlphabet* alphabet = &AlphabetTools::DNA_ALPHABET;
-  SubstitutionModel* model = new T92(alphabet, 3.);
-  DiscreteDistribution* rdist = new GammaDiscreteDistribution(1.0, 4);
-  rdist->aliasParameters("alpha", "beta");
 
   VectorSiteContainer sites(alphabet);
   sites.addSequence(BasicSequence("A", "AAATGGCTGTGCACGTC", alphabet));
@@ -85,17 +101,38 @@ int main() {
   sites.addSequence(BasicSequence("C", "CTCTGGATGTGCACGTG", alphabet));
   sites.addSequence(BasicSequence("D", "AAATGGCGGTGCGCCTA", alphabet));
 
+  auto_ptr<SubstitutionModel> model(new T92(alphabet, 3.));
+  auto_ptr<DiscreteDistribution> rdist(new GammaDiscreteRateDistribution(4, 1.0));
   try {
-    fitModelH(model, rdist, *tree, sites, 75.031104151696752069, 65.03473753351640596065);
+    cout << "Testing Single Tree Traversal likelihood class..." << endl;
+    fitModelHSR(model.get(), rdist.get(), *tree, sites, 85.030942031997312824, 65.72293577214308868406);
   } catch (Exception& ex) {
     cerr << ex.what() << endl;
     return 1;
   }  
 
-  //-------------
-  delete tree;
-  delete model;
-  delete rdist;
+  model.reset(new T92(alphabet, 3.));
+  rdist.reset(new GammaDiscreteRateDistribution(4, 1.0));
+  try {
+    cout << "Testing Double Tree Traversal likelihood class..." << endl;
+    fitModelHDR(model.get(), rdist.get(), *tree, sites, 85.030942031997312824, 65.72293577214308868406);
+  } catch (Exception& ex) {
+    cerr << ex.what() << endl;
+    return 1;
+  }  
+
+  //Let's compare the derivatives:
+  RHomogeneousTreeLikelihood tlsr(*tree, sites, model.get(), rdist.get());
+  tlsr.initialize();
+  DRHomogeneousTreeLikelihood tldr(*tree, sites, model.get(), rdist.get());
+  tldr.initialize();
+  vector<string> params = tlsr.getBranchLengthsParameters().getParameterNames();
+  for (vector<string>::iterator it = params.begin(); it != params.end(); ++it) {
+    double d1sr = tlsr.getFirstOrderDerivative(*it);
+    double d1dr = tldr.getFirstOrderDerivative(*it);
+    cout << *it << "\t" << d1sr << "\t" << d1dr << endl;
+    if (abs(d1sr - d1dr) > 0.000001) return 1;
+  }
 
   return 0;
 }
diff --git a/test/test_likelihood_clock.cpp b/test/test_likelihood_clock.cpp
index 2647ffa..e89c4f0 100644
--- a/test/test_likelihood_clock.cpp
+++ b/test/test_likelihood_clock.cpp
@@ -37,11 +37,11 @@ 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/GammaDiscreteDistribution.h>
 #include <Bpp/Numeric/Matrix/MatrixTools.h>
 #include <Bpp/Seq/Alphabet/AlphabetTools.h>
 #include <Bpp/Phyl/TreeTemplate.h>
 #include <Bpp/Phyl/Model/Nucleotide/T92.h>
+#include <Bpp/Phyl/Model/RateDistribution/GammaDiscreteRateDistribution.h>
 #include <Bpp/Phyl/Simulation/HomogeneousSequenceSimulator.h>
 #include <Bpp/Phyl/Likelihood/RHomogeneousTreeLikelihood.h>
 #include <Bpp/Phyl/Likelihood/RHomogeneousClockTreeLikelihood.h>
@@ -103,8 +103,7 @@ int main() {
 
   const NucleicAlphabet* alphabet = &AlphabetTools::DNA_ALPHABET;
   SubstitutionModel* model = new T92(alphabet, 3.);
-  DiscreteDistribution* rdist = new GammaDiscreteDistribution(4, 1.0);
-  rdist->aliasParameters("alpha", "beta");
+  DiscreteDistribution* rdist = new GammaDiscreteRateDistribution(4, 1.0);
 
   VectorSiteContainer sites(alphabet);
   sites.addSequence(BasicSequence("A", "AAATGGCTGTGCACGTC", alphabet));
diff --git a/test/test_likelihood_nh.cpp b/test/test_likelihood_nh.cpp
index 84f0a0e..c1f0e45 100644
--- a/test/test_likelihood_nh.cpp
+++ b/test/test_likelihood_nh.cpp
@@ -37,13 +37,13 @@ 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/GammaDiscreteDistribution.h>
 #include <Bpp/Numeric/Matrix/MatrixTools.h>
 #include <Bpp/Seq/Alphabet/AlphabetTools.h>
 #include <Bpp/Phyl/TreeTemplate.h>
 #include <Bpp/Phyl/Model/Nucleotide/T92.h>
 #include <Bpp/Phyl/Model/FrequenciesSet/NucleotideFrequenciesSet.h>
 #include <Bpp/Phyl/Model/SubstitutionModelSetTools.h>
+#include <Bpp/Phyl/Model/RateDistribution/GammaDiscreteRateDistribution.h>
 #include <Bpp/Phyl/Simulation/NonHomogeneousSequenceSimulator.h>
 #include <Bpp/Phyl/Likelihood/RNonHomogeneousTreeLikelihood.h>
 #include <Bpp/Phyl/Likelihood/DRNonHomogeneousTreeLikelihood.h>
@@ -84,8 +84,7 @@ int main() {
   SubstitutionModelSet* modelSet = SubstitutionModelSetTools::createNonHomogeneousModelSet(model, rootFreqs, tree, globalParameterNames);
   //DiscreteDistribution* rdist = new ConstantDistribution(1.0, true);
   //Very difficult to optimize on small datasets:
-  DiscreteDistribution* rdist = new GammaDiscreteDistribution(4, 1.0);
-  rdist->aliasParameters("alpha", "beta");
+  DiscreteDistribution* rdist = new GammaDiscreteRateDistribution(4, 1.0);
 
   size_t nsites = 1000;
   unsigned int nrep = 20;
diff --git a/test/test_mapping.cpp b/test/test_mapping.cpp
index 94f5f00..8fd3c61 100644
--- a/test/test_mapping.cpp
+++ b/test/test_mapping.cpp
@@ -73,8 +73,8 @@ int main() {
   //DiscreteDistribution* rdist = new GammaDiscreteDistribution(4, 0.4, 0.4);
   DiscreteDistribution* rdist = new ConstantDistribution(1.0);
   HomogeneousSequenceSimulator simulator(model, rdist, tree);
-  TotalSubstitutionRegister* totReg = new TotalSubstitutionRegister(alphabet);
-  ComprehensiveSubstitutionRegister* detReg = new ComprehensiveSubstitutionRegister(alphabet);
+  TotalSubstitutionRegister* totReg = new TotalSubstitutionRegister(model);
+  ComprehensiveSubstitutionRegister* detReg = new ComprehensiveSubstitutionRegister(model);
 
   unsigned int n = 20000;
   vector< vector<double> > realMap(n);
@@ -83,7 +83,7 @@ int main() {
   VectorSiteContainer sites(tree->getLeavesNames(), alphabet);
   for (unsigned int i = 0; i < n; ++i) {
     ApplicationTools::displayGauge(i, n-1, '=');
-    auto_ptr<RASiteSimulationResult> result(simulator.dSimulate());
+    auto_ptr<RASiteSimulationResult> result(simulator.dSimulateSite());
     realMap[i].resize(ids.size());
     realMapTotal[i].resize(ids.size());
     realMapDetailed[i].resize(ids.size());
@@ -102,8 +102,8 @@ int main() {
         return 1;
       }
     }
-    auto_ptr<Site> site(result->getSite());
-    site->setPosition(i);
+    auto_ptr<Site> site(result->getSite(*model));
+    site->setPosition(static_cast<int>(i));
     sites.addSite(*site, false);
   }
   ApplicationTools::displayTaskDone();
@@ -115,31 +115,31 @@ int main() {
   DRHomogeneousTreeLikelihood drhtl(*tree, sites, model, rdist);
   drhtl.initialize();
   cout << drhtl.getValue() << endl;
- 
+
   SubstitutionCount* sCountAna = new LaplaceSubstitutionCount(model, 10);
   Matrix<double>* m = sCountAna->getAllNumbersOfSubstitutions(0.001, 1);
   cout << "Analytical total count:" << endl;
   MatrixTools::print(*m);
   delete m;
   ProbabilisticSubstitutionMapping* probMapAna = 
-    SubstitutionMappingTools::computeSubstitutionVectors(drhtl, *sCountAna);
+    SubstitutionMappingTools::computeSubstitutionVectors(drhtl, ids, *sCountAna);
 
   //Simple:
-  SubstitutionCount* sCountTot = new NaiveSubstitutionCount(totReg);
+  SubstitutionCount* sCountTot = new NaiveSubstitutionCount(model, totReg);
   m = sCountTot->getAllNumbersOfSubstitutions(0.001,1);
   cout << "Simple total count:" << endl;
   MatrixTools::print(*m);
   delete m;
   ProbabilisticSubstitutionMapping* probMapTot = 
-    SubstitutionMappingTools::computeSubstitutionVectors(drhtl, *sCountTot);
+    SubstitutionMappingTools::computeSubstitutionVectors(drhtl, ids, *sCountTot);
 
-  SubstitutionCount* sCountDet = new NaiveSubstitutionCount(detReg);
+  SubstitutionCount* sCountDet = new NaiveSubstitutionCount(model, detReg);
   m = sCountDet->getAllNumbersOfSubstitutions(0.001,1);
   cout << "Detailed count, type 1:" << endl;
   MatrixTools::print(*m);
   delete m;
   ProbabilisticSubstitutionMapping* probMapDet = 
-    SubstitutionMappingTools::computeSubstitutionVectors(drhtl, *sCountDet);
+    SubstitutionMappingTools::computeSubstitutionVectors(drhtl, ids, *sCountDet);
 
   //Decomposition:
   SubstitutionCount* sCountDecTot = new DecompositionSubstitutionCount(model, totReg);
@@ -148,7 +148,7 @@ int main() {
   MatrixTools::print(*m);
   delete m;
   ProbabilisticSubstitutionMapping* probMapDecTot = 
-    SubstitutionMappingTools::computeSubstitutionVectors(drhtl, *sCountDecTot);
+    SubstitutionMappingTools::computeSubstitutionVectors(drhtl, ids, *sCountDecTot);
 
   SubstitutionCount* sCountDecDet = new DecompositionSubstitutionCount(model, detReg);
   m = sCountDecDet->getAllNumbersOfSubstitutions(0.001,1);
@@ -156,7 +156,7 @@ int main() {
   MatrixTools::print(*m);
   delete m;
   ProbabilisticSubstitutionMapping* probMapDecDet = 
-    SubstitutionMappingTools::computeSubstitutionVectors(drhtl, *sCountDecDet);
+    SubstitutionMappingTools::computeSubstitutionVectors(drhtl, ids, *sCountDecDet);
 
   //Uniformization
   SubstitutionCount* sCountUniTot = new UniformizationSubstitutionCount(model, totReg);
@@ -165,7 +165,7 @@ int main() {
   MatrixTools::print(*m);
   delete m;
   ProbabilisticSubstitutionMapping* probMapUniTot = 
-    SubstitutionMappingTools::computeSubstitutionVectors(drhtl, *sCountUniTot);  
+    SubstitutionMappingTools::computeSubstitutionVectors(drhtl, ids, *sCountUniTot);  
 
   SubstitutionCount* sCountUniDet = new UniformizationSubstitutionCount(model, detReg);
   m = sCountUniDet->getAllNumbersOfSubstitutions(0.001,1);
@@ -173,7 +173,7 @@ int main() {
   MatrixTools::print(*m);
   delete m;
   ProbabilisticSubstitutionMapping* probMapUniDet = 
-    SubstitutionMappingTools::computeSubstitutionVectors(drhtl, *sCountUniDet);
+    SubstitutionMappingTools::computeSubstitutionVectors(drhtl, ids, *sCountUniDet);
 
   //Check saturation:
   cout << "checking saturation..." << endl;
diff --git a/test/test_mapping_codon.cpp b/test/test_mapping_codon.cpp
index c5286de..3e98269 100644
--- a/test/test_mapping_codon.cpp
+++ b/test/test_mapping_codon.cpp
@@ -41,11 +41,12 @@ knowledge of the CeCILL license and that you accept its terms.
 #include <Bpp/Numeric/Prob/ConstantDistribution.h>
 #include <Bpp/Numeric/Matrix/MatrixTools.h>
 #include <Bpp/Seq/Alphabet/AlphabetTools.h>
-#include <Bpp/Seq/Alphabet/StandardCodonAlphabet.h>
+#include <Bpp/Seq/Alphabet/CodonAlphabet.h>
 #include <Bpp/Seq/Io/Fasta.h>
 #include <Bpp/Seq/GeneticCode/StandardGeneticCode.h>
 #include <Bpp/Phyl/TreeTemplate.h>
 #include <Bpp/Phyl/Model/Nucleotide/JCnuc.h>
+#include <Bpp/Phyl/Model/Codon/YN98.h>
 #include <Bpp/Phyl/Model/Codon/CodonRateSubstitutionModel.h>
 #include <Bpp/Phyl/Model/FrequenciesSet/CodonFrequenciesSet.h>
 #include <Bpp/Phyl/Simulation/HomogeneousSequenceSimulator.h>
@@ -69,17 +70,18 @@ int main() {
 
   //-------------
 
-  CodonAlphabet* alphabet = new StandardCodonAlphabet(&AlphabetTools::DNA_ALPHABET);
+  CodonAlphabet* alphabet = new CodonAlphabet(&AlphabetTools::DNA_ALPHABET);
   GeneticCode* gc = new StandardGeneticCode(&AlphabetTools::DNA_ALPHABET);
-  //SubstitutionModel* model = new YN98(gc, CodonFrequenciesSet::getFrequenciesSetForCodons(CodonFrequenciesSet::F0, *alphabet));
-  SubstitutionModel* model = new CodonRateSubstitutionModel(
-        dynamic_cast<const CodonAlphabet*>(gc->getSourceAlphabet()),
-        new JCnuc(dynamic_cast<CodonAlphabet*>(alphabet)->getNucleicAlphabet()));
+  CodonSubstitutionModel* model = new YN98(gc, CodonFrequenciesSet::getFrequenciesSetForCodons(CodonFrequenciesSet::F0, gc));
+  //SubstitutionModel* model = new CodonRateSubstitutionModel(
+  //      gc,
+  //      new JCnuc(dynamic_cast<CodonAlphabet*>(alphabet)->getNucleicAlphabet()));
+  cout << model->getNumberOfStates() << endl;
   MatrixTools::printForR(model->getGenerator(), "g");
   DiscreteDistribution* rdist = new ConstantDistribution(1.0);
   HomogeneousSequenceSimulator simulator(model, rdist, tree);
-  TotalSubstitutionRegister* totReg = new TotalSubstitutionRegister(alphabet);
-  DnDsSubstitutionRegister* dndsReg = new DnDsSubstitutionRegister(gc);
+  TotalSubstitutionRegister* totReg = new TotalSubstitutionRegister(model);
+  DnDsSubstitutionRegister* dndsReg = new DnDsSubstitutionRegister(model);
 
   unsigned int n = 20000;
   vector< vector<double> > realMap(n);
@@ -88,7 +90,7 @@ int main() {
   VectorSiteContainer sites(tree->getLeavesNames(), alphabet);
   for (unsigned int i = 0; i < n; ++i) {
     ApplicationTools::displayGauge(i, n-1, '=');
-    RASiteSimulationResult* result = simulator.dSimulate();
+    RASiteSimulationResult* result = simulator.dSimulateSite();
     realMap[i].resize(ids.size());
     realMapTotal[i].resize(ids.size());
     realMapDnDs[i].resize(ids.size());
@@ -107,8 +109,8 @@ int main() {
       //  return 1;
       //}
     }
-    auto_ptr<Site> site(result->getSite());
-    site->setPosition(i);
+    auto_ptr<Site> site(result->getSite(*model));
+    site->setPosition(static_cast<int>(i));
     sites.addSite(*site, false);
     delete result;
   }
@@ -128,23 +130,23 @@ int main() {
   MatrixTools::print(*m);
   delete m;
   ProbabilisticSubstitutionMapping* probMapAna = 
-    SubstitutionMappingTools::computeSubstitutionVectors(drhtl, *sCountAna);
+    SubstitutionMappingTools::computeSubstitutionVectors(drhtl, ids, *sCountAna);
 
-  SubstitutionCount* sCountTot = new NaiveSubstitutionCount(totReg);
+  SubstitutionCount* sCountTot = new NaiveSubstitutionCount(model, totReg);
   m = sCountTot->getAllNumbersOfSubstitutions(0.001,1);
   cout << "Simple total count:" << endl;
   MatrixTools::print(*m);
   delete m;
   ProbabilisticSubstitutionMapping* probMapTot = 
-    SubstitutionMappingTools::computeSubstitutionVectors(drhtl, *sCountTot);
+    SubstitutionMappingTools::computeSubstitutionVectors(drhtl, ids, *sCountTot);
 
-  SubstitutionCount* sCountDnDs = new NaiveSubstitutionCount(dndsReg);
+  SubstitutionCount* sCountDnDs = new NaiveSubstitutionCount(model, dndsReg);
   m = sCountDnDs->getAllNumbersOfSubstitutions(0.001,1);
   cout << "Detailed count, type 1:" << endl;
   MatrixTools::print(*m);
   delete m;
   ProbabilisticSubstitutionMapping* probMapDnDs = 
-    SubstitutionMappingTools::computeSubstitutionVectors(drhtl, *sCountDnDs);
+    SubstitutionMappingTools::computeSubstitutionVectors(drhtl, ids, *sCountDnDs);
 
   SubstitutionCount* sCountUniTot = new UniformizationSubstitutionCount(model, totReg);
   m = sCountUniTot->getAllNumbersOfSubstitutions(0.001,1);
@@ -152,7 +154,7 @@ int main() {
   MatrixTools::print(*m);
   delete m;
   ProbabilisticSubstitutionMapping* probMapUniTot = 
-    SubstitutionMappingTools::computeSubstitutionVectors(drhtl, *sCountUniTot);
+    SubstitutionMappingTools::computeSubstitutionVectors(drhtl, ids, *sCountUniTot);
 
   SubstitutionCount* sCountUniDnDs = new UniformizationSubstitutionCount(model, dndsReg);
   m = sCountUniDnDs->getAllNumbersOfSubstitutions(0.001,2);
@@ -160,7 +162,7 @@ int main() {
   MatrixTools::print(*m);
   delete m;
   ProbabilisticSubstitutionMapping* probMapUniDnDs = 
-    SubstitutionMappingTools::computeSubstitutionVectors(drhtl, *sCountUniDnDs);
+    SubstitutionMappingTools::computeSubstitutionVectors(drhtl, ids, *sCountUniDnDs);
 
   //Check per branch:
   
diff --git a/test/test_models.cpp b/test/test_models.cpp
index 052f0d6..da57f5b 100644
--- a/test/test_models.cpp
+++ b/test/test_models.cpp
@@ -41,7 +41,7 @@ knowledge of the CeCILL license and that you accept its terms.
 #include <Bpp/Phyl/Model/Codon/YN98.h>
 #include <Bpp/Phyl/Model/FrequenciesSet/CodonFrequenciesSet.h>
 #include <Bpp/Seq/Alphabet/AlphabetTools.h>
-#include <Bpp/Seq/Alphabet/StandardCodonAlphabet.h>
+#include <Bpp/Seq/Alphabet/CodonAlphabet.h>
 #include <Bpp/Seq/GeneticCode/StandardGeneticCode.h>
 #include <Bpp/Numeric/Function/Functions.h>
 #include <Bpp/Numeric/Function/ReparametrizationFunctionWrapper.h>
@@ -117,8 +117,8 @@ int main() {
 
   //Codon models:
   StandardGeneticCode gc(&AlphabetTools::DNA_ALPHABET);
-  const CodonAlphabet* codonAlphabet = new StandardCodonAlphabet(&AlphabetTools::DNA_ALPHABET);
-  FrequenciesSet* fset = CodonFrequenciesSet::getFrequenciesSetForCodons(CodonFrequenciesSet::F3X4, *codonAlphabet);
+  const CodonAlphabet* codonAlphabet = new CodonAlphabet(&AlphabetTools::DNA_ALPHABET);
+  FrequenciesSet* fset = CodonFrequenciesSet::getFrequenciesSetForCodons(CodonFrequenciesSet::F3X4, &gc);
   YN98 yn98(&gc, fset);
   if (!testModel(yn98)) return 1;
 
diff --git a/test/test_simulations.cpp b/test/test_simulations.cpp
index f0d78f7..dc7a08f 100644
--- a/test/test_simulations.cpp
+++ b/test/test_simulations.cpp
@@ -80,12 +80,14 @@ int main() {
   OutputStream* messenger = new StlOutputStream(new ofstream("messages.txt", ios::out));
 
   //Check fast simulation first:
-  
+ 
+  cout << "Fast check:" << endl;
+ 
   //Generate data set:
   VectorSiteContainer sites(seqNames, alphabet);
   for (unsigned int i = 0; i < n; ++i) {
-    auto_ptr<Site> site(simulator.simulate());
-    site->setPosition(i);
+    auto_ptr<Site> site(simulator.simulateSite());
+    site->setPosition(static_cast<int>(i));
     sites.addSite(*site, false);
   }
 
@@ -109,12 +111,14 @@ int main() {
 
   //Now try detailed simulations:
 
+  cout << "Detailed check:" << endl;
+  
   //Generate data set:
   VectorSiteContainer sites2(seqNames, alphabet);
   for (unsigned int i = 0; i < n; ++i) {
-    RASiteSimulationResult* result = simulator.dSimulate();
-    auto_ptr<Site> site(result->getSite());
-    site->setPosition(i);
+    RASiteSimulationResult* result = simulator.dSimulateSite();
+    auto_ptr<Site> site(result->getSite(*simulator.getSubstitutionModelSet()->getModel(0)));
+    site->setPosition(static_cast<int>(i));
     sites2.addSite(*site, false);
     delete result;
   }
diff --git a/test/test_tree.cpp b/test/test_tree.cpp
index 3e3e8ef..79c661d 100644
--- a/test/test_tree.cpp
+++ b/test/test_tree.cpp
@@ -238,8 +238,31 @@ int main() {
   cout << TreeTemplateTools::treeToParenthesis(*weird6) << endl;
   delete weird6;
 
+  // Test TreeTools functions:
+  
+  //getPathBetweenAnyTwoNodes()...
+  TreeTemplate <Node>* tree = TreeTemplateTools::parenthesisToTree ("(A:0.1, (B :0.2, C:0.4):0.1);" );
+  vector <int> Leaves_select = tree->getLeavesId();
 
+  Node* node1 = tree->getNode(Leaves_select[0]);
+  Node* node2 = tree->getNode(Leaves_select[1]);
+  Node* node3 = tree->getNode(Leaves_select[2]);
 
+  vector<Node*> vecNode = TreeTemplateTools::getPathBetweenAnyTwoNodes(*node1, *node2, true);
+  cout << "Id node1 " << node1->getId() << endl;
+  cout << "Id node2 " << node2->getId() << endl;
+  cout << "Ids of path:" << endl;
+  for (size_t i = 0; i < vecNode.size(); i++){
+    cout << vecNode[i]->getId() << endl;
+  }
 
+  vecNode = TreeTemplateTools::getPathBetweenAnyTwoNodes(*node1, *node3, true);
+  cout << "Id node1 " << node1->getId() << endl;
+  cout << "Id node3 " << node3->getId() << endl;
+  cout << "Ids of path: " << endl;
+  for (size_t i = 0; i < vecNode.size(); i++){
+    cout << vecNode[i]->getId() << endl;
+  }
+  
   return 0;
 }

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



More information about the debian-med-commit mailing list