[med-svn] [libbpp-phyl] 01/03: New upstream version 2.3.2

Julien Dutheil jdutheil-guest at moszumanska.debian.org
Tue Feb 6 12:41:12 UTC 2018


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

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

commit 7e007750d853b42d71eb29853744de68b339c0da
Author: Julien Y. Dutheil <dutheil at evolbio.mpg.de>
Date:   Mon Feb 5 20:55:40 2018 +0100

    New upstream version 2.3.2
---
 CTestConfig.cmake                                  |    1 +
 Doxyfile                                           |  477 +++-----
 src/Bpp/Phyl/App/PhylogeneticsApplicationTools.cpp |  146 ++-
 src/Bpp/Phyl/App/PhylogeneticsApplicationTools.h   |   12 +
 src/Bpp/Phyl/Distance/DistanceEstimation.h         |  119 +-
 src/Bpp/Phyl/Io/BppOFrequenciesSetFormat.cpp       |   12 +-
 src/Bpp/Phyl/Io/BppOSubstitutionModelFormat.cpp    |  416 +++++--
 src/Bpp/Phyl/Io/BppOSubstitutionModelFormat.h      |    6 +-
 src/Bpp/Phyl/Io/BppOTransitionModelFormat.cpp      |   48 +-
 .../AbstractHomogeneousTreeLikelihood.cpp          |    4 +-
 .../Likelihood/AbstractHomogeneousTreeLikelihood.h |   29 +-
 .../AbstractNonHomogeneousTreeLikelihood.h         |    4 +-
 src/Bpp/Phyl/Likelihood/AbstractTreeLikelihood.h   |   13 +-
 .../Phyl/Likelihood/DRHomogeneousTreeLikelihood.h  |    2 +-
 .../DiscreteRatesAcrossSitesTreeLikelihood.h       |  324 +++---
 .../Phyl/Likelihood/HomogeneousTreeLikelihood.h    |  104 +-
 .../MarginalAncestralStateReconstruction.cpp       |    4 +-
 .../Phyl/Likelihood/NonHomogeneousTreeLikelihood.h |   85 +-
 .../Phyl/Likelihood/SitePartitionTreeLikelihood.h  |   12 +-
 src/Bpp/Phyl/Likelihood/TreeLikelihood.h           |    5 +-
 .../Phyl/Mapping/CategorySubstitutionRegister.h    |   27 +-
 src/Bpp/Phyl/Mapping/DecompositionMethods.cpp      |  300 +++++
 src/Bpp/Phyl/Mapping/DecompositionMethods.h        |  174 +++
 src/Bpp/Phyl/Mapping/DecompositionReward.cpp       |  112 +-
 src/Bpp/Phyl/Mapping/DecompositionReward.h         |  178 ++-
 .../Mapping/DecompositionSubstitutionCount.cpp     |  163 +--
 .../Phyl/Mapping/DecompositionSubstitutionCount.h  |   47 +-
 src/Bpp/Phyl/Mapping/RewardMappingTools.cpp        |    3 +-
 src/Bpp/Phyl/Mapping/SubstitutionMappingTools.cpp  |  718 ++++++++++--
 src/Bpp/Phyl/Mapping/SubstitutionMappingTools.h    | 1217 +++++++++++++-------
 src/Bpp/Phyl/Mapping/SubstitutionRegister.h        |  411 +++++--
 .../Mapping/UniformizationSubstitutionCount.cpp    |    2 +-
 .../Model/AbstractBiblioMixedSubstitutionModel.cpp |   13 +-
 .../Model/AbstractBiblioMixedSubstitutionModel.h   |  309 ++---
 .../Phyl/Model/AbstractBiblioSubstitutionModel.cpp |   18 +-
 .../Phyl/Model/AbstractBiblioSubstitutionModel.h   |   95 +-
 ...bstractFromSubstitutionModelTransitionModel.cpp |    6 +-
 .../AbstractFromSubstitutionModelTransitionModel.h |  113 +-
 .../AbstractKroneckerWordSubstitutionModel.cpp     |   33 +-
 src/Bpp/Phyl/Model/AbstractSubstitutionModel.cpp   |  294 ++++-
 src/Bpp/Phyl/Model/AbstractSubstitutionModel.h     |  733 ++++++------
 .../Phyl/Model/AbstractWordSubstitutionModel.cpp   |  272 +----
 src/Bpp/Phyl/Model/AbstractWrappedModel.h          |  289 +++++
 ...itutionModel.h => AnonymousSubstitutionModel.h} |   78 +-
 ...=> AbstractCodonAAFitnessSubstitutionModel.cpp} |   37 +-
 ...h => AbstractCodonAAFitnessSubstitutionModel.h} |   75 +-
 ...pp => AbstractCodonAARateSubstitutionModel.cpp} |   41 +-
 .../Codon/AbstractCodonAARateSubstitutionModel.h   |  162 +++
 ...l.cpp => AbstractCodonBGCSubstitutionModel.cpp} |   54 +-
 .../Codon/AbstractCodonBGCSubstitutionModel.h      |  138 +++
 .../Codon/AbstractCodonCpGSubstitutionModel.cpp    |    3 +-
 .../Codon/AbstractCodonCpGSubstitutionModel.h      |  155 +--
 .../AbstractCodonDistanceSubstitutionModel.cpp     |    9 +-
 .../Codon/AbstractCodonDistanceSubstitutionModel.h |  180 +--
 .../AbstractCodonFitnessSubstitutionModel.cpp      |   10 +-
 .../Codon/AbstractCodonFitnessSubstitutionModel.h  |   28 +-
 .../AbstractCodonFrequenciesSubstitutionModel.cpp  |    3 +-
 .../AbstractCodonFrequenciesSubstitutionModel.h    |  171 +--
 ...tractCodonPhaseFrequenciesSubstitutionModel.cpp |    7 +-
 ...bstractCodonPhaseFrequenciesSubstitutionModel.h |  160 +--
 .../Model/Codon/AbstractCodonSubstitutionModel.cpp |    1 +
 .../Model/Codon/AbstractCodonSubstitutionModel.h   |    1 +
 .../Model/Codon/CodonAdHocSubstitutionModel.cpp    |  172 +++
 ...tutionModel.h => CodonAdHocSubstitutionModel.h} |  104 +-
 .../Codon/CodonDistanceCpGSubstitutionModel.cpp    |   93 --
 .../CodonDistanceFrequenciesSubstitutionModel.cpp  |   10 +-
 .../CodonDistanceFrequenciesSubstitutionModel.h    |    4 +
 ...onDistancePhaseFrequenciesSubstitutionModel.cpp |   12 +-
 ...odonDistancePhaseFrequenciesSubstitutionModel.h |    7 +
 .../Model/Codon/CodonDistanceSubstitutionModel.cpp |    6 +-
 .../Model/Codon/CodonDistanceSubstitutionModel.h   |    2 +-
 .../CodonRateFrequenciesSubstitutionModel.cpp      |  100 --
 .../Codon/CodonRateFrequenciesSubstitutionModel.h  |  124 --
 .../Phyl/Model/Codon/CodonRateSubstitutionModel.h  |  107 --
 src/Bpp/Phyl/Model/Codon/CodonSubstitutionModel.h  |   34 +-
 src/Bpp/Phyl/Model/Codon/GY94.h                    |  101 +-
 src/Bpp/Phyl/Model/Codon/KCM.h                     |   11 +-
 ...erCodonDistanceFrequenciesSubstitutionModel.cpp |   12 +-
 ...ckerCodonDistanceFrequenciesSubstitutionModel.h |    5 +
 .../KroneckerCodonDistanceSubstitutionModel.cpp    |   12 +-
 src/Bpp/Phyl/Model/Codon/MG94.h                    |  100 +-
 src/Bpp/Phyl/Model/Codon/SENCA.cpp                 |   30 +-
 src/Bpp/Phyl/Model/Codon/SENCA.h                   |   29 +-
 .../Phyl/Model/Codon/TripletSubstitutionModel.h    |   10 +-
 src/Bpp/Phyl/Model/Codon/YN98.cpp                  |    2 +
 src/Bpp/Phyl/Model/Codon/YN98.h                    |  100 +-
 .../Codon/{CodonSubstitutionModel.h => YNGP_M.h}   |  118 +-
 src/Bpp/Phyl/Model/Codon/YNGP_M1.cpp               |   26 +-
 src/Bpp/Phyl/Model/Codon/YNGP_M1.h                 |  136 +--
 src/Bpp/Phyl/Model/Codon/YNGP_M10.cpp              |   31 +-
 src/Bpp/Phyl/Model/Codon/YNGP_M10.h                |  160 ++-
 src/Bpp/Phyl/Model/Codon/YNGP_M2.cpp               |   25 +-
 src/Bpp/Phyl/Model/Codon/YNGP_M2.h                 |  119 +-
 src/Bpp/Phyl/Model/Codon/YNGP_M3.cpp               |   25 +-
 src/Bpp/Phyl/Model/Codon/YNGP_M3.h                 |  122 +-
 src/Bpp/Phyl/Model/Codon/YNGP_M7.cpp               |   25 +-
 src/Bpp/Phyl/Model/Codon/YNGP_M7.h                 |  132 +--
 src/Bpp/Phyl/Model/Codon/YNGP_M8.cpp               |   25 +-
 src/Bpp/Phyl/Model/Codon/YNGP_M8.h                 |  133 +--
 src/Bpp/Phyl/Model/Codon/YNGP_M9.cpp               |   31 +-
 src/Bpp/Phyl/Model/Codon/YNGP_M9.h                 |  166 ++-
 .../Model/FrequenciesSet/CodonFrequenciesSet.cpp   |   36 +-
 .../Model/FrequenciesSet/CodonFrequenciesSet.h     |   12 +-
 src/Bpp/Phyl/Model/FrequenciesSet/FrequenciesSet.h |    4 +-
 .../Model/FrequenciesSet/WordFrequenciesSet.cpp    |   63 +-
 .../Phyl/Model/FrequenciesSet/WordFrequenciesSet.h |   11 +-
 .../Phyl/Model/FromMixtureSubstitutionModel.cpp    |   27 +-
 src/Bpp/Phyl/Model/FromMixtureSubstitutionModel.h  |  308 ++---
 ...utionModel.cpp => InMixedSubstitutionModel.cpp} |   54 +-
 src/Bpp/Phyl/Model/InMixedSubstitutionModel.h      |  314 +++++
 .../Model/MarkovModulatedSubstitutionModel.cpp     |   18 +
 .../Phyl/Model/MarkovModulatedSubstitutionModel.h  |   56 +-
 src/Bpp/Phyl/Model/MixedSubstitutionModel.h        |    2 +-
 src/Bpp/Phyl/Model/MixedSubstitutionModelSet.cpp   |   12 +-
 src/Bpp/Phyl/Model/MixedSubstitutionModelSet.h     |   39 +-
 src/Bpp/Phyl/Model/MixtureOfASubstitutionModel.cpp |    2 +-
 src/Bpp/Phyl/Model/MixtureOfASubstitutionModel.h   |    2 +-
 src/Bpp/Phyl/Model/MixtureOfSubstitutionModels.cpp |    2 +-
 src/Bpp/Phyl/Model/MixtureOfSubstitutionModels.h   |    2 +-
 src/Bpp/Phyl/Model/Nucleotide/L95.cpp              |    1 +
 src/Bpp/Phyl/Model/Nucleotide/RN95.cpp             |    1 +
 src/Bpp/Phyl/Model/Nucleotide/RN95s.cpp            |    1 +
 src/Bpp/Phyl/Model/Nucleotide/YpR.cpp              |    3 +
 src/Bpp/Phyl/Model/Nucleotide/gBGC.cpp             |    3 +
 src/Bpp/Phyl/Model/Nucleotide/gBGC.h               |    4 +-
 .../Model/OneChangeRegisterTransitionModel.cpp     |  422 +++++++
 .../Phyl/Model/OneChangeRegisterTransitionModel.h  |  215 ++++
 src/Bpp/Phyl/Model/OneChangeTransitionModel.cpp    |   22 +-
 src/Bpp/Phyl/Model/OneChangeTransitionModel.h      |   39 +-
 src/Bpp/Phyl/Model/Protein/DSO78.h                 |    6 +
 src/Bpp/Phyl/Model/Protein/JCprot.cpp              |  213 ++--
 src/Bpp/Phyl/Model/Protein/JCprot.h                |   18 +-
 src/Bpp/Phyl/Model/Protein/JTT92.h                 |   75 +-
 src/Bpp/Phyl/Model/Protein/LG08.h                  |    6 +
 src/Bpp/Phyl/Model/Protein/LG10_EX_EHO.cpp         |   20 +-
 src/Bpp/Phyl/Model/Protein/LG10_EX_EHO.h           |  146 ++-
 src/Bpp/Phyl/Model/Protein/LGL08_CAT.cpp           |   19 +-
 src/Bpp/Phyl/Model/Protein/LGL08_CAT.h             |  152 ++-
 src/Bpp/Phyl/Model/Protein/LLG08_EHO.cpp           |   18 +-
 src/Bpp/Phyl/Model/Protein/LLG08_EHO.h             |  155 ++-
 src/Bpp/Phyl/Model/Protein/LLG08_EX2.cpp           |   19 +-
 src/Bpp/Phyl/Model/Protein/LLG08_EX2.h             |  152 ++-
 src/Bpp/Phyl/Model/Protein/LLG08_EX3.cpp           |   19 +-
 src/Bpp/Phyl/Model/Protein/LLG08_EX3.h             |  153 ++-
 src/Bpp/Phyl/Model/Protein/LLG08_UL2.cpp           |   19 +-
 src/Bpp/Phyl/Model/Protein/LLG08_UL2.h             |  154 ++-
 src/Bpp/Phyl/Model/Protein/LLG08_UL3.cpp           |   18 +-
 src/Bpp/Phyl/Model/Protein/LLG08_UL3.h             |  153 ++-
 .../Model/Protein/UserProteinSubstitutionModel.h   |    7 +
 src/Bpp/Phyl/Model/Protein/WAG01.h                 |    6 +
 src/Bpp/Phyl/Model/RE08.h                          |    4 +
 .../Phyl/Model/RegisterRatesSubstitutionModel.cpp  |  113 ++
 .../Phyl/Model/RegisterRatesSubstitutionModel.h    |  268 +++++
 src/Bpp/Phyl/Model/SubstitutionModel.h             |   47 +-
 src/Bpp/Phyl/Model/SubstitutionModelSet.cpp        |    2 +-
 src/Bpp/Phyl/Model/SubstitutionModelSet.h          |   51 +-
 src/Bpp/Phyl/Model/WordSubstitutionModel.cpp       |   13 +-
 src/Bpp/Phyl/Model/WordSubstitutionModel.h         |    1 +
 .../WrappedModel.h}                                |   74 +-
 src/Bpp/Phyl/OptimizationTools.cpp                 |    6 +-
 .../Phyl/Simulation/HomogeneousSequenceSimulator.h |    2 +-
 src/Bpp/Phyl/Simulation/MutationProcess.cpp        |   33 +-
 src/CMakeLists.txt                                 |   11 +-
 test/CMakeLists.txt                                |    3 +
 test/test_likelihood_clock.cpp                     |   20 +-
 test/test_mapping.cpp                              |  103 +-
 test/test_mapping_codon.cpp                        |    7 +-
 test/test_models.cpp                               |    1 +
 168 files changed, 9197 insertions(+), 5889 deletions(-)

diff --git a/CTestConfig.cmake b/CTestConfig.cmake
index ab6df4d..5c3816f 100644
--- a/CTestConfig.cmake
+++ b/CTestConfig.cmake
@@ -11,3 +11,4 @@ set(CTEST_DROP_METHOD "http")
 set(CTEST_DROP_SITE "biopp.univ-montp2.fr")
 set(CTEST_DROP_LOCATION "/dashboard/submit.php?project=bpp-phyl")
 set(CTEST_DROP_SITE_CDASH TRUE)
+
diff --git a/Doxyfile b/Doxyfile
index a99cf18..c884095 100644
--- a/Doxyfile
+++ b/Doxyfile
@@ -1,4 +1,4 @@
-# Doxyfile 1.8.11
+# Doxyfile 1.8.7
 
 # This file describes the settings to be used by the documentation system
 # doxygen (www.doxygen.org) for a project.
@@ -44,23 +44,23 @@ PROJECT_NUMBER         = 2.3.0
 # for a project that appears at the top of each page and should give viewer a
 # quick idea about the purpose of the project. Keep the description short.
 
-PROJECT_BRIEF          = 
+PROJECT_BRIEF          =
 
-# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
-# in the documentation. The maximum height of the logo should not exceed 55
-# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
-# the logo to the output directory.
+# With the PROJECT_LOGO tag one can specify an logo or icon that is included in
+# the documentation. The maximum height of the logo should not exceed 55 pixels
+# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo
+# to the output directory.
 
-PROJECT_LOGO           = 
+PROJECT_LOGO           =
 
 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
 # into which the generated documentation will be written. If a relative path is
 # entered, it will be relative to the location where doxygen was started. If
 # left blank the current directory will be used.
 
-OUTPUT_DIRECTORY       = 
+OUTPUT_DIRECTORY       =
 
-# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub-
 # directories (in 2 levels) under the output directory of each output format and
 # will distribute the generated files over these directories. Enabling this
 # option can be useful when feeding doxygen a huge amount of source files, where
@@ -93,14 +93,14 @@ ALLOW_UNICODE_NAMES    = NO
 
 OUTPUT_LANGUAGE        = English
 
-# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
+# If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member
 # descriptions after the members that are listed in the file and class
 # documentation (similar to Javadoc). Set to NO to disable this.
 # The default value is: YES.
 
 BRIEF_MEMBER_DESC      = YES
 
-# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief
+# If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief
 # description of a member or function before the detailed description
 #
 # Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
@@ -118,7 +118,7 @@ REPEAT_BRIEF           = YES
 # the entity):The $name class, The $name widget, The $name file, is, provides,
 # specifies, contains, represents, a, an and the.
 
-ABBREVIATE_BRIEF       = 
+ABBREVIATE_BRIEF       =
 
 # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
 # doxygen will generate a detailed section even if there is only a brief
@@ -135,7 +135,7 @@ ALWAYS_DETAILED_SEC    = NO
 
 INLINE_INHERITED_MEMB  = YES
 
-# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
+# If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path
 # before files name in the file list and in the header files. If set to NO the
 # shortest path that makes the file name unique will be used
 # The default value is: YES.
@@ -205,9 +205,9 @@ MULTILINE_CPP_IS_BRIEF = NO
 
 INHERIT_DOCS           = YES
 
-# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new
-# page for each member. If set to NO, the documentation of a member will be part
-# of the file/class/namespace that contains it.
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a
+# new page for each member. If set to NO, the documentation of a member will be
+# part of the file/class/namespace that contains it.
 # The default value is: NO.
 
 SEPARATE_MEMBER_PAGES  = NO
@@ -228,13 +228,13 @@ TAB_SIZE               = 2
 # "Side Effects:". You can put \n's in the value part of an alias to insert
 # newlines.
 
-ALIASES                = 
+ALIASES                =
 
 # This tag can be used to specify a number of word-keyword mappings (TCL only).
 # A mapping has the form "name=value". For example adding "class=itcl::class"
 # will allow you to use the command class in the itcl::class meaning.
 
-TCL_SUBST              = 
+TCL_SUBST              =
 
 # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
 # only. Doxygen will then generate output that is more tailored for C. For
@@ -276,12 +276,12 @@ OPTIMIZE_OUTPUT_VHDL   = NO
 # instance to make doxygen treat .inc files as Fortran files (default is PHP),
 # and .f files as C (default is Fortran), use: inc=Fortran f=C.
 #
-# Note: For files without extension you can use no_extension as a placeholder.
+# Note For files without extension you can use no_extension as a placeholder.
 #
 # Note that for custom extensions you also need to set FILE_PATTERNS otherwise
 # the files are not read by doxygen.
 
-EXTENSION_MAPPING      = 
+EXTENSION_MAPPING      =
 
 # If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
 # according to the Markdown format, which allows for more readable
@@ -295,8 +295,8 @@ MARKDOWN_SUPPORT       = YES
 
 # When enabled doxygen tries to link words that correspond to documented
 # classes, or namespaces to their corresponding documentation. Such a link can
-# be prevented in individual cases by putting a % sign in front of the word or
-# globally by setting AUTOLINK_SUPPORT to NO.
+# be prevented in individual cases by by putting a % sign in front of the word
+# or globally by setting AUTOLINK_SUPPORT to NO.
 # The default value is: YES.
 
 AUTOLINK_SUPPORT       = YES
@@ -336,20 +336,13 @@ SIP_SUPPORT            = NO
 IDL_PROPERTY_SUPPORT   = YES
 
 # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
-# tag is set to YES then doxygen will reuse the documentation of the first
+# tag is set to YES, then doxygen will reuse the documentation of the first
 # member in the group (if any) for the other members of the group. By default
 # all members of a group must be documented explicitly.
 # The default value is: NO.
 
 DISTRIBUTE_GROUP_DOC   = NO
 
-# If one adds a struct or class to a group and this option is enabled, then also
-# any nested class or struct is added to the same group. By default this option
-# is disabled and one has to add nested compounds explicitly via \ingroup.
-# The default value is: NO.
-
-GROUP_NESTED_COMPOUNDS = NO
-
 # Set the SUBGROUPING tag to YES to allow class member groups of the same type
 # (for instance a group of public functions) to be put as a subgroup of that
 # type (e.g. under the Public Functions section). Set it to NO to prevent
@@ -408,7 +401,7 @@ LOOKUP_CACHE_SIZE      = 0
 # Build related configuration options
 #---------------------------------------------------------------------------
 
-# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
 # documentation are documented, even if no documentation was available. Private
 # class members and static file members will be hidden unless the
 # EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
@@ -418,35 +411,35 @@ LOOKUP_CACHE_SIZE      = 0
 
 EXTRACT_ALL            = YES
 
-# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will
 # be included in the documentation.
 # The default value is: NO.
 
 EXTRACT_PRIVATE        = YES
 
-# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
+# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal
 # scope will be included in the documentation.
 # The default value is: NO.
 
 EXTRACT_PACKAGE        = NO
 
-# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
+# If the EXTRACT_STATIC tag is set to YES all static members of a file will be
 # included in the documentation.
 # The default value is: NO.
 
 EXTRACT_STATIC         = YES
 
-# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
-# locally in source files will be included in the documentation. If set to NO,
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined
+# locally in source files will be included in the documentation. If set to NO
 # only classes defined in header files are included. Does not have any effect
 # for Java sources.
 # The default value is: YES.
 
 EXTRACT_LOCAL_CLASSES  = YES
 
-# This flag is only useful for Objective-C code. If set to YES, local methods,
+# This flag is only useful for Objective-C code. When set to YES local methods,
 # which are defined in the implementation section but not in the interface are
-# included in the documentation. If set to NO, only methods in the interface are
+# included in the documentation. If set to NO only methods in the interface are
 # included.
 # The default value is: NO.
 
@@ -471,21 +464,21 @@ HIDE_UNDOC_MEMBERS     = NO
 
 # If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
 # undocumented classes that are normally visible in the class hierarchy. If set
-# to NO, these classes will be included in the various overviews. This option
-# has no effect if EXTRACT_ALL is enabled.
+# to NO these classes will be included in the various overviews. This option has
+# no effect if EXTRACT_ALL is enabled.
 # The default value is: NO.
 
 HIDE_UNDOC_CLASSES     = NO
 
 # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
-# (class|struct|union) declarations. If set to NO, these declarations will be
+# (class|struct|union) declarations. If set to NO these declarations will be
 # included in the documentation.
 # The default value is: NO.
 
 HIDE_FRIEND_COMPOUNDS  = NO
 
 # If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
-# documentation blocks found inside the body of a function. If set to NO, these
+# documentation blocks found inside the body of a function. If set to NO these
 # blocks will be appended to the function's detailed documentation block.
 # The default value is: NO.
 
@@ -499,7 +492,7 @@ HIDE_IN_BODY_DOCS      = NO
 INTERNAL_DOCS          = NO
 
 # If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
-# names in lower-case letters. If set to YES, upper-case letters are also
+# names in lower-case letters. If set to YES upper-case letters are also
 # allowed. This is useful if you have classes or files whose names only differ
 # in case and if your file system supports case sensitive file names. Windows
 # and Mac users are advised to set this option to NO.
@@ -508,19 +501,12 @@ INTERNAL_DOCS          = NO
 CASE_SENSE_NAMES       = YES
 
 # If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
-# their full class and namespace scopes in the documentation. If set to YES, the
+# their full class and namespace scopes in the documentation. If set to YES the
 # scope will be hidden.
 # The default value is: NO.
 
 HIDE_SCOPE_NAMES       = NO
 
-# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
-# append additional text to a page's title, such as Class Reference. If set to
-# YES the compound reference will be hidden.
-# The default value is: NO.
-
-HIDE_COMPOUND_REFERENCE= NO
-
 # If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
 # the files that are included by a file in the documentation of that file.
 # The default value is: YES.
@@ -548,14 +534,14 @@ INLINE_INFO            = YES
 
 # If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
 # (detailed) documentation of file and class members alphabetically by member
-# name. If set to NO, the members will appear in declaration order.
+# name. If set to NO the members will appear in declaration order.
 # The default value is: YES.
 
 SORT_MEMBER_DOCS       = YES
 
 # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
 # descriptions of file, namespace and class members alphabetically by member
-# name. If set to NO, the members will appear in declaration order. Note that
+# name. If set to NO the members will appear in declaration order. Note that
 # this will also influence the order of the classes in the class list.
 # The default value is: NO.
 
@@ -600,25 +586,27 @@ SORT_BY_SCOPE_NAME     = NO
 
 STRICT_PROTO_MATCHING  = NO
 
-# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo
-# list. This list is created by putting \todo commands in the documentation.
+# The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the
+# todo list. This list is created by putting \todo commands in the
+# documentation.
 # The default value is: YES.
 
 GENERATE_TODOLIST      = NO
 
-# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test
-# list. This list is created by putting \test commands in the documentation.
+# The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the
+# test list. This list is created by putting \test commands in the
+# documentation.
 # The default value is: YES.
 
 GENERATE_TESTLIST      = NO
 
-# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug
+# The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug
 # list. This list is created by putting \bug commands in the documentation.
 # The default value is: YES.
 
 GENERATE_BUGLIST       = NO
 
-# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)
+# The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO)
 # the deprecated list. This list is created by putting \deprecated commands in
 # the documentation.
 # The default value is: YES.
@@ -629,7 +617,7 @@ GENERATE_DEPRECATEDLIST= YES
 # sections, marked by \if <section_label> ... \endif and \cond <section_label>
 # ... \endcond blocks.
 
-ENABLED_SECTIONS       = 
+ENABLED_SECTIONS       =
 
 # The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
 # initial value of a variable or macro / define can have for it to appear in the
@@ -643,8 +631,8 @@ ENABLED_SECTIONS       =
 MAX_INITIALIZER_LINES  = 30
 
 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
-# the bottom of the documentation of classes and structs. If set to YES, the
-# list will mention the files that were used to generate the documentation.
+# the bottom of the documentation of classes and structs. If set to YES the list
+# will mention the files that were used to generate the documentation.
 # The default value is: YES.
 
 SHOW_USED_FILES        = YES
@@ -671,7 +659,7 @@ SHOW_NAMESPACES        = YES
 # by doxygen. Whatever the program writes to standard output is used as the file
 # version. For an example see the documentation.
 
-FILE_VERSION_FILTER    = 
+FILE_VERSION_FILTER    =
 
 # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
 # by doxygen. The layout file controls the global structure of the generated
@@ -684,7 +672,7 @@ FILE_VERSION_FILTER    =
 # DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
 # tag is left empty.
 
-LAYOUT_FILE            = 
+LAYOUT_FILE            =
 
 # The CITE_BIB_FILES tag can be used to specify one or more bib files containing
 # the reference definitions. This must be a list of .bib files. The .bib
@@ -692,9 +680,10 @@ LAYOUT_FILE            =
 # to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
 # For LaTeX the style of the bibliography can be controlled using
 # LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
-# search path. See also \cite for info how to create references.
+# search path. Do not use file names with spaces, bibtex cannot handle them. See
+# also \cite for info how to create references.
 
-CITE_BIB_FILES         = 
+CITE_BIB_FILES         =
 
 #---------------------------------------------------------------------------
 # Configuration options related to warning and progress messages
@@ -708,7 +697,7 @@ CITE_BIB_FILES         =
 QUIET                  = NO
 
 # The WARNINGS tag can be used to turn on/off the warning messages that are
-# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
+# generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES
 # this implies that the warnings are on.
 #
 # Tip: Turn warnings on while writing the documentation.
@@ -716,7 +705,7 @@ QUIET                  = NO
 
 WARNINGS               = YES
 
-# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
+# If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate
 # warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
 # will automatically be disabled.
 # The default value is: YES.
@@ -733,18 +722,12 @@ WARN_IF_DOC_ERROR      = YES
 
 # This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
 # are documented, but have no documentation for their parameters or return
-# value. If set to NO, doxygen will only warn about wrong or incomplete
-# parameter documentation, but not about the absence of documentation.
+# value. If set to NO doxygen will only warn about wrong or incomplete parameter
+# documentation, but not about the absence of documentation.
 # The default value is: NO.
 
 WARN_NO_PARAMDOC       = NO
 
-# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
-# a warning is encountered.
-# The default value is: NO.
-
-WARN_AS_ERROR          = NO
-
 # The WARN_FORMAT tag determines the format of the warning messages that doxygen
 # can produce. The string should contain the $file, $line, and $text tags, which
 # will be replaced by the file and line number from which the warning originated
@@ -759,7 +742,7 @@ WARN_FORMAT            = "$file:$line: $text"
 # messages should be written. If left blank the output is written to standard
 # error (stderr).
 
-WARN_LOGFILE           = 
+WARN_LOGFILE           =
 
 #---------------------------------------------------------------------------
 # Configuration options related to the input files
@@ -768,7 +751,7 @@ WARN_LOGFILE           =
 # The INPUT tag is used to specify the files and/or directories that contain
 # documented source files. You may enter file names like myfile.cpp or
 # directories like /usr/src/myproject. Separate the files or directories with
-# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
+# spaces.
 # Note: If this tag is empty the current directory is searched.
 
 INPUT                  = src
@@ -784,17 +767,12 @@ INPUT_ENCODING         = UTF-8
 
 # If the value of the INPUT tag contains directories, you can use the
 # FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
-# *.h) to filter out the source-files in the directories.
-#
-# Note that for custom extensions or not directly supported extensions you also
-# need to set EXTENSION_MAPPING for the extension otherwise the files are not
-# read by doxygen.
-#
-# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
-# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
-# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
-# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f, *.for, *.tcl,
-# *.vhd, *.vhdl, *.ucf, *.qsf, *.as and *.js.
+# *.h) to filter out the source-files in the directories. If left blank the
+# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii,
+# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp,
+# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown,
+# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf,
+# *.qsf, *.as and *.js.
 
 FILE_PATTERNS          = *.h \
                          *.cpp
@@ -812,7 +790,7 @@ RECURSIVE              = YES
 # Note that relative paths are relative to the directory from which doxygen is
 # run.
 
-EXCLUDE                = 
+EXCLUDE                =
 
 # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
 # directories that are symbolic links (a Unix file system feature) are excluded
@@ -828,7 +806,7 @@ EXCLUDE_SYMLINKS       = NO
 # Note that the wildcards are matched against the file with absolute path, so to
 # exclude all test directories for example use the pattern */test/*
 
-EXCLUDE_PATTERNS       = 
+EXCLUDE_PATTERNS       =
 
 # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
 # (namespaces, classes, functions, etc.) that should be excluded from the
@@ -839,20 +817,20 @@ EXCLUDE_PATTERNS       =
 # Note that the wildcards are matched against the file with absolute path, so to
 # exclude all test directories use the pattern */test/*
 
-EXCLUDE_SYMBOLS        = 
+EXCLUDE_SYMBOLS        =
 
 # The EXAMPLE_PATH tag can be used to specify one or more files or directories
 # that contain example code fragments that are included (see the \include
 # command).
 
-EXAMPLE_PATH           = 
+EXAMPLE_PATH           =
 
 # If the value of the EXAMPLE_PATH tag contains directories, you can use the
 # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
 # *.h) to filter out the source-files in the directories. If left blank all
 # files are included.
 
-EXAMPLE_PATTERNS       = 
+EXAMPLE_PATTERNS       =
 
 # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
 # searched for input files to be used with the \include or \dontinclude commands
@@ -865,7 +843,7 @@ EXAMPLE_RECURSIVE      = NO
 # that contain images that are to be included in the documentation (see the
 # \image command).
 
-IMAGE_PATH             = 
+IMAGE_PATH             =
 
 # The INPUT_FILTER tag can be used to specify a program that doxygen should
 # invoke to filter for each input file. Doxygen will invoke the filter program
@@ -881,12 +859,8 @@ IMAGE_PATH             =
 # Note that the filter must not add or remove lines; it is applied before the
 # code is scanned, but not when the output code is generated. If lines are added
 # or removed, the anchors will not be placed correctly.
-#
-# Note that for custom extensions or not directly supported extensions you also
-# need to set EXTENSION_MAPPING for the extension otherwise the files are not
-# properly processed by doxygen.
 
-INPUT_FILTER           = 
+INPUT_FILTER           =
 
 # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
 # basis. Doxygen will compare the file name with each pattern and apply the
@@ -894,15 +868,11 @@ INPUT_FILTER           =
 # (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
 # filters are used. If the FILTER_PATTERNS tag is empty or if none of the
 # patterns match the file name, INPUT_FILTER is applied.
-#
-# Note that for custom extensions or not directly supported extensions you also
-# need to set EXTENSION_MAPPING for the extension otherwise the files are not
-# properly processed by doxygen.
 
-FILTER_PATTERNS        = 
+FILTER_PATTERNS        =
 
 # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
-# INPUT_FILTER) will also be used to filter the input files that are used for
+# INPUT_FILTER ) will also be used to filter the input files that are used for
 # producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
 # The default value is: NO.
 
@@ -914,14 +884,14 @@ FILTER_SOURCE_FILES    = NO
 # *.ext= (so without naming a filter).
 # This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
 
-FILTER_SOURCE_PATTERNS = 
+FILTER_SOURCE_PATTERNS =
 
 # If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
 # is part of the input, its contents will be placed on the main page
 # (index.html). This can be useful if you have a project on for instance GitHub
 # and want to reuse the introduction page also for the doxygen output.
 
-USE_MDFILE_AS_MAINPAGE = 
+USE_MDFILE_AS_MAINPAGE =
 
 #---------------------------------------------------------------------------
 # Configuration options related to source browsing
@@ -962,7 +932,7 @@ REFERENCED_BY_RELATION = YES
 REFERENCES_RELATION    = YES
 
 # If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
-# to YES then the hyperlinks from functions in REFERENCES_RELATION and
+# to YES, then the hyperlinks from functions in REFERENCES_RELATION and
 # REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
 # link to the documentation.
 # The default value is: YES.
@@ -1009,25 +979,6 @@ USE_HTAGS              = NO
 
 VERBATIM_HEADERS       = YES
 
-# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the
-# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the
-# cost of reduced performance. This can be particularly helpful with template
-# rich C++ code for which doxygen's built-in parser lacks the necessary type
-# information.
-# Note: The availability of this option depends on whether or not doxygen was
-# generated with the -Duse-libclang=ON option for CMake.
-# The default value is: NO.
-
-CLANG_ASSISTED_PARSING = NO
-
-# If clang assisted parsing is enabled you can provide the compiler with command
-# line options that you would normally use when invoking the compiler. Note that
-# the include paths will already be set by doxygen for the files and directories
-# specified with INPUT and INCLUDE_PATH.
-# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
-
-CLANG_OPTIONS          = 
-
 #---------------------------------------------------------------------------
 # Configuration options related to the alphabetical class index
 #---------------------------------------------------------------------------
@@ -1052,13 +1003,13 @@ COLS_IN_ALPHA_INDEX    = 5
 # while generating the index headers.
 # This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
 
-IGNORE_PREFIX          = 
+IGNORE_PREFIX          =
 
 #---------------------------------------------------------------------------
 # Configuration options related to the HTML output
 #---------------------------------------------------------------------------
 
-# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
+# If the GENERATE_HTML tag is set to YES doxygen will generate HTML output
 # The default value is: YES.
 
 GENERATE_HTML          = YES
@@ -1096,7 +1047,7 @@ HTML_FILE_EXTENSION    = .html
 # of the possible markers and block names see the documentation.
 # This tag requires that the tag GENERATE_HTML is set to YES.
 
-HTML_HEADER            = 
+HTML_HEADER            =
 
 # The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
 # generated HTML page. If the tag is left blank doxygen will generate a standard
@@ -1106,7 +1057,7 @@ HTML_HEADER            =
 # that doxygen normally uses.
 # This tag requires that the tag GENERATE_HTML is set to YES.
 
-HTML_FOOTER            = 
+HTML_FOOTER            =
 
 # The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
 # sheet that is used by each HTML page. It can be used to fine-tune the look of
@@ -1118,20 +1069,18 @@ HTML_FOOTER            =
 # obsolete.
 # This tag requires that the tag GENERATE_HTML is set to YES.
 
-HTML_STYLESHEET        = 
+HTML_STYLESHEET        =
 
-# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
-# cascading style sheets that are included after the standard style sheets
+# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user-
+# defined cascading style sheet that is included after the standard style sheets
 # created by doxygen. Using this option one can overrule certain style aspects.
 # This is preferred over using HTML_STYLESHEET since it does not replace the
-# standard style sheet and is therefore more robust against future updates.
-# Doxygen will copy the style sheet files to the output directory.
-# Note: The order of the extra style sheet files is of importance (e.g. the last
-# style sheet in the list overrules the setting of the previous ones in the
-# list). For an example see the documentation.
+# standard style sheet and is therefor more robust against future updates.
+# Doxygen will copy the style sheet file to the output directory. For an example
+# see the documentation.
 # This tag requires that the tag GENERATE_HTML is set to YES.
 
-HTML_EXTRA_STYLESHEET  = 
+HTML_EXTRA_STYLESHEET  =
 
 # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
 # other source files which should be copied to the HTML output directory. Note
@@ -1141,10 +1090,10 @@ HTML_EXTRA_STYLESHEET  =
 # files will be copied as-is; there are no commands or markers available.
 # This tag requires that the tag GENERATE_HTML is set to YES.
 
-HTML_EXTRA_FILES       = 
+HTML_EXTRA_FILES       =
 
 # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
-# will adjust the colors in the style sheet and background images according to
+# will adjust the colors in the stylesheet and background images according to
 # this color. Hue is specified as an angle on a colorwheel, see
 # http://en.wikipedia.org/wiki/Hue for more information. For instance the value
 # 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
@@ -1175,9 +1124,8 @@ HTML_COLORSTYLE_GAMMA  = 80
 
 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
 # page will contain the date and time when the page was generated. Setting this
-# to YES can help to show when doxygen was last run and thus if the
-# documentation is up to date.
-# The default value is: NO.
+# to NO can help when comparing the output of multiple runs.
+# The default value is: YES.
 # This tag requires that the tag GENERATE_HTML is set to YES.
 
 HTML_TIMESTAMP         = YES
@@ -1270,31 +1218,31 @@ GENERATE_HTMLHELP      = NO
 # written to the html output directory.
 # This tag requires that the tag GENERATE_HTMLHELP is set to YES.
 
-CHM_FILE               = 
+CHM_FILE               =
 
 # The HHC_LOCATION tag can be used to specify the location (absolute path
-# including file name) of the HTML help compiler (hhc.exe). If non-empty,
+# including file name) of the HTML help compiler ( hhc.exe). If non-empty
 # doxygen will try to run the HTML help compiler on the generated index.hhp.
 # The file has to be specified with full path.
 # This tag requires that the tag GENERATE_HTMLHELP is set to YES.
 
-HHC_LOCATION           = 
+HHC_LOCATION           =
 
-# The GENERATE_CHI flag controls if a separate .chi index file is generated
-# (YES) or that it should be included in the master .chm file (NO).
+# The GENERATE_CHI flag controls if a separate .chi index file is generated (
+# YES) or that it should be included in the master .chm file ( NO).
 # The default value is: NO.
 # This tag requires that the tag GENERATE_HTMLHELP is set to YES.
 
 GENERATE_CHI           = NO
 
-# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)
+# The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc)
 # and project file content.
 # This tag requires that the tag GENERATE_HTMLHELP is set to YES.
 
-CHM_INDEX_ENCODING     = 
+CHM_INDEX_ENCODING     =
 
-# The BINARY_TOC flag controls whether a binary table of contents is generated
-# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
+# The BINARY_TOC flag controls whether a binary table of contents is generated (
+# YES) or a normal table of contents ( NO) in the .chm file. Furthermore it
 # enables the Previous and Next buttons.
 # The default value is: NO.
 # This tag requires that the tag GENERATE_HTMLHELP is set to YES.
@@ -1322,7 +1270,7 @@ GENERATE_QHP           = NO
 # the HTML output folder.
 # This tag requires that the tag GENERATE_QHP is set to YES.
 
-QCH_FILE               = 
+QCH_FILE               =
 
 # The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
 # Project output. For more information please see Qt Help Project / Namespace
@@ -1347,7 +1295,7 @@ QHP_VIRTUAL_FOLDER     = doc
 # filters).
 # This tag requires that the tag GENERATE_QHP is set to YES.
 
-QHP_CUST_FILTER_NAME   = 
+QHP_CUST_FILTER_NAME   =
 
 # The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
 # custom filter to add. For more information please see Qt Help Project / Custom
@@ -1355,21 +1303,21 @@ QHP_CUST_FILTER_NAME   =
 # filters).
 # This tag requires that the tag GENERATE_QHP is set to YES.
 
-QHP_CUST_FILTER_ATTRS  = 
+QHP_CUST_FILTER_ATTRS  =
 
 # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
 # project's filter section matches. Qt Help Project / Filter Attributes (see:
 # http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
 # This tag requires that the tag GENERATE_QHP is set to YES.
 
-QHP_SECT_FILTER_ATTRS  = 
+QHP_SECT_FILTER_ATTRS  =
 
 # The QHG_LOCATION tag can be used to specify the location of Qt's
 # qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
 # generated .qhp file.
 # This tag requires that the tag GENERATE_QHP is set to YES.
 
-QHG_LOCATION           = 
+QHG_LOCATION           =
 
 # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
 # generated, together with the HTML files, they form an Eclipse help plugin. To
@@ -1408,7 +1356,7 @@ DISABLE_INDEX          = NO
 # index structure (just like the one that is generated for HTML Help). For this
 # to work a browser that supports JavaScript, DHTML, CSS and frames is required
 # (i.e. any modern browser). Windows users are probably better off using the
-# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
+# HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can
 # further fine-tune the look of the index. As an example, the default style
 # sheet generated by doxygen has an example that shows how to put an image at
 # the root of the tree instead of the PROJECT_NAME. Since the tree basically has
@@ -1436,7 +1384,7 @@ ENUM_VALUES_PER_LINE   = 4
 
 TREEVIEW_WIDTH         = 250
 
-# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to
+# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to
 # external symbols imported via tag files in a separate window.
 # The default value is: NO.
 # This tag requires that the tag GENERATE_HTML is set to YES.
@@ -1465,7 +1413,7 @@ FORMULA_TRANSPARENT    = YES
 
 # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
 # http://www.mathjax.org) which uses client side Javascript for the rendering
-# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
+# instead of using prerendered bitmaps. Use this if you do not have LaTeX
 # installed or if you want to formulas look prettier in the HTML output. When
 # enabled you may also need to install MathJax separately and configure the path
 # to it using the MATHJAX_RELPATH option.
@@ -1502,7 +1450,7 @@ MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest
 # MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
 # This tag requires that the tag USE_MATHJAX is set to YES.
 
-MATHJAX_EXTENSIONS     = 
+MATHJAX_EXTENSIONS     =
 
 # The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
 # of code that will be used on startup of the MathJax code. See the MathJax site
@@ -1510,7 +1458,7 @@ MATHJAX_EXTENSIONS     =
 # example see the documentation.
 # This tag requires that the tag USE_MATHJAX is set to YES.
 
-MATHJAX_CODEFILE       = 
+MATHJAX_CODEFILE       =
 
 # When the SEARCHENGINE tag is enabled doxygen will generate a search box for
 # the HTML output. The underlying search engine uses javascript and DHTML and
@@ -1551,7 +1499,7 @@ SERVER_BASED_SEARCH    = NO
 # external search engine pointed to by the SEARCHENGINE_URL option to obtain the
 # search results.
 #
-# Doxygen ships with an example indexer (doxyindexer) and search engine
+# Doxygen ships with an example indexer ( doxyindexer) and search engine
 # (doxysearch.cgi) which are based on the open source search engine library
 # Xapian (see: http://xapian.org/).
 #
@@ -1564,13 +1512,13 @@ EXTERNAL_SEARCH        = NO
 # The SEARCHENGINE_URL should point to a search engine hosted by a web server
 # which will return the search results when EXTERNAL_SEARCH is enabled.
 #
-# Doxygen ships with an example indexer (doxyindexer) and search engine
+# Doxygen ships with an example indexer ( doxyindexer) and search engine
 # (doxysearch.cgi) which are based on the open source search engine library
 # Xapian (see: http://xapian.org/). See the section "External Indexing and
 # Searching" for details.
 # This tag requires that the tag SEARCHENGINE is set to YES.
 
-SEARCHENGINE_URL       = 
+SEARCHENGINE_URL       =
 
 # When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
 # search data is written to a file for indexing by an external tool. With the
@@ -1586,7 +1534,7 @@ SEARCHDATA_FILE        = searchdata.xml
 # projects and redirect the results back to the right project.
 # This tag requires that the tag SEARCHENGINE is set to YES.
 
-EXTERNAL_SEARCH_ID     = 
+EXTERNAL_SEARCH_ID     =
 
 # The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
 # projects other than the one defined by this configuration file, but that are
@@ -1596,13 +1544,13 @@ EXTERNAL_SEARCH_ID     =
 # EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
 # This tag requires that the tag SEARCHENGINE is set to YES.
 
-EXTRA_SEARCH_MAPPINGS  = 
+EXTRA_SEARCH_MAPPINGS  =
 
 #---------------------------------------------------------------------------
 # Configuration options related to the LaTeX output
 #---------------------------------------------------------------------------
 
-# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
+# If the GENERATE_LATEX tag is set to YES doxygen will generate LaTeX output.
 # The default value is: YES.
 
 GENERATE_LATEX         = NO
@@ -1633,7 +1581,7 @@ LATEX_CMD_NAME         = latex
 
 MAKEINDEX_CMD_NAME     = makeindex
 
-# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
+# If the COMPACT_LATEX tag is set to YES doxygen generates more compact LaTeX
 # documents. This may be useful for small projects and may help to save some
 # trees in general.
 # The default value is: NO.
@@ -1651,12 +1599,9 @@ COMPACT_LATEX          = NO
 PAPER_TYPE             = a4wide
 
 # The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
-# that should be included in the LaTeX output. The package can be specified just
-# by its name or with the correct syntax as to be used with the LaTeX
-# \usepackage command. To get the times font for instance you can specify :
-# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times}
-# To use the option intlimits with the amsmath package you can specify:
-# EXTRA_PACKAGES=[intlimits]{amsmath}
+# that should be included in the LaTeX output. To get the times font for
+# instance you can specify
+# EXTRA_PACKAGES=times
 # If left blank no extra packages will be included.
 # This tag requires that the tag GENERATE_LATEX is set to YES.
 
@@ -1670,35 +1615,22 @@ EXTRA_PACKAGES         = amsmath
 #
 # Note: Only use a user-defined header if you know what you are doing! The
 # following commands have a special meaning inside the header: $title,
-# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
-# $projectbrief, $projectlogo. Doxygen will replace $title with the empty
-# string, for the replacement values of the other commands the user is referred
-# to HTML_HEADER.
+# $datetime, $date, $doxygenversion, $projectname, $projectnumber. Doxygen will
+# replace them by respectively the title of the page, the current date and time,
+# only the current date, the version number of doxygen, the project name (see
+# PROJECT_NAME), or the project number (see PROJECT_NUMBER).
 # This tag requires that the tag GENERATE_LATEX is set to YES.
 
-LATEX_HEADER           = 
+LATEX_HEADER           =
 
 # The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
 # generated LaTeX document. The footer should contain everything after the last
-# chapter. If it is left blank doxygen will generate a standard footer. See
-# LATEX_HEADER for more information on how to generate a default footer and what
-# special commands can be used inside the footer.
+# chapter. If it is left blank doxygen will generate a standard footer.
 #
 # Note: Only use a user-defined footer if you know what you are doing!
 # This tag requires that the tag GENERATE_LATEX is set to YES.
 
-LATEX_FOOTER           = 
-
-# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
-# LaTeX style sheets that are included after the standard style sheets created
-# by doxygen. Using this option one can overrule certain style aspects. Doxygen
-# will copy the style sheet files to the output directory.
-# Note: The order of the extra style sheet files is of importance (e.g. the last
-# style sheet in the list overrules the setting of the previous ones in the
-# list).
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_EXTRA_STYLESHEET = 
+LATEX_FOOTER           =
 
 # The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
 # other source files which should be copied to the LATEX_OUTPUT output
@@ -1706,7 +1638,7 @@ LATEX_EXTRA_STYLESHEET =
 # markers available.
 # This tag requires that the tag GENERATE_LATEX is set to YES.
 
-LATEX_EXTRA_FILES      = 
+LATEX_EXTRA_FILES      =
 
 # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
 # prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
@@ -1717,8 +1649,8 @@ LATEX_EXTRA_FILES      =
 
 PDF_HYPERLINKS         = NO
 
-# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
-# the PDF file directly from the LaTeX files. Set this option to YES, to get a
+# If the LATEX_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
+# the PDF file directly from the LaTeX files. Set this option to YES to get a
 # higher quality PDF documentation.
 # The default value is: YES.
 # This tag requires that the tag GENERATE_LATEX is set to YES.
@@ -1759,19 +1691,11 @@ LATEX_SOURCE_CODE      = NO
 
 LATEX_BIB_STYLE        = plain
 
-# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated
-# page will contain the date and time when the page was generated. Setting this
-# to NO can help when comparing the output of multiple runs.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_TIMESTAMP        = NO
-
 #---------------------------------------------------------------------------
 # Configuration options related to the RTF output
 #---------------------------------------------------------------------------
 
-# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The
+# If the GENERATE_RTF tag is set to YES doxygen will generate RTF output. The
 # RTF output is optimized for Word 97 and may not look too pretty with other RTF
 # readers/editors.
 # The default value is: NO.
@@ -1786,7 +1710,7 @@ GENERATE_RTF           = NO
 
 RTF_OUTPUT             = rtf
 
-# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF
+# If the COMPACT_RTF tag is set to YES doxygen generates more compact RTF
 # documents. This may be useful for small projects and may help to save some
 # trees in general.
 # The default value is: NO.
@@ -1814,30 +1738,20 @@ RTF_HYPERLINKS         = NO
 # default style sheet that doxygen normally uses.
 # This tag requires that the tag GENERATE_RTF is set to YES.
 
-RTF_STYLESHEET_FILE    = 
+RTF_STYLESHEET_FILE    =
 
 # Set optional variables used in the generation of an RTF document. Syntax is
 # similar to doxygen's config file. A template extensions file can be generated
 # using doxygen -e rtf extensionFile.
 # This tag requires that the tag GENERATE_RTF is set to YES.
 
-RTF_EXTENSIONS_FILE    = 
-
-# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
-# with syntax highlighting in the RTF output.
-#
-# Note that which sources are shown also depends on other settings such as
-# SOURCE_BROWSER.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_SOURCE_CODE        = NO
+RTF_EXTENSIONS_FILE    =
 
 #---------------------------------------------------------------------------
 # Configuration options related to the man page output
 #---------------------------------------------------------------------------
 
-# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for
+# If the GENERATE_MAN tag is set to YES doxygen will generate man pages for
 # classes and files.
 # The default value is: NO.
 
@@ -1866,7 +1780,7 @@ MAN_EXTENSION          = .3
 # MAN_EXTENSION with the initial . removed.
 # This tag requires that the tag GENERATE_MAN is set to YES.
 
-MAN_SUBDIR             = 
+MAN_SUBDIR             =
 
 # If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
 # will generate one additional man file for each entity documented in the real
@@ -1881,7 +1795,7 @@ MAN_LINKS              = NO
 # Configuration options related to the XML output
 #---------------------------------------------------------------------------
 
-# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that
+# If the GENERATE_XML tag is set to YES doxygen will generate an XML file that
 # captures the structure of the code including all documentation.
 # The default value is: NO.
 
@@ -1895,7 +1809,7 @@ GENERATE_XML           = NO
 
 XML_OUTPUT             = xml
 
-# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program
+# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program
 # listings (including syntax highlighting and cross-referencing information) to
 # the XML output. Note that enabling this will significantly increase the size
 # of the XML output.
@@ -1908,7 +1822,7 @@ XML_PROGRAMLISTING     = YES
 # Configuration options related to the DOCBOOK output
 #---------------------------------------------------------------------------
 
-# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files
+# If the GENERATE_DOCBOOK tag is set to YES doxygen will generate Docbook files
 # that can be used to generate PDF.
 # The default value is: NO.
 
@@ -1922,23 +1836,14 @@ GENERATE_DOCBOOK       = NO
 
 DOCBOOK_OUTPUT         = docbook
 
-# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
-# program listings (including syntax highlighting and cross-referencing
-# information) to the DOCBOOK output. Note that enabling this will significantly
-# increase the size of the DOCBOOK output.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
-
-DOCBOOK_PROGRAMLISTING = NO
-
 #---------------------------------------------------------------------------
 # Configuration options for the AutoGen Definitions output
 #---------------------------------------------------------------------------
 
-# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
-# AutoGen Definitions (see http://autogen.sf.net) file that captures the
-# structure of the code including all documentation. Note that this feature is
-# still experimental and incomplete at the moment.
+# If the GENERATE_AUTOGEN_DEF tag is set to YES doxygen will generate an AutoGen
+# Definitions (see http://autogen.sf.net) file that captures the structure of
+# the code including all documentation. Note that this feature is still
+# experimental and incomplete at the moment.
 # The default value is: NO.
 
 GENERATE_AUTOGEN_DEF   = NO
@@ -1947,7 +1852,7 @@ GENERATE_AUTOGEN_DEF   = NO
 # Configuration options related to the Perl module output
 #---------------------------------------------------------------------------
 
-# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module
+# If the GENERATE_PERLMOD tag is set to YES doxygen will generate a Perl module
 # file that captures the structure of the code including all documentation.
 #
 # Note that this feature is still experimental and incomplete at the moment.
@@ -1955,7 +1860,7 @@ GENERATE_AUTOGEN_DEF   = NO
 
 GENERATE_PERLMOD       = NO
 
-# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary
+# If the PERLMOD_LATEX tag is set to YES doxygen will generate the necessary
 # Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
 # output from the Perl module output.
 # The default value is: NO.
@@ -1963,9 +1868,9 @@ GENERATE_PERLMOD       = NO
 
 PERLMOD_LATEX          = NO
 
-# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be nicely
 # formatted so it can be parsed by a human reader. This is useful if you want to
-# understand what is going on. On the other hand, if this tag is set to NO, the
+# understand what is going on. On the other hand, if this tag is set to NO the
 # size of the Perl module output will be much smaller and Perl will parse it
 # just the same.
 # The default value is: YES.
@@ -1979,20 +1884,20 @@ PERLMOD_PRETTY         = YES
 # overwrite each other's variables.
 # This tag requires that the tag GENERATE_PERLMOD is set to YES.
 
-PERLMOD_MAKEVAR_PREFIX = 
+PERLMOD_MAKEVAR_PREFIX =
 
 #---------------------------------------------------------------------------
 # Configuration options related to the preprocessor
 #---------------------------------------------------------------------------
 
-# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all
+# If the ENABLE_PREPROCESSING tag is set to YES doxygen will evaluate all
 # C-preprocessor directives found in the sources and include files.
 # The default value is: YES.
 
 ENABLE_PREPROCESSING   = YES
 
-# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names
-# in the source code. If set to NO, only conditional compilation will be
+# If the MACRO_EXPANSION tag is set to YES doxygen will expand all macro names
+# in the source code. If set to NO only conditional compilation will be
 # performed. Macro expansion can be done in a controlled way by setting
 # EXPAND_ONLY_PREDEF to YES.
 # The default value is: NO.
@@ -2008,7 +1913,7 @@ MACRO_EXPANSION        = NO
 
 EXPAND_ONLY_PREDEF     = NO
 
-# If the SEARCH_INCLUDES tag is set to YES, the include files in the
+# If the SEARCH_INCLUDES tag is set to YES the includes files in the
 # INCLUDE_PATH will be searched if a #include is found.
 # The default value is: YES.
 # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
@@ -2020,7 +1925,7 @@ SEARCH_INCLUDES        = YES
 # preprocessor.
 # This tag requires that the tag SEARCH_INCLUDES is set to YES.
 
-INCLUDE_PATH           = 
+INCLUDE_PATH           =
 
 # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
 # patterns (like *.h and *.hpp) to filter out the header-files in the
@@ -2028,7 +1933,7 @@ INCLUDE_PATH           =
 # used.
 # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
 
-INCLUDE_FILE_PATTERNS  = 
+INCLUDE_FILE_PATTERNS  =
 
 # The PREDEFINED tag can be used to specify one or more macro names that are
 # defined before the preprocessor is started (similar to the -D option of e.g.
@@ -2038,7 +1943,7 @@ INCLUDE_FILE_PATTERNS  =
 # recursively expanded use the := operator instead of the = operator.
 # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
 
-PREDEFINED             = 
+PREDEFINED             =
 
 # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
 # tag can be used to specify a list of macro names that should be expanded. The
@@ -2047,7 +1952,7 @@ PREDEFINED             =
 # definition found in the source code.
 # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
 
-EXPAND_AS_DEFINED      = 
+EXPAND_AS_DEFINED      =
 
 # If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
 # remove all references to function-like macros that are alone on a line, have
@@ -2085,21 +1990,20 @@ TAGFILES               = ../bpp-core/BppCore.tag=../../bpp-core/html \
 
 GENERATE_TAGFILE       = BppPhyl.tag
 
-# If the ALLEXTERNALS tag is set to YES, all external class will be listed in
-# the class index. If set to NO, only the inherited external classes will be
-# listed.
+# If the ALLEXTERNALS tag is set to YES all external class will be listed in the
+# class index. If set to NO only the inherited external classes will be listed.
 # The default value is: NO.
 
 ALLEXTERNALS           = NO
 
-# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed
-# in the modules index. If set to NO, only the current project's groups will be
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed in
+# the modules index. If set to NO, only the current project's groups will be
 # listed.
 # The default value is: YES.
 
 EXTERNAL_GROUPS        = YES
 
-# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in
+# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed in
 # the related pages index. If set to NO, only the current project's pages will
 # be listed.
 # The default value is: YES.
@@ -2116,7 +2020,7 @@ PERL_PATH              = /usr/bin/perl
 # Configuration options related to the dot tool
 #---------------------------------------------------------------------------
 
-# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
+# If the CLASS_DIAGRAMS tag is set to YES doxygen will generate a class diagram
 # (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
 # NO turns the diagrams off. Note that this option also works with HAVE_DOT
 # disabled, but it is recommended to install and use dot, since it yields more
@@ -2132,16 +2036,16 @@ CLASS_DIAGRAMS         = YES
 # the mscgen tool resides. If left empty the tool is assumed to be found in the
 # default search path.
 
-MSCGEN_PATH            = 
+MSCGEN_PATH            =
 
 # You can include diagrams made with dia in doxygen documentation. Doxygen will
 # then run dia to produce the diagram and insert it in the documentation. The
 # DIA_PATH tag allows you to specify the directory where the dia binary resides.
 # If left empty dia is assumed to be found in the default search path.
 
-DIA_PATH               = 
+DIA_PATH               =
 
-# If set to YES the inheritance and collaboration graphs will hide inheritance
+# If set to YES, the inheritance and collaboration graphs will hide inheritance
 # and usage relations if the target is undocumented or is not a class.
 # The default value is: YES.
 
@@ -2166,7 +2070,7 @@ HAVE_DOT               = YES
 
 DOT_NUM_THREADS        = 0
 
-# When you want a differently looking font in the dot files that doxygen
+# When you want a differently looking font n the dot files that doxygen
 # generates you can specify the font name using DOT_FONTNAME. You need to make
 # sure dot is able to find the font, which can be done by putting it in a
 # standard location or by setting the DOTFONTPATH environment variable or by
@@ -2188,7 +2092,7 @@ DOT_FONTSIZE           = 10
 # the path where dot can find it using this tag.
 # This tag requires that the tag HAVE_DOT is set to YES.
 
-DOT_FONTPATH           = 
+DOT_FONTPATH           =
 
 # If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
 # each documented class showing the direct and indirect inheritance relations.
@@ -2214,7 +2118,7 @@ COLLABORATION_GRAPH    = YES
 
 GROUP_GRAPHS           = YES
 
-# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
 # collaboration diagrams in a style similar to the OMG's Unified Modeling
 # Language.
 # The default value is: NO.
@@ -2266,8 +2170,7 @@ INCLUDED_BY_GRAPH      = YES
 #
 # Note that enabling this option will significantly increase the time of a run.
 # So in most cases it will be better to enable call graphs for selected
-# functions only using the \callgraph command. Disabling a call graph can be
-# accomplished by means of the command \hidecallgraph.
+# functions only using the \callgraph command.
 # The default value is: NO.
 # This tag requires that the tag HAVE_DOT is set to YES.
 
@@ -2278,8 +2181,7 @@ CALL_GRAPH             = NO
 #
 # Note that enabling this option will significantly increase the time of a run.
 # So in most cases it will be better to enable caller graphs for selected
-# functions only using the \callergraph command. Disabling a caller graph can be
-# accomplished by means of the command \hidecallergraph.
+# functions only using the \callergraph command.
 # The default value is: NO.
 # This tag requires that the tag HAVE_DOT is set to YES.
 
@@ -2302,17 +2204,13 @@ GRAPHICAL_HIERARCHY    = YES
 DIRECTORY_GRAPH        = YES
 
 # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
-# generated by dot. For an explanation of the image formats see the section
-# output formats in the documentation of the dot tool (Graphviz (see:
-# http://www.graphviz.org/)).
+# generated by dot.
 # Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
 # to make the SVG files visible in IE 9+ (other browsers do not have this
 # requirement).
 # Possible values are: png, png:cairo, png:cairo:cairo, png:cairo:gd, png:gd,
 # png:gd:gd, jpg, jpg:cairo, jpg:cairo:gd, jpg:gd, jpg:gd:gd, gif, gif:cairo,
-# gif:cairo:gd, gif:gd, gif:gd:gd, svg, png:gd, png:gd:gd, png:cairo,
-# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
-# png:gdiplus:gdiplus.
+# gif:cairo:gd, gif:gd, gif:gd:gd and svg.
 # The default value is: png.
 # This tag requires that the tag HAVE_DOT is set to YES.
 
@@ -2334,39 +2232,26 @@ INTERACTIVE_SVG        = NO
 # found. If left blank, it is assumed the dot tool can be found in the path.
 # This tag requires that the tag HAVE_DOT is set to YES.
 
-DOT_PATH               = 
+DOT_PATH               =
 
 # The DOTFILE_DIRS tag can be used to specify one or more directories that
 # contain dot files that are included in the documentation (see the \dotfile
 # command).
 # This tag requires that the tag HAVE_DOT is set to YES.
 
-DOTFILE_DIRS           = 
+DOTFILE_DIRS           =
 
 # The MSCFILE_DIRS tag can be used to specify one or more directories that
 # contain msc files that are included in the documentation (see the \mscfile
 # command).
 
-MSCFILE_DIRS           = 
+MSCFILE_DIRS           =
 
 # The DIAFILE_DIRS tag can be used to specify one or more directories that
 # contain dia files that are included in the documentation (see the \diafile
 # command).
 
-DIAFILE_DIRS           = 
-
-# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
-# path where java can find the plantuml.jar file. If left blank, it is assumed
-# PlantUML is not used or called during a preprocessing step. Doxygen will
-# generate a warning when it encounters a \startuml command in this case and
-# will not generate output for the diagram.
-
-PLANTUML_JAR_PATH      = 
-
-# When using plantuml, the specified paths are searched for files specified by
-# the !include statement in a plantuml block.
-
-PLANTUML_INCLUDE_PATH  = 
+DIAFILE_DIRS           =
 
 # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
 # that will be shown in the graph. If the number of nodes in a graph becomes
@@ -2404,7 +2289,7 @@ MAX_DOT_GRAPH_DEPTH    = 0
 
 DOT_TRANSPARENT        = NO
 
-# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
 # files in one run (i.e. multiple -o and -T options on the command line). This
 # makes dot run faster, but since only newer versions of dot (>1.8.10) support
 # this, this feature is disabled by default.
@@ -2421,7 +2306,7 @@ DOT_MULTI_TARGETS      = YES
 
 GENERATE_LEGEND        = YES
 
-# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot
+# If the DOT_CLEANUP tag is set to YES doxygen will remove the intermediate dot
 # files that are used to generate the various graphs.
 # The default value is: YES.
 # This tag requires that the tag HAVE_DOT is set to YES.
diff --git a/src/Bpp/Phyl/App/PhylogeneticsApplicationTools.cpp b/src/Bpp/Phyl/App/PhylogeneticsApplicationTools.cpp
index f42aade..71b5ab8 100644
--- a/src/Bpp/Phyl/App/PhylogeneticsApplicationTools.cpp
+++ b/src/Bpp/Phyl/App/PhylogeneticsApplicationTools.cpp
@@ -40,6 +40,7 @@
 
 #include "PhylogeneticsApplicationTools.h"
 #include "../Model/SubstitutionModel.h"
+#include "../Model/WrappedModel.h"
 #include "../Model/Protein/Coala.h"
 #include "../Model/FrequenciesSet/MvaFrequenciesSet.h"
 #include "../Likelihood/TreeLikelihood.h"
@@ -463,6 +464,7 @@ void PhylogeneticsApplicationTools::setSubstitutionModelSet(
 
   unique_ptr<TransitionModel> tmp(bIO.readTransitionModel(alphabet, tmpDesc, data, false));
 
+
   if (tmp->getNumberOfStates() != alphabet->getSize())
   {
     // Markov-Modulated Markov Model...
@@ -526,8 +528,8 @@ void PhylogeneticsApplicationTools::setSubstitutionModelSet(
 
     unparsedParameters.insert(sharedParameters.begin(), sharedParameters.end());
 
-    vector<int> nodesId = ApplicationTools::getVectorParameter<int>(prefix + ".nodes_id", params, ',', ':', TextTools::toString(i), suffix, suffixIsOptional, warn);
-
+    vector<int> nodesId = ApplicationTools::getVectorParameter<int>(prefix + ".nodes_id", params, ',', ':', "", suffix, suffixIsOptional, warn);
+    
     if (verbose)
       ApplicationTools::displayResult("Model" + TextTools::toString(i + 1) + " is associated to", TextTools::toString(nodesId.size()) + " node(s).");
 
@@ -1469,7 +1471,7 @@ void PhylogeneticsApplicationTools::printParameters(const SubstitutionModelSet*
   // Loop over all models:
   for (size_t i = 0; i < modelSet->getNumberOfModels(); i++)
   {
-    const TransitionModel* model = modelSet->getTransitionModel(i);
+    const TransitionModel* model = modelSet->getModel(i);
 
     map<string, string> aliases;
 
@@ -1552,6 +1554,7 @@ void PhylogeneticsApplicationTools::printParameters(const DiscreteDistribution*
 /************************
 * Substitution Mapping *
 ************************/
+
 SubstitutionCount* PhylogeneticsApplicationTools::getSubstitutionCount(
   const Alphabet* alphabet,
   const SubstitutionModel* model,
@@ -1612,4 +1615,139 @@ SubstitutionCount* PhylogeneticsApplicationTools::getSubstitutionCount(
   return substitutionCount;
 }
 
-/******************************************************************************/
+/****************************************************************************/
+
+
+SubstitutionRegister* PhylogeneticsApplicationTools::getSubstitutionRegister(const std::string& regTypeDesc, const SubstitutionModel* model, bool verbose)
+{
+  string regType = "";
+  map<string, string> regArgs;
+  KeyvalTools::parseProcedure(regTypeDesc, regType, regArgs);
+  
+  SubstitutionRegister* reg = 0;
+
+  if (regType=="Combination")
+  {
+    VectorOfSubstitionRegisters* vreg= new VectorOfSubstitionRegisters(model);
+
+    size_t i = 0;
+    while (++i)
+    {
+      string regDesc = ApplicationTools::getStringParameter("reg" + TextTools::toString(i), regArgs, "", "", false, 1);
+      if (regDesc=="")
+        break;
+      
+      SubstitutionRegister* sreg=getSubstitutionRegister(regDesc, model);
+
+      vreg->addRegister(sreg);
+    }
+    
+    reg=vreg;
+  }
+  else if (regType == "All")
+  {
+    reg = new ComprehensiveSubstitutionRegister(model, false);
+  }
+  else if (regType == "Total")
+  {
+    reg = new TotalSubstitutionRegister(model);
+  }    
+  else if (regType == "Selected"){  
+    string subsList = ApplicationTools::getStringParameter("substitution.list", regArgs, "All", "", true, false);
+    reg = new SelectedSubstitutionRegister(model, subsList);  
+  }
+
+  
+  // Alphabet dependent registers
+
+  
+  else if (AlphabetTools::isNucleicAlphabet(model->getAlphabet()))
+  {
+    const NucleotideSubstitutionModel* nmodel=dynamic_cast<const NucleotideSubstitutionModel*>(model);
+    if (!nmodel)
+    {
+      const WrappedSubstitutionModel* wmodel=dynamic_cast<const WrappedSubstitutionModel*>(model);
+      if (wmodel)
+      {
+        nmodel=dynamic_cast<const NucleotideSubstitutionModel*>(&wmodel->getSubstitutionModel());
+      }
+    }
+
+    if (!nmodel)
+      throw Exception("PhylogeneticsApplicationTools::getSubstitutionRegister : model and alphabet do not fit " + model->getAlphabet()->getAlphabetType() + " vs " + model->getName());
+
+    
+    if (regType == "GC")
+      reg = new GCSubstitutionRegister(nmodel, false);
+    else if (regType == "TsTv")
+      reg = new TsTvSubstitutionRegister(nmodel);
+    else if (regType == "SW")
+      reg = new SWSubstitutionRegister(nmodel);
+    else
+      throw Exception("Unsupported substitution categorization: " + regType + " for alphabet " + model->getAlphabet()->getAlphabetType());
+  }
+  
+  else if (AlphabetTools::isCodonAlphabet(model->getAlphabet()))
+  {
+    const CodonSubstitutionModel* cmodel=dynamic_cast<const CodonSubstitutionModel*>(model);
+    if (!cmodel)
+    {
+      const WrappedSubstitutionModel* wmodel=dynamic_cast<const WrappedSubstitutionModel*>(model);
+      if (wmodel)
+      {
+        cmodel=dynamic_cast<const CodonSubstitutionModel*>(&wmodel->getSubstitutionModel());
+      }
+    }
+
+    if (!cmodel)
+      throw Exception("PhylogeneticsApplicationTools::getSubstitutionRegister : model and alphabet do not fit " + model->getAlphabet()->getAlphabetType() + " vs " + model->getName());
+  
+    if (regType == "IntraAA")
+      reg = new AAInteriorSubstitutionRegister(cmodel);
+    else if (regType == "InterAA")
+      reg = new AAExteriorSubstitutionRegister(cmodel);
+    else if (regType == "GC")
+      reg = new GCSynonymousSubstitutionRegister(cmodel);
+    else if (regType == "TsTv")
+      reg = new TsTvSubstitutionRegister(cmodel);
+    else if (regType == "SW")
+      reg = new SWSubstitutionRegister(cmodel);
+    else if (regType == "KrKc")
+      reg = new KrKcSubstitutionRegister(cmodel);
+    else if (regType == "DnDs")
+      reg = new DnDsSubstitutionRegister(cmodel, false);
+    else
+      throw Exception("Unsupported substitution categorization: " + regType + " for alphabet " + model->getAlphabet()->getAlphabetType());
+  }
+  
+  else if (AlphabetTools::isProteicAlphabet(model->getAlphabet()))
+  {
+    const ProteinSubstitutionModel* pmodel=dynamic_cast<const ProteinSubstitutionModel*>(model);
+    if (!pmodel)
+    {
+      const WrappedSubstitutionModel* wmodel=dynamic_cast<const WrappedSubstitutionModel*>(model);
+      if (wmodel)
+      {
+        pmodel=dynamic_cast<const ProteinSubstitutionModel*>(&wmodel->getSubstitutionModel());
+      }
+    }
+
+    if (!pmodel)
+      throw Exception("PhylogeneticsApplicationTools::getSubstitutionRegister : model and alphabet do not fit " + model->getAlphabet()->getAlphabetType() + " vs " + model->getName());
+  
+    if (regType == "KrKc")
+      reg = new KrKcSubstitutionRegister(pmodel);
+    else
+      throw Exception("Unsupported substitution categorization: " + regType + " for alphabet " + model->getAlphabet()->getAlphabetType());
+  }
+  
+  CategorySubstitutionRegister* csr=dynamic_cast<CategorySubstitutionRegister*>(reg);
+  if (csr)
+    csr->setStationarity(ApplicationTools::getBooleanParameter("stationarity", regArgs, true));
+
+  if (verbose)
+    ApplicationTools::displayResult("Substitution Register", regType);
+
+  return reg;
+}
+
diff --git a/src/Bpp/Phyl/App/PhylogeneticsApplicationTools.h b/src/Bpp/Phyl/App/PhylogeneticsApplicationTools.h
index 7e503b0..9675918 100644
--- a/src/Bpp/Phyl/App/PhylogeneticsApplicationTools.h
+++ b/src/Bpp/Phyl/App/PhylogeneticsApplicationTools.h
@@ -573,6 +573,18 @@ public:
     int warn = 1);
 
   /**
+   * @brief Get a Register instance.
+   *
+   * @param regTypeDesc The description of the register.
+   * @param model The model to use.
+   * @param verbose if outputs  reading
+   * @return A SubstitutionRegister object.
+   */
+  
+  static SubstitutionRegister* getSubstitutionRegister(const std::string& regTypeDesc, const SubstitutionModel* model, bool verbose = true);
+  
+
+  /**
    * @brief Write a tree according to options.
    *
    * See the Bio++ Program Suite manual for a descriptio of all available options.
diff --git a/src/Bpp/Phyl/Distance/DistanceEstimation.h b/src/Bpp/Phyl/Distance/DistanceEstimation.h
index 0c63d6f..c13e0f2 100755
--- a/src/Bpp/Phyl/Distance/DistanceEstimation.h
+++ b/src/Bpp/Phyl/Distance/DistanceEstimation.h
@@ -6,36 +6,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 _DISTANCEESTIMATION_H_
@@ -65,9 +65,9 @@ namespace bpp
 /**
  * @brief This class is a simplified version of DRHomogeneousTreeLikelihood for 2-Trees.
  */
-class TwoTreeLikelihood:
-  public AbstractDiscreteRatesAcrossSitesTreeLikelihood  
-{
+  class TwoTreeLikelihood:
+    public AbstractDiscreteRatesAcrossSitesTreeLikelihood  
+  {
   private:
     SiteContainer* shrunkData_;
     std::vector<std::string> seqnames_;
@@ -100,9 +100,9 @@ class TwoTreeLikelihood:
 
     //some values we'll need:
     size_t nbSites_,         //the number of sites in the container
-           nbClasses_,       //the number of rate classes
-           nbStates_,        //the number of states in the alphabet
-           nbDistinctSites_; //the number of distinct sites in the container
+      nbClasses_,       //the number of rate classes
+      nbStates_,        //the number of states in the alphabet
+      nbDistinctSites_; //the number of distinct sites in the container
 
     mutable VVVdouble rootLikelihoods_;
     mutable VVdouble rootLikelihoodsS_;
@@ -162,8 +162,11 @@ class TwoTreeLikelihood:
     double getLogLikelihoodForASite(size_t site) const;
     ParameterList getBranchLengthsParameters() const;
     ParameterList getSubstitutionModelParameters() const;
-    TransitionModel* getSubstitutionModel(int nodeId, size_t siteIndex) throw (NodeNotFoundException) { return model_; }
-    const TransitionModel* getSubstitutionModel(int nodeId, size_t siteIndex) const throw (NodeNotFoundException) { return model_; }
+  
+    TransitionModel* getModelForSite(int nodeId, size_t siteIndex) { return model_; }
+  
+    const TransitionModel* getModelForSite(int nodeId, size_t siteIndex) const { return model_; }
+
     const std::vector<double>& getRootFrequencies(size_t siteIndex) const { return model_->getFrequencies(); }
     size_t getSiteIndex(size_t site) const throw (IndexOutOfBoundsException) { return rootPatternLinks_[site]; }
     /**
@@ -185,19 +188,14 @@ class TwoTreeLikelihood:
     double getLogLikelihoodForASiteForARateClassForAState(size_t site, size_t rateClass, int state) const;
     /** @} */
 
-    /**
-     * @brief Get the substitution model used for the computation.
-     *
-     * @return A const pointer toward the substitution model of this instance.
-     */
-    const TransitionModel* getSubstitutionModel() const { return model_; }
-    
+    const TransitionModel* getModel() const { return model_; }
+
     /**
      * @brief Get the substitution model used for the computation.
      *
      * @return A pointer toward the substitution model of this instance.
      */
-    TransitionModel* getSubstitutionModel() { return model_; }
+    TransitionModel* getModel() { return model_; }
 
     ConstBranchModelIterator* getNewBranchModelIterator(int nodeId) const throw (NotImplementedException)
     {
@@ -292,7 +290,7 @@ class TwoTreeLikelihood:
      */
     virtual void applyParameters() throw (Exception);  
 
-};
+  };
 
 /**
  * @brief Estimate a distance matrix from sequence data, according to a given model.
@@ -306,9 +304,9 @@ class TwoTreeLikelihood:
  * You'll have to specify a 'profiler' to the optimizer and then look at the file
  * if you want to do so.
  */
-class DistanceEstimation:
-  public virtual Clonable
-{
+  class DistanceEstimation:
+    public virtual Clonable
+  {
   private:
     std::unique_ptr<TransitionModel> model_;
     std::unique_ptr<DiscreteDistribution> rateDist_;
@@ -336,9 +334,9 @@ class DistanceEstimation:
      *  - 4=3 + likelihood object verbose enabled
      */
     DistanceEstimation(
-        TransitionModel* model,
-        DiscreteDistribution* rateDist,
-        size_t verbose = 1) :
+      TransitionModel* model,
+      DiscreteDistribution* rateDist,
+      size_t verbose = 1) :
       model_(model),
       rateDist_(rateDist),
       sites_(0),
@@ -369,11 +367,11 @@ class DistanceEstimation:
      *  @param computeMat if true the computeMatrix() method is called.
      */
     DistanceEstimation(
-        TransitionModel* model,
-        DiscreteDistribution* rateDist,
-        const SiteContainer* sites,
-        size_t verbose = 1,
-        bool computeMat = true) :
+      TransitionModel* model,
+      DiscreteDistribution* rateDist,
+      const SiteContainer* sites,
+      size_t verbose = 1,
+      bool computeMat = true) :
       model_(model),
       rateDist_(rateDist),
       sites_(sites),
@@ -481,7 +479,8 @@ class DistanceEstimation:
 
     bool hasModel() const { return model_.get(); }
 
-    const TransitionModel& getSubstitutionModel() const throw (Exception) {
+    const TransitionModel& getModel() const throw (Exception)
+    {
       if (hasModel())
         return *model_;
       else
@@ -542,7 +541,7 @@ class DistanceEstimation:
      * @return Verbose level.
      */
     size_t getVerbose() const { return verbose_; }
-};
+  };
 
 } //end of namespace bpp.
 
diff --git a/src/Bpp/Phyl/Io/BppOFrequenciesSetFormat.cpp b/src/Bpp/Phyl/Io/BppOFrequenciesSetFormat.cpp
index 007577e..7b3f9ca 100644
--- a/src/Bpp/Phyl/Io/BppOFrequenciesSetFormat.cpp
+++ b/src/Bpp/Phyl/Io/BppOFrequenciesSetFormat.cpp
@@ -177,6 +177,9 @@ FrequenciesSet* BppOFrequenciesSetFormat::read(const Alphabet* alphabet, const s
 
     const WordAlphabet* pWA = dynamic_cast<const WordAlphabet*>(alphabet);
 
+    if (pWA==NULL)
+      throw Exception("BppOFrequenciesSetFormat::read : Word freq name is from WordAlphabet.");
+    
     if (args.find("frequency") != args.end())
     {
       string sAFS = args["frequency"];
@@ -266,7 +269,7 @@ FrequenciesSet* BppOFrequenciesSetFormat::read(const Alphabet* alphabet, const s
       string sAFS = args["frequency"];
 
       BppOFrequenciesSetFormat nestedReader(alphabetCode_, false, warningLevel_);
-      unique_ptr<FrequenciesSet> pFS2(nestedReader.read(pWA->getNAlphabet(0), sAFS, data, false));
+      unique_ptr<FrequenciesSet> pFS2(nestedReader.read(pWA->getNucleicAlphabet(), sAFS, data, false));
       map<string, string> unparsedParameterValuesNested(nestedReader.getUnparsedArguments());
 
       for (map<string, string>::iterator it = unparsedParameterValuesNested.begin(); it != unparsedParameterValuesNested.end(); it++)
@@ -295,7 +298,7 @@ FrequenciesSet* BppOFrequenciesSetFormat::read(const Alphabet* alphabet, const s
       for (size_t i = 0; i < v_sAFS.size(); ++i)
       {
         BppOFrequenciesSetFormat nestedReader(alphabetCode_, false, warningLevel_);
-        pFS.reset(nestedReader.read(pWA->getNAlphabet(i), v_sAFS[i], data, false));
+        pFS.reset(nestedReader.read(pWA->getNucleicAlphabet(), v_sAFS[i], data, false));
         map<string, string> unparsedParameterValuesNested(nestedReader.getUnparsedArguments());
         for (map<string, string>::iterator it = unparsedParameterValuesNested.begin(); it != unparsedParameterValuesNested.end(); it++)
         {
@@ -388,7 +391,7 @@ FrequenciesSet* BppOFrequenciesSetFormat::read(const Alphabet* alphabet, const s
         string sAFS = args["frequency"];
         
         BppOFrequenciesSetFormat nestedReader(alphabetCode_, false, warningLevel_);
-        unique_ptr<FrequenciesSet> pFS2(nestedReader.read(pWA->getNAlphabet(0), sAFS, data, false));
+        unique_ptr<FrequenciesSet> pFS2(nestedReader.read(pWA->getNucleicAlphabet(), sAFS, data, false));
         if (pFS2->getName()!="Full")
           throw Exception("BppOFrequenciesSetFormat::read. The frequency option in F1X4 can only be Full");
         
@@ -440,7 +443,7 @@ FrequenciesSet* BppOFrequenciesSetFormat::read(const Alphabet* alphabet, const s
           {
             BppOFrequenciesSetFormat nestedReader(alphabetCode_, false, warningLevel_);
             if (v_sAFS[i]!=""){
-              pFS.reset(nestedReader.read(pWA->getNAlphabet(i), v_sAFS[i], data, false));
+              pFS.reset(nestedReader.read(pWA->getNucleicAlphabet(), v_sAFS[i], data, false));
               if (pFS->getName()!="Full")
                 throw Exception("BppOFrequenciesSetFormat::read. The frequency options in F3X4 can only be Full");
 
@@ -520,7 +523,6 @@ FrequenciesSet* BppOFrequenciesSetFormat::read(const Alphabet* alphabet, const s
     {
       pname2 = pFS->getParameterNameWithoutNamespace(pl[j].getName());
 
-      // if (j == i || args.find(pname2) == args.end()) continue; Julien 03/03/2010: This extra condition prevents complicated (nested) models to work properly...
       if (j == i)
         continue;
       if (pval == pname2)
diff --git a/src/Bpp/Phyl/Io/BppOSubstitutionModelFormat.cpp b/src/Bpp/Phyl/Io/BppOSubstitutionModelFormat.cpp
index c73d0ae..6488ac0 100644
--- a/src/Bpp/Phyl/Io/BppOSubstitutionModelFormat.cpp
+++ b/src/Bpp/Phyl/Io/BppOSubstitutionModelFormat.cpp
@@ -58,15 +58,19 @@
 #include "../Model/Codon/YNGP_M10.h"
 #include "../Model/Codon/YN98.h"
 #include "../Model/Codon/TripletSubstitutionModel.h"
-#include "../Model/Codon/CodonRateSubstitutionModel.h"
-#include "../Model/Codon/CodonDistanceSubstitutionModel.h"
-#include "../Model/Codon/CodonDistanceCpGSubstitutionModel.h"
-#include "../Model/Codon/CodonRateFrequenciesSubstitutionModel.h"
+#include "../Model/Codon/AbstractCodonDistanceSubstitutionModel.h"
+#include "../Model/Codon/AbstractCodonAARateSubstitutionModel.h"
+#include "../Model/Codon/AbstractCodonAAFitnessSubstitutionModel.h"
+#include "../Model/Codon/AbstractCodonCpGSubstitutionModel.h"
+#include "../Model/Codon/AbstractCodonBGCSubstitutionModel.h"
+#include "../Model/Codon/AbstractCodonDistanceSubstitutionModel.h"
+#include "../Model/Codon/AbstractCodonFitnessSubstitutionModel.h"
+#include "../Model/Codon/AbstractCodonFrequenciesSubstitutionModel.h"
+#include "../Model/Codon/AbstractCodonPhaseFrequenciesSubstitutionModel.h"
+#include "../Model/Codon/CodonAdHocSubstitutionModel.h"
 #include "../Model/Codon/KroneckerCodonDistanceFrequenciesSubstitutionModel.h"
 #include "../Model/Codon/KroneckerCodonDistanceSubstitutionModel.h"
 #include "../Model/Codon/KCM.h"
-#include "../Model/Codon/CodonDistanceFrequenciesSubstitutionModel.h"
-#include "../Model/Codon/CodonDistancePhaseFrequenciesSubstitutionModel.h"
 #include "../Model/Codon/SENCA.h"
 #include "../Model/RE08.h"
 #include "../Model/TS98.h"
@@ -103,7 +107,10 @@
 #include "../Model/Protein/LG10_EX_EHO.h"
 #include "../Model/BinarySubstitutionModel.h"
 #include "../Model/FromMixtureSubstitutionModel.h"
+#include "../Model/InMixedSubstitutionModel.h"
 #include "../Model/OneChangeTransitionModel.h"
+#include "../Model/OneChangeRegisterTransitionModel.h"
+#include "../Model/RegisterRatesSubstitutionModel.h"
 
 #include "../App/PhylogeneticsApplicationTools.h"
 
@@ -162,7 +169,108 @@ SubstitutionModel* BppOSubstitutionModelFormat::read(
   if ((modelName == "MixedModel" || (modelName == "Mixture")) && allowMixed_)
     model.reset(readMixed_(alphabet, modelDescription, data));
 
+  // ///////////////////////////////
+  // LINKED WITH MIXTURES
+  // //////////////////////////////
+  
+  else if (modelName == "InMixed")
+  {
+    if (args.find("model") == args.end())
+      throw Exception("'model' argument missing to define the InMixed model.");
+
+    string nameMod="";
+    size_t numMod=0;
+    
+    if (args.find("numMod") == args.end())
+    {
+      if (args.find("nameMod") == args.end())
+        throw Exception("'numMod' and 'nameMod' arguments missing to define the InMixed submodel.");
+      else
+        nameMod=args["nameMod"];
+    }
+    else
+      numMod=(size_t)TextTools::toInt(args["numMod"]);
+    
+    string modelDesc2=args["model"];
+    BppOSubstitutionModelFormat nestedReader(alphabetCode_, false, true, false, false, warningLevel_);
+    nestedReader.setGeneticCode(geneticCode_); //This uses the same instance as the o
+
+    MixedSubstitutionModel* nestedModel=dynamic_cast<MixedSubstitutionModel*>(nestedReader.read(alphabet, modelDesc2, data, false));
+
+    // Check that nestedModel is fine and has subModel of given name
+    // or number
+    
+    if (nestedModel==NULL)
+      throw Exception("Unknown mixed model " + modelDesc2 + ".");
+    
+    if (nameMod!="")
+    {
+      if (nestedModel->getSubModelWithName(nameMod)==NULL)
+        throw Exception("BppOSubstitutionModelFormat::read. " + nestedModel->getName() + "argument for model 'InMixed' has no submodel with name " + nameMod + ".");
+      model.reset(new InMixedSubstitutionModel(*nestedModel, nameMod, modelDesc2));
+    }
+    else
+    {
+      if (numMod==0 || (nestedModel->getNumberOfModels()<numMod))
+        throw Exception("BppOSubstitutionModelFormat::read. " + nestedModel->getName() + "argument for model 'InMixed' has no submodel with number " + TextTools::toString(numMod) + ".");
+      model.reset(new InMixedSubstitutionModel(*nestedModel, numMod-1, modelDesc2));      
+    }
+
+    map<string, string> unparsedParameterValuesNested(nestedReader.getUnparsedArguments());
+    for (map<string, string>::iterator it = unparsedParameterValuesNested.begin(); it != unparsedParameterValuesNested.end(); it++)
+    {
+      unparsedArguments_[it->first] = it->second;
+    }
+
+    if (verbose_)
+      ApplicationTools::displayResult("Number of submodel", TextTools::toString(numMod));
+
+    delete nestedModel;
+  }
+
+
+  else if (modelName == "FromRegister")
+  {
+    // We have to parse the nested model first:
+    if (args.find("model")==args.end())
+      throw Exception("BppOSubstitutionModelFormat::read. Missing argument 'model' for model 'FromRegister'.");
+
+    string nestedModelDescription = args["model"];
+    BppOSubstitutionModelFormat nestedReader(ALL, false, allowMixed_, allowGaps_, verbose_, warningLevel_);
+    if (geneticCode_)
+      nestedReader.setGeneticCode(geneticCode_);
+    
+    SubstitutionModel* nestedModel=nestedReader.read(alphabet, nestedModelDescription, data, false);
+    map<string, string> unparsedParameterValuesNested(nestedReader.getUnparsedArguments());
+
+    // We look for the register:
+    if (args.find("register")==args.end())
+      throw Exception("BppOSubstitutionModelFormat::read. Missing argument 'register' for model 'FromRegister'.");
+    
+    string registerDescription = args["register"];
+    SubstitutionRegister* reg=PhylogeneticsApplicationTools::getSubstitutionRegister(registerDescription, nestedModel);
+
+    // is it normalized (default : false)
+    bool isNorm=false;
+    
+    if (args.find("isNormalized")!=args.end() && args["isNormalized"]=="true")
+      isNorm=true;
 
+    model.reset(new RegisterRatesSubstitutionModel(*nestedModel, *reg, isNorm));
+    
+    if (TextTools::isEmpty(registerDescription))
+      throw Exception("BppOSubstitutionModelFormat::read. Missing argument 'register' for model 'FromRegister'.");
+
+    // Then we update the parameter set:
+    for (map<string, string>::iterator it = unparsedParameterValuesNested.begin(); it != unparsedParameterValuesNested.end(); it++)
+    {
+      unparsedArguments_["FromRegister."+it->first] = it->second;
+    }
+    
+    delete nestedModel;
+  }
+  
+  
   // /////////////////////////////////
   // / WORDS and CODONS
   // ///////////////////////////////
@@ -170,11 +278,10 @@ SubstitutionModel* BppOSubstitutionModelFormat::read(
   else if ((modelName == "Word") || (modelName.substr(0,4) == "Kron") || (modelName == "Triplet") || (modelName.substr(0, 5) == "Codon") || (modelName == "SENCA") )
     model.reset(readWord_(alphabet, modelDescription, data));
 
-
-  // //////////////////////////////////////
+  
+  // //////////////////
   // PREDEFINED CODON MODELS
-  // //////////////////////////////////////
-
+  
   else if (((modelName == "MG94") || (modelName == "YN98") ||
             (modelName == "GY94") || (modelName.substr(0, 4) == "YNGP") ||
             (modelName.substr(0,3) == "KCM")
@@ -472,10 +579,15 @@ SubstitutionModel* BppOSubstitutionModelFormat::read(
         if (verbose_)
           ApplicationTools::displayResult("Biased gene conversion for", subModName);
 
-        string::size_type begin = modelDescription.find_first_of("(");
-        string::size_type end = modelDescription.find_last_of(")");
+        string nestedModelDescription = subModName;
+        
+        if (modelDescription.find_first_of("(")!=string::npos)
+        {
+          string::size_type begin = modelDescription.find_first_of("(");
+          string::size_type end = modelDescription.find_last_of(")");
 
-        string nestedModelDescription = subModName+modelDescription.substr(begin,end-begin+1);
+          nestedModelDescription += modelDescription.substr(begin,end-begin+1);
+        }
         
         BppOSubstitutionModelFormat nestedReader(NUCLEOTIDE, true, true, false, verbose_, warningLevel_);
         unique_ptr<NucleotideSubstitutionModel> nestedModel(dynamic_cast<NucleotideSubstitutionModel*>(nestedReader.read(alphabet, nestedModelDescription, data, false)));
@@ -593,9 +705,7 @@ SubstitutionModel* BppOSubstitutionModelFormat::read(
         model.reset(new JCnuc(alpha));
       }
       else
-      {
-        throw Exception("Model '" + modelName + "' unknown.");
-      }
+        throw Exception("Model '" + modelName + "' unknown, or does not fit nucleic alphabet.");
     }
     else if (AlphabetTools::isProteicAlphabet(alphabet))
     {
@@ -683,9 +793,9 @@ SubstitutionModel* BppOSubstitutionModelFormat::read(
           throw Exception("Unknown model " + modelName + ".");
         
         if (nestedModel->getSubModelWithName(subModelName)==NULL)
-          throw Exception("BppOSubstitutionModelFormat::read. " + nestedModel->getName() + "argument for model 'FromModel' has no submodel with name " + subModelName + ".");
+          throw Exception("BppOSubstitutionModelFormat::read. " + nestedModel->getName() + "argument for model 'FromMixture' has no submodel with name " + subModelName + ".");
 
-        // Now we create the FromModel substitution model:
+        // Now we create the FromMixture substitution model:
         model.reset(new FromMixtureSubstitutionModel(*nestedModel, subModelName, modelDesc2));
         
         delete nestedModel;
@@ -714,6 +824,8 @@ SubstitutionModel* BppOSubstitutionModelFormat::read(
         model.reset(new Coala(alpha, *nestedModel, TextTools::to<unsigned int>(nbrOfParametersPerBranch)));
         model->setFreqFromData(*data);
       }
+      else
+        throw Exception("Model '" + modelName + "' is unknown, or does not fit proteic alphabet.");      
     }
     else if (AlphabetTools::isBinaryAlphabet(alphabet))
     {
@@ -724,9 +836,11 @@ SubstitutionModel* BppOSubstitutionModelFormat::read(
 
       if (modelName == "Binary")
         model.reset(new BinarySubstitutionModel(balpha));
+      else
+        throw Exception("Model '" + modelName + "' unknown, or does not fit binary alphabet.");
     }
     else
-      throw Exception("Model '" + modelName + "' unknown, or does not fit alphabet.");
+      throw Exception("Model '" + modelName + "' unknown, or does not fit " + alphabet->getAlphabetType() + " alphabet.");
     
   }
     
@@ -821,7 +935,7 @@ SubstitutionModel* BppOSubstitutionModelFormat::readWord_(const Alphabet* alphab
 
   vector<string> v_nestedModelDescription;
   vector<SubstitutionModel*> v_pSM;
-  const WordAlphabet* pWA;
+  const CoreWordAlphabet* pWA;
 
   string s, nestedModelDescription;
   unsigned int nbmodels;
@@ -831,7 +945,7 @@ SubstitutionModel* BppOSubstitutionModelFormat::readWord_(const Alphabet* alphab
     throw Exception("Bad alphabet type "
                     + alphabet->getAlphabetType() + " for  model " + modelName + ".");
 
-  pWA = dynamic_cast<const WordAlphabet*>(alphabet);
+  pWA = dynamic_cast<const CoreWordAlphabet*>(alphabet);
 
   
   ////////////////////////////////////
@@ -1046,78 +1160,116 @@ SubstitutionModel* BppOSubstitutionModelFormat::readWord_(const Alphabet* alphab
                     dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[1]),
                     dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[2])));
 
-    else if (modelName == "CodonRate")
-      model.reset((v_nestedModelDescription.size() != 3)
-                  ? new CodonRateSubstitutionModel(
-                    geneticCode_,
-                    dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[0]))
-                  : new CodonRateSubstitutionModel(
-                    geneticCode_,
-                    dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[0]),
-                    dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[1]),
-                    dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[2])));
+    else if (modelName.find("Codon")!=string::npos)
+    {
+      vector<CoreCodonSubstitutionModel*> vCSM;
+      string name="Codon";
+      map<string, string> unparsedParameterValuesNested;
 
+      if (modelName.find("Dist")!=string::npos)
+      {
+        name +="Dist";
+        
+        vCSM.push_back(new AbstractCodonDistanceSubstitutionModel(pai2.release(), geneticCode_, ""));
+      }
+      else if (modelName.find("BGC")!=string::npos)
+      {
+        name +="BGC";
+        
+        vCSM.push_back(new AbstractCodonBGCSubstitutionModel(geneticCode_, ""));
+      }
+      else if (modelName.find("Prot")!=string::npos)
+      {
+        name+="Prot";
 
-    else if (modelName == "CodonDist")
-    {
-      if (v_nestedModelDescription.size() != 3)
-        model.reset(new CodonDistanceSubstitutionModel(geneticCode_, dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[0]), pai2.release()));
-      else
-        model.reset(new CodonDistanceSubstitutionModel(
-                      geneticCode_,
-                      dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[0]),
-                      dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[1]),
-                      dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[2]), pai2.release()));
-    }
+        if (args.find("protmodel")==args.end())
+          throw Exception("BppOSubstitutionModelFormat::read. Missing argument 'protmodel' for codon model argument 'Prot'.");
 
-    else if (modelName == "CodonDistCpG")
-    {
-      if (v_nestedModelDescription.size() != 3)
-        model.reset(new CodonDistanceCpGSubstitutionModel(geneticCode_, dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[0]), pai2.release()));
-      else
-        model.reset(new CodonDistanceCpGSubstitutionModel(
-                      geneticCode_,
-                      dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[0]),
-                      dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[1]),
-                      dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[2]), pai2.release()));
-    }
+        nestedModelDescription = args["protmodel"];
+        BppOSubstitutionModelFormat nestedReader(PROTEIN, false, false, allowGaps_, verbose_, warningLevel_);
+        
+        shared_ptr<ProteinSubstitutionModel> nestedModel(dynamic_cast<ProteinSubstitutionModel*>(nestedReader.read(geneticCode_->getTargetAlphabet(), nestedModelDescription, data, false)));
+        
+        unparsedParameterValuesNested.insert(nestedReader.getUnparsedArguments().begin(),nestedReader.getUnparsedArguments().end());
 
-    else if (modelName == "CodonRateFreq")
-    {
-      if (v_nestedModelDescription.size() != 3)
-        model.reset(
-          new CodonRateFrequenciesSubstitutionModel(
-            geneticCode_,
-            dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[0]),
-            pFS.release()));
-      else
-        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()));
-    }
+        vCSM.push_back(new AbstractCodonAARateSubstitutionModel(nestedModel, geneticCode_, ""));
+      }
+      
+      if (vCSM.size()==0)
+        name+="Rate";
+      
+      if (modelName.find("CpG")!=string::npos)
+      {
+        name+="CpG";
+        vCSM.push_back(new AbstractCodonCpGSubstitutionModel(""));
+      }
+      
+      if (modelName.find("AAFit")!=string::npos)
+      {
+        name+="AAFit";
 
-    else if (modelName == "CodonDistFreq")
-    {
-      if (v_nestedModelDescription.size() != 3)
-        model.reset(new CodonDistanceFrequenciesSubstitutionModel(geneticCode_,
-                                                                  dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[0]),
-                                                                  pFS.release(),
-                                                                  pai2.release()));
-      else
-        model.reset(new CodonDistanceFrequenciesSubstitutionModel(
-                      geneticCode_,
-                      dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[0]),
-                      dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[1]),
-                      dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[2]),
-                      pFS.release(),
-                      pai2.release()));
-    }
+        if (args.find("fitness")==args.end())
+          throw Exception("BppOSubstitutionModelFormat::read. Missing argument 'fitness' for codon model argument 'AAFit'.");
+
+        string nestedFreqDescription = args["fitness"];
+        BppOFrequenciesSetFormat nestedReader(PROTEIN, verbose_, warningLevel_);
 
+        FrequenciesSet* nestedFreq=nestedReader.read(geneticCode_->getTargetAlphabet(), nestedFreqDescription, data, false);
+        
+        for (auto  it : nestedReader.getUnparsedArguments())
+          unparsedParameterValuesNested["fit_" + it.first] = it.second;
+
+        vCSM.push_back(new AbstractCodonAAFitnessSubstitutionModel(nestedFreq, geneticCode_, ""));
+      }
+      else if (modelName.find("Fit")!=string::npos)
+      {
+        if (args.find("fitness") == args.end())
+          throw Exception("BppOSubstitutionModelFormat::read. Missing argument 'fitness' for codon model argument 'Fit'.");
+        string nestedFreqDescription = args["fitness"];
+        
+        BppOFrequenciesSetFormat nestedReader(alphabetCode_, verbose_, warningLevel_);
+        nestedReader.setGeneticCode(geneticCode_);
+      
+        FrequenciesSet* nestedFreq=nestedReader.read(alphabet, nestedFreqDescription, data, false);
+        
+        for (auto  it : nestedReader.getUnparsedArguments())
+          unparsedParameterValuesNested["fit_" + it.first] = it.second;
+        
+        vCSM.push_back(new AbstractCodonFitnessSubstitutionModel(nestedFreq, geneticCode_, ""));
+      }
+
+      if (modelName.find("PhasFreq")!=string::npos)
+      {
+        name+="PhasFreq";
+        vCSM.push_back(new AbstractCodonPhaseFrequenciesSubstitutionModel(pFS.release(),""));
+      }
+      else if (modelName.find("Freq")!=string::npos)
+      {
+        name+="Freq";
+        vCSM.push_back(new AbstractCodonFrequenciesSubstitutionModel(pFS.release(),""));
+      }
+
+      // Then we update the parameter set:
+      for (map<string, string>::iterator it = unparsedParameterValuesNested.begin(); it != unparsedParameterValuesNested.end(); it++)
+      {
+        unparsedArguments_[name+"."+it->first] = it->second;
+      }
     
+      model.reset((v_nestedModelDescription.size() != 3)
+                  ? new CodonAdHocSubstitutionModel(
+                    geneticCode_,
+                    dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[0]),
+                    vCSM,
+                    name)
+                  : new CodonAdHocSubstitutionModel(
+                    geneticCode_,
+                    dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[0]),
+                    dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[1]),
+                    dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[2]),
+                    vCSM,
+                    name));
+      
+    }
     else if (modelName == "KronDistFreq")
     {
       if (v_nestedModelDescription.size() != 3){
@@ -1193,23 +1345,6 @@ SubstitutionModel* BppOSubstitutionModelFormat::readWord_(const Alphabet* alphab
       }
     }
     
-    else if (modelName == "CodonDistPhasFreq")
-    {
-      if (v_nestedModelDescription.size() != 3)
-        model.reset(new CodonDistancePhaseFrequenciesSubstitutionModel(geneticCode_,
-                                                                       dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[0]),
-                                                                       pFS.release(),
-                                                                       pai2.release()));
-      else
-        model.reset(new CodonDistancePhaseFrequenciesSubstitutionModel(
-                      geneticCode_,
-                      dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[0]),
-                      dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[1]),
-                      dynamic_cast<NucleotideSubstitutionModel*>(v_pSM[2]),
-                      pFS.release(),
-                      pai2.release()));
-    }
-    
     else if (modelName == "SENCA")
     {
       if (args.find("fitness") == args.end())
@@ -1463,11 +1598,33 @@ void BppOSubstitutionModelFormat::write(const TransitionModel& model,
   if (onechangetransitionmodel)
   {
     out << "model=";
-    const SubstitutionModel& nestedModel = onechangetransitionmodel->getModel();
+    const TransitionModel& nestedModel = onechangetransitionmodel->getModel();
     write(nestedModel, out, globalAliases, writtenNames);
     comma = true;
   }
-
+  else
+  {
+    // Is it a model with register?
+    const OneChangeRegisterTransitionModel* onechangeregistertransitionmodel = dynamic_cast<const OneChangeRegisterTransitionModel*>(&model);
+    const RegisterRatesSubstitutionModel* regratessubsmodel = dynamic_cast<const RegisterRatesSubstitutionModel*>(&model);
+    if (onechangeregistertransitionmodel || regratessubsmodel)
+    {
+      out << "model=";
+      const TransitionModel& nestedModel = onechangeregistertransitionmodel?onechangeregistertransitionmodel->getModel():regratessubsmodel->getModel();
+      
+      write(nestedModel, out, globalAliases, writtenNames);
+      comma = true;
+      out << ", register=";
+      if (onechangeregistertransitionmodel)
+        out << onechangeregistertransitionmodel->getRegisterName();
+      else
+        out << regratessubsmodel->getRegisterName();
+      
+      if (onechangeregistertransitionmodel)
+        out << ", numReg=" << VectorTools::paste(onechangeregistertransitionmodel->getRegisterNumbers(),"+");
+    }
+  }
+  
   // Is it a gBGC model?
   const gBGC* gbgcModel = dynamic_cast<const gBGC*>(&model);
   if (gbgcModel)
@@ -1529,16 +1686,19 @@ void BppOSubstitutionModelFormat::write(const TransitionModel& model,
     comma = true;
   }
 
-  // // Is it a FromMixture model?
+  // Is it a InMixed model?
 
-  // const FromMixtureSubstitutionModel* fromModel = dynamic_cast<const FromMixtureSubstitutionModel*>(&model);
-  // if (fromModel)
-  // {
-  //   out << "exch=" << coalaModel->getExch() << ",nbrAxes=" << coalaModel->getNbrOfAxes();
-  //   comma = true;
-  // }
+  const InMixedSubstitutionModel* inModel = dynamic_cast<const InMixedSubstitutionModel*>(&model);
+  if (inModel)
+  {
+    out << "model=";
+    write(inModel->getMixedModel(), out, globalAliases, writtenNames);
+    out << ", numMod=" << TextTools::toString(inModel->getSubModelNumber());
+    comma = true;
+  }
+  
+  // Is it a model with FrequenciesSet?
   
-  // Regular model
   const FrequenciesSet* pfs = model.getFrequenciesSet();
   if (pfs)
   {
@@ -1552,6 +1712,36 @@ void BppOSubstitutionModelFormat::write(const TransitionModel& model,
     comma = true;
   }
 
+  // Is it a codon model with Protein Model in it? 
+  const CodonAdHocSubstitutionModel* casm=dynamic_cast<const CodonAdHocSubstitutionModel*>(&model);
+  if (casm)
+  {
+    for (size_t i=0; i<casm->getNumberOfModels(); i++)
+    {
+      const AbstractCodonAARateSubstitutionModel* acr=dynamic_cast<const AbstractCodonAARateSubstitutionModel*>(casm->getNModel(i).get());
+      if (acr)
+      {
+        if (comma)
+          out << ",";
+        out << "protmodel=";
+    
+        write(*acr->getAAModel().get(), out, globalAliases, writtenNames);
+        comma = true;
+      }
+      const AbstractCodonAAFitnessSubstitutionModel* acf=dynamic_cast<const AbstractCodonAAFitnessSubstitutionModel*>(casm->getNModel(i).get());
+      if (acf)
+      {
+        if (comma)
+          out << ",";
+        out << "fitness=";
+    
+        BppOFrequenciesSetFormat bIOFreq(PROTEIN, false, warningLevel_);
+        bIOFreq.write(&acf->getAAFitness(), out, globalAliases, writtenNames);
+        comma = true;
+      }
+    }
+  }
+
   // Specific case of SENCA
 
   const SENCA* pCF = dynamic_cast<const SENCA*>(&model);
diff --git a/src/Bpp/Phyl/Io/BppOSubstitutionModelFormat.h b/src/Bpp/Phyl/Io/BppOSubstitutionModelFormat.h
index 65bd076..ec391c1 100644
--- a/src/Bpp/Phyl/Io/BppOSubstitutionModelFormat.h
+++ b/src/Bpp/Phyl/Io/BppOSubstitutionModelFormat.h
@@ -37,11 +37,13 @@
   knowledge of the CeCILL license and that you accept its terms.
 */
 
-#ifndef _BPPOSUBSTITUTIONMODELFORMAT_H_
-#define _BPPOSUBSTITUTIONMODELFORMAT_H_
+#ifndef _BPP_OSUBSTITUTION_MODEL_FORMAT_H_
+#define _BPP_OSUBSTITUTION_MODEL_FORMAT_H_
 
 #include "IoSubstitutionModelFactory.h"
 #include "../Model/MixedSubstitutionModel.h"
+#include "../Model/MixtureOfASubstitutionModel.h"
+#include "../Model/MixtureOfSubstitutionModels.h"
 
 // From bpp-seq
 #include <Bpp/Seq/GeneticCode/GeneticCode.h>
diff --git a/src/Bpp/Phyl/Io/BppOTransitionModelFormat.cpp b/src/Bpp/Phyl/Io/BppOTransitionModelFormat.cpp
index 7db6b97..cc11318 100644
--- a/src/Bpp/Phyl/Io/BppOTransitionModelFormat.cpp
+++ b/src/Bpp/Phyl/Io/BppOTransitionModelFormat.cpp
@@ -46,6 +46,7 @@
 #include <Bpp/Text/KeyvalTools.h>
 
 #include "../Model/OneChangeTransitionModel.h"
+#include "../Model/OneChangeRegisterTransitionModel.h"
 
 #include "../App/PhylogeneticsApplicationTools.h"
 
@@ -89,18 +90,53 @@ TransitionModel* BppOTransitionModelFormat::readTransitionModel(
   if (modelName == "OneChange")
   {
     // We have to parse the nested model first:
-    string nestedModelDescription = args["model"];
-    if (TextTools::isEmpty(nestedModelDescription))
+    if (args.find("model")==args.end())
       throw Exception("BppOTransitionModelFormat::read. Missing argument 'model' for model 'OneChange'.");
+    string nestedModelDescription = args["model"];
     BppOSubstitutionModelFormat nestedReader(ALL, false, allowMixed_, allowGaps_, verbose_, warningLevel_);
     if (geneticCode_)
       nestedReader.setGeneticCode(geneticCode_);
     
     SubstitutionModel* nestedModel=nestedReader.read(alphabet, nestedModelDescription, data, false);
-    
-    // Now we create the FromModel substitution model:
-    model.reset(new OneChangeTransitionModel(*nestedModel));
-        
+    map<string, string> unparsedParameterValuesNested(nestedReader.getUnparsedArguments());
+
+    // We look for the register:
+    if (args.find("register")==args.end())
+      model.reset(new OneChangeTransitionModel(*nestedModel));
+    else
+    {
+      string registerDescription = args["register"];
+      unique_ptr<SubstitutionRegister> reg(PhylogeneticsApplicationTools::getSubstitutionRegister(registerDescription, nestedModel));
+
+      if (args.find("numReg") == args.end())
+        throw Exception("Missing argument 'numReg' (number of event for register in model " + modelName);
+
+      vector<size_t> vNumRegs;
+      
+      StringTokenizer nst(args["numReg"], "+");
+
+      bool out=true;
+      
+      while (nst.hasMoreToken())
+      {
+        size_t n=TextTools::to<size_t>(nst.nextToken());
+        vNumRegs.push_back(n);
+        if (verbose_)
+        {
+          ApplicationTools::displayResult(out?"Register types":"", reg->getTypeName(n));
+          out=false;
+        }
+      }
+
+      model.reset(new OneChangeRegisterTransitionModel(*nestedModel, *reg, vNumRegs));
+    }
+
+    // Then we update the parameter set:
+    for (map<string, string>::iterator it = unparsedParameterValuesNested.begin(); it != unparsedParameterValuesNested.end(); it++)
+    {
+      unparsedArguments_["OneChange." + it->first] = it->second;
+    }
+
     delete nestedModel;
   }
   else
diff --git a/src/Bpp/Phyl/Likelihood/AbstractHomogeneousTreeLikelihood.cpp b/src/Bpp/Phyl/Likelihood/AbstractHomogeneousTreeLikelihood.cpp
index be75c17..a4dd932 100644
--- a/src/Bpp/Phyl/Likelihood/AbstractHomogeneousTreeLikelihood.cpp
+++ b/src/Bpp/Phyl/Likelihood/AbstractHomogeneousTreeLikelihood.cpp
@@ -159,7 +159,7 @@ void AbstractHomogeneousTreeLikelihood::init_(
   nodes_.pop_back(); // Remove the root node (the last added!).
   nbNodes_ = nodes_.size();
   nbClasses_ = rateDistribution_->getNumberOfCategories();
-  setSubstitutionModel(model);
+  setModel(model);
 
   verbose_ = verbose;
 
@@ -170,7 +170,7 @@ void AbstractHomogeneousTreeLikelihood::init_(
 
 /******************************************************************************/
 
-void AbstractHomogeneousTreeLikelihood::setSubstitutionModel(TransitionModel* model) throw (Exception)
+void AbstractHomogeneousTreeLikelihood::setModel(TransitionModel* model) throw (Exception)
 {
   // Check:
   if (data_)
diff --git a/src/Bpp/Phyl/Likelihood/AbstractHomogeneousTreeLikelihood.h b/src/Bpp/Phyl/Likelihood/AbstractHomogeneousTreeLikelihood.h
index 3dca3f3..372e03f 100644
--- a/src/Bpp/Phyl/Likelihood/AbstractHomogeneousTreeLikelihood.h
+++ b/src/Bpp/Phyl/Likelihood/AbstractHomogeneousTreeLikelihood.h
@@ -200,15 +200,34 @@ public:
    *
    * @{
    */
-  const TransitionModel* getSubstitutionModel() const { return model_; }
-  const TransitionModel* getSubstitutionModel(int nodeId, size_t siteIndex) const throw (NodeNotFoundException) { return model_; }
+  const TransitionModel* getModel() const { return model_; }
+  const TransitionModel* getModel(int nodeId, size_t siteIndex) const { return model_; }
 
-  TransitionModel* getSubstitutionModel() { return model_; }
-  TransitionModel* getSubstitutionModel(int nodeId, size_t siteIndex) throw (NodeNotFoundException) { return model_; }
+  TransitionModel* getModel() { return model_; }
+  TransitionModel* getModel(int nodeId, size_t siteIndex) { return model_; }
 
-  void setSubstitutionModel(TransitionModel* model) throw (Exception);
+  void setModel(TransitionModel* model) throw (Exception);
   /** @} */
 
+  /**
+   * @brief Get a SubstitutionModel pointer toward the model associated to this instance, if possible.
+   *
+   * Performs a cast operation on the pointer. Return NULL if cast failed.
+   * @return A SubstitutionModel pointer toward the model associated to this instance.
+   */
+  virtual const SubstitutionModel* getSubstitutionModel() const { return dynamic_cast<const SubstitutionModel*>(model_); }
+  
+  /**
+   * @brief Get a SubstitutionModel pointer toward the model associated to this instance, if possible.
+   *
+   * Performs a cast operation on the pointer. Return NULL if cast failed.
+   * @return A SubstitutionModel pointer toward the model associated to this instance.
+   *
+   * @param nodeId Id of the node
+   * @param siteIndex Position of the site
+   */
+  virtual const SubstitutionModel* getSubstitutionModel(int nodeId, size_t siteIndex) const { return dynamic_cast<const SubstitutionModel*>(model_); }
+
 public:
   // Specific methods:
 
diff --git a/src/Bpp/Phyl/Likelihood/AbstractNonHomogeneousTreeLikelihood.h b/src/Bpp/Phyl/Likelihood/AbstractNonHomogeneousTreeLikelihood.h
index cc1b85a..ed42c51 100644
--- a/src/Bpp/Phyl/Likelihood/AbstractNonHomogeneousTreeLikelihood.h
+++ b/src/Bpp/Phyl/Likelihood/AbstractNonHomogeneousTreeLikelihood.h
@@ -193,12 +193,12 @@ class AbstractNonHomogeneousTreeLikelihood:
       return AbstractDiscreteRatesAcrossSitesTreeLikelihood::getRateDistributionParameters();
     }
 
-    const TransitionModel* getSubstitutionModelForNode(int nodeId) const throw (NodeNotFoundException) 
+    const TransitionModel* getModelForNode(int nodeId) const throw (NodeNotFoundException) 
     {
       return modelSet_->getModelForNode(nodeId);
     }
 
-    TransitionModel* getSubstitutionModelForNode(int nodeId) throw (NodeNotFoundException)
+    TransitionModel* getModelForNode(int nodeId) throw (NodeNotFoundException)
     {
       return modelSet_->getModelForNode(nodeId);
     }
diff --git a/src/Bpp/Phyl/Likelihood/AbstractTreeLikelihood.h b/src/Bpp/Phyl/Likelihood/AbstractTreeLikelihood.h
index 5c1b844..f78422d 100755
--- a/src/Bpp/Phyl/Likelihood/AbstractTreeLikelihood.h
+++ b/src/Bpp/Phyl/Likelihood/AbstractTreeLikelihood.h
@@ -46,7 +46,7 @@
 
 #include <Bpp/Numeric/AbstractParametrizable.h>
 
-//From SeqLib:
+//From bpp-seq:
 #include <Bpp/Seq/Container/SiteContainer.h>
 
 namespace bpp
@@ -302,17 +302,6 @@ namespace bpp
     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;
-    
   };
 
 } //end of namespace bpp.
diff --git a/src/Bpp/Phyl/Likelihood/DRHomogeneousTreeLikelihood.h b/src/Bpp/Phyl/Likelihood/DRHomogeneousTreeLikelihood.h
index 1538a53..570c6b3 100755
--- a/src/Bpp/Phyl/Likelihood/DRHomogeneousTreeLikelihood.h
+++ b/src/Bpp/Phyl/Likelihood/DRHomogeneousTreeLikelihood.h
@@ -122,7 +122,7 @@ class DRHomogeneousTreeLikelihood:
      */ 
     DRHomogeneousTreeLikelihood(const DRHomogeneousTreeLikelihood& lik);
     
-    DRHomogeneousTreeLikelihood & operator=(const DRHomogeneousTreeLikelihood& lik);
+    DRHomogeneousTreeLikelihood& operator=(const DRHomogeneousTreeLikelihood& lik);
 
     virtual ~DRHomogeneousTreeLikelihood();
 
diff --git a/src/Bpp/Phyl/Likelihood/DiscreteRatesAcrossSitesTreeLikelihood.h b/src/Bpp/Phyl/Likelihood/DiscreteRatesAcrossSitesTreeLikelihood.h
index a1e5c2f..d8eb263 100755
--- a/src/Bpp/Phyl/Likelihood/DiscreteRatesAcrossSitesTreeLikelihood.h
+++ b/src/Bpp/Phyl/Likelihood/DiscreteRatesAcrossSitesTreeLikelihood.h
@@ -5,40 +5,40 @@
 //
 
 /*
-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 _DISCRETERATESACROSSSITESTREELIKELIHOOD_H_
-#define _DISCRETERATESACROSSSITESTREELIKELIHOOD_H_
+#ifndef _DISCRETE_RATES_ACROSS_SITESTREELIKELIHOOD_H_
+#define _DISCRETE_RATES_ACROSS_SITESTREELIKELIHOOD_H_
 
 #include "TreeLikelihood.h"
 
@@ -53,143 +53,143 @@ namespace bpp
  *
  * This interface provides methods for dealing with RAS models.
  */
-class DiscreteRatesAcrossSitesTreeLikelihood:
-  public virtual TreeLikelihood
-{
-	public:
-		DiscreteRatesAcrossSitesTreeLikelihood() {}
-		virtual ~DiscreteRatesAcrossSitesTreeLikelihood() {}
-
-	public:
-
-		/**
-		 * @brief Get the rate distribution used for the computation.
-		 *
-		 * @return A const pointer toward the rate distribution of this instance.
-		 */
-		virtual const DiscreteDistribution* getRateDistribution() const = 0;
-
-		/**
-		 * @brief Get the rate distribution used for the computation.
-		 *
-		 * @return A pointer toward the rate distribution of this instance.
-		 */
-		virtual DiscreteDistribution* getRateDistribution() = 0;
-
-		/**
-		 * @brief Get the likelihood for a site knowing its rate class.
-		 *
-		 * @param site      The site index.
-		 * @param rateClass The rate class index.
-		 * @return The likelihood for the specified site and rate class.
-		 */
-		virtual double getLikelihoodForASiteForARateClass(size_t site, size_t rateClass) const = 0;
+  class DiscreteRatesAcrossSitesTreeLikelihood:
+    public virtual TreeLikelihood
+  {
+  public:
+    DiscreteRatesAcrossSitesTreeLikelihood() {}
+    virtual ~DiscreteRatesAcrossSitesTreeLikelihood() {}
+
+  public:
+
+    /**
+     * @brief Get the rate distribution used for the computation.
+     *
+     * @return A const pointer toward the rate distribution of this instance.
+     */
+    virtual const DiscreteDistribution* getRateDistribution() const = 0;
+
+    /**
+     * @brief Get the rate distribution used for the computation.
+     *
+     * @return A pointer toward the rate distribution of this instance.
+     */
+    virtual DiscreteDistribution* getRateDistribution() = 0;
+
+    /**
+     * @brief Get the likelihood for a site knowing its rate class.
+     *
+     * @param site      The site index.
+     * @param rateClass The rate class index.
+     * @return The likelihood for the specified site and rate class.
+     */
+    virtual double getLikelihoodForASiteForARateClass(size_t site, size_t rateClass) const = 0;
 		
-		/**
-		 * @brief Get the logarithm of the likelihood for a site knowing its rate class.
-		 *
-		 * @param site      The site index.
-		 * @param rateClass The rate class index.
-		 * @return The logarithm of the likelihood for the specified site and rate class.
-		 */
-		virtual double getLogLikelihoodForASiteForARateClass(size_t site, size_t rateClass) const = 0;
+    /**
+     * @brief Get the logarithm of the likelihood for a site knowing its rate class.
+     *
+     * @param site      The site index.
+     * @param rateClass The rate class index.
+     * @return The logarithm of the likelihood for the specified site and rate class.
+     */
+    virtual double getLogLikelihoodForASiteForARateClass(size_t site, size_t rateClass) const = 0;
 	
-		/**
-		 * @brief Get the likelihood for a site knowing its rate class and its ancestral state.
-		 *
-		 * @param site      The site index.
-		 * @param rateClass The rate class index.
-		 * @param state     The ancestral state.
-		 * @return The likelihood for the specified site and rate class and ancestral state.
-		 */
-		virtual double getLikelihoodForASiteForARateClassForAState(size_t site, size_t rateClass, int state) const = 0;
+    /**
+     * @brief Get the likelihood for a site knowing its rate class and its ancestral state.
+     *
+     * @param site      The site index.
+     * @param rateClass The rate class index.
+     * @param state     The ancestral state.
+     * @return The likelihood for the specified site and rate class and ancestral state.
+     */
+    virtual double getLikelihoodForASiteForARateClassForAState(size_t site, size_t rateClass, int state) const = 0;
 		
-		/**
-		 * @brief Get the logarithm of the likelihood for a site knowing its rate class and its ancestral state.
-		 *
-		 * @param site      The site index.
-		 * @param rateClass The rate class index.
-		 * @param state     The ancestral state.
-		 * @return The logarithm of the likelihood for the specified site and rate class and ancestral state..
-		 */
-		virtual double getLogLikelihoodForASiteForARateClassForAState(size_t site, size_t rateClass, int state) const = 0;
-
-		/**
-		 * @brief Get the likelihood for each site and each rate class.
-		 *
-		 * @return A two-dimension vector with all likelihoods.
-		 */
-		virtual VVdouble getLikelihoodForEachSiteForEachRateClass() const = 0;
+    /**
+     * @brief Get the logarithm of the likelihood for a site knowing its rate class and its ancestral state.
+     *
+     * @param site      The site index.
+     * @param rateClass The rate class index.
+     * @param state     The ancestral state.
+     * @return The logarithm of the likelihood for the specified site and rate class and ancestral state..
+     */
+    virtual double getLogLikelihoodForASiteForARateClassForAState(size_t site, size_t rateClass, int state) const = 0;
+
+    /**
+     * @brief Get the likelihood for each site and each rate class.
+     *
+     * @return A two-dimension vector with all likelihoods.
+     */
+    virtual VVdouble getLikelihoodForEachSiteForEachRateClass() const = 0;
 		
-		/**
-		 * @brief Get the logarithm of the likelihood for each site and each rate class.
-		 *
-		 * @return A two-dimension vector with all log likelihoods:
-		 * <code>V[i][j] =</code> likelihood of site i and rate class j.
-		 */
-		virtual VVdouble getLogLikelihoodForEachSiteForEachRateClass() const = 0;
+    /**
+     * @brief Get the logarithm of the likelihood for each site and each rate class.
+     *
+     * @return A two-dimension vector with all log likelihoods:
+     * <code>V[i][j] =</code> likelihood of site i and rate class j.
+     */
+    virtual VVdouble getLogLikelihoodForEachSiteForEachRateClass() const = 0;
 		
-		/**
-		 * @brief Get the likelihood for each site and each rate class and each state.
-		 *
-		 * @return A three-dimension vector with all likelihoods.
-		 */
-		virtual VVVdouble getLikelihoodForEachSiteForEachRateClassForEachState() const = 0;
+    /**
+     * @brief Get the likelihood for each site and each rate class and each state.
+     *
+     * @return A three-dimension vector with all likelihoods.
+     */
+    virtual VVVdouble getLikelihoodForEachSiteForEachRateClassForEachState() const = 0;
 		
-		/**
-		 * @brief Get the logarithm of the likelihood for each site and each rate class and each state.
-		 *
-		 * @return A three-dimension vector with all log likelihoods:
-		 * <code>V[i][j][k} =</code> likelihood of site i and rate class j and state k.
-		 */
-		virtual VVVdouble getLogLikelihoodForEachSiteForEachRateClassForEachState() const = 0;
-
-		/**
-		 * @brief Get the posterior probability for each site of belonging to a
-		 * particular rate class.
-		 *
-		 * @return A two-dimension vector with all posterior probabilities:
-		 * <code>V[i][j] =</code> probablity for site i of belonging to rate class j.
-		 */
-		virtual VVdouble getPosteriorProbabilitiesOfEachRate() const = 0;
+    /**
+     * @brief Get the logarithm of the likelihood for each site and each rate class and each state.
+     *
+     * @return A three-dimension vector with all log likelihoods:
+     * <code>V[i][j][k} =</code> likelihood of site i and rate class j and state k.
+     */
+    virtual VVVdouble getLogLikelihoodForEachSiteForEachRateClassForEachState() const = 0;
+
+    /**
+     * @brief Get the posterior probability for each site of belonging to a
+     * particular rate class.
+     *
+     * @return A two-dimension vector with all posterior probabilities:
+     * <code>V[i][j] =</code> probablity for site i of belonging to rate class j.
+     */
+    virtual VVdouble getPosteriorProbabilitiesOfEachRate() const = 0;
 		
-		/**
-		 * @brief Get the posterior rate class (the one with maximum posterior
-		 * probability) for each site.
-		 *
-		 * @return A vector with all rate classes indexes.
-		 */
-		virtual std::vector<size_t> getRateClassWithMaxPostProbOfEachSite() const = 0;
-
-		/**
-		 * @brief Get the posterior rate (the one with maximum posterior
-		 * probability) for each site.
-		 *
-		 * @return A vector with all rate classes indexes.
-		 */
-		virtual Vdouble getRateWithMaxPostProbOfEachSite() const = 0;
+    /**
+     * @brief Get the posterior rate class (the one with maximum posterior
+     * probability) for each site.
+     *
+     * @return A vector with all rate classes indexes.
+     */
+    virtual std::vector<size_t> getRateClassWithMaxPostProbOfEachSite() const = 0;
+
+    /**
+     * @brief Get the posterior rate (the one with maximum posterior
+     * probability) for each site.
+     *
+     * @return A vector with all rate classes indexes.
+     */
+    virtual Vdouble getRateWithMaxPostProbOfEachSite() const = 0;
 	
-		/**
-		 * @brief Get the posterior rate, i.e. averaged over all classes
-		 * and weighted with posterior probabilities, for each site.
-		 *
-		 * @return A vector with all rates.
-		 */
-		virtual Vdouble getPosteriorRateOfEachSite() const = 0;
-
-		/**
-		 * @brief Get the parameters associated to the rate distirbution.
-		 *
-		 * @return A ParameterList object with all rate distribution parameters.
-		 */
-		virtual ParameterList getRateDistributionParameters() const = 0;
-
-		/**
-		 * @brief Get the number of classes.
-		 *
-		 * @return The Number of classes.
-		 */
-		virtual size_t getNumberOfClasses() const = 0;
+    /**
+     * @brief Get the posterior rate, i.e. averaged over all classes
+     * and weighted with posterior probabilities, for each site.
+     *
+     * @return A vector with all rates.
+     */
+    virtual Vdouble getPosteriorRateOfEachSite() const = 0;
+
+    /**
+     * @brief Get the parameters associated to the rate distirbution.
+     *
+     * @return A ParameterList object with all rate distribution parameters.
+     */
+    virtual ParameterList getRateDistributionParameters() const = 0;
+
+    /**
+     * @brief Get the number of classes.
+     *
+     * @return The number of classes.
+     */
+    virtual size_t getNumberOfClasses() const = 0;
 
     /**
      * @brief Retrieves all Pij(t) for a particular branch, defined by the upper node.
@@ -202,7 +202,7 @@ class DiscreteRatesAcrossSitesTreeLikelihood:
      */
     virtual VVVdouble getTransitionProbabilitiesPerRateClass(int nodeId, size_t siteIndex) const = 0;
 		
-};
+  };
 
 } //end of namespace bpp.
 
diff --git a/src/Bpp/Phyl/Likelihood/HomogeneousTreeLikelihood.h b/src/Bpp/Phyl/Likelihood/HomogeneousTreeLikelihood.h
index 6c52fd3..9ba7c6e 100755
--- a/src/Bpp/Phyl/Likelihood/HomogeneousTreeLikelihood.h
+++ b/src/Bpp/Phyl/Likelihood/HomogeneousTreeLikelihood.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 _HOMOGENEOUSTREELIKELIHOOD_H_
@@ -55,41 +55,59 @@ namespace bpp
  *
  * @see SubstitutionModel, SitePartitionHomogeneousTreeLikelihood.
  */
-class HomogeneousTreeLikelihood :
-	public virtual TreeLikelihood
-{
-	public:
+  class HomogeneousTreeLikelihood :
+    public virtual TreeLikelihood
+  {
+  public:
 
     HomogeneousTreeLikelihood* clone() const = 0;
 
   public:
-    const TransitionModel* getSubstitutionModel(int nodeId, size_t siteIndex) const throw (NodeNotFoundException)
-    {
-      return getSubstitutionModel();
+    const TransitionModel* getModelForSite(int nodeId, size_t siteIndex) const    {
+      return getModel();
     }
 
-    TransitionModel* getSubstitutionModel(int nodeId, size_t siteIndex) throw (NodeNotFoundException)
+    TransitionModel* getModelForSite(int nodeId, size_t siteIndex)
     {
-      return getSubstitutionModel();
+      return getModel();
     }
 
     /**
      * @return The substitution model attached to this instance.
      */
-    virtual const TransitionModel* getSubstitutionModel() const = 0;
+    virtual const TransitionModel* getModel() const = 0;
     
     /**
      * @return The substitution model attached to this instance.
      */
-    virtual TransitionModel* getSubstitutionModel() = 0;
+    virtual TransitionModel* getModel() = 0;
 
     /**
      * @return Set the substitution model for this instance.
      * @throw Exception If the model could not be set (for instance, because of a wrong alphabet type).
      */
-    virtual void setSubstitutionModel(TransitionModel* model) throw (Exception) = 0;
+    virtual void setModel(TransitionModel* model) throw (Exception) = 0;
+
+    /**
+     * @brief Get a SubstitutionModel pointer toward the model associated to this instance, if possible.
+     *
+     * Performs a cast operation on the pointer. Return NULL if cast failed.
+     * @return A SubstitutionModel pointer toward the model associated to this instance.
+     */
+    virtual const SubstitutionModel* getSubstitutionModel() const = 0;
+  
+    /**
+     * @brief Get a SubstitutionModel pointer toward the model associated to this instance, if possible.
+     *
+     * Performs a cast operation on the pointer. Return NULL if cast failed.
+     * @return A SubstitutionModel pointer toward the model associated to this instance.
+     *
+     * @param nodeId Id of the node
+     * @param siteIndex Position of the site
+     */
+    virtual const SubstitutionModel* getSubstitutionModel(int nodeId, size_t siteIndex) const = 0;
     
-};
+  };
 
 } //end of namespace bpp.
 
diff --git a/src/Bpp/Phyl/Likelihood/MarginalAncestralStateReconstruction.cpp b/src/Bpp/Phyl/Likelihood/MarginalAncestralStateReconstruction.cpp
index 8911b30..553c06a 100644
--- a/src/Bpp/Phyl/Likelihood/MarginalAncestralStateReconstruction.cpp
+++ b/src/Bpp/Phyl/Likelihood/MarginalAncestralStateReconstruction.cpp
@@ -115,7 +115,7 @@ Sequence* MarginalAncestralStateReconstruction::getAncestralSequenceForNode(int
 {
   string name = tree_.hasNodeName(nodeId) ? tree_.getNodeName(nodeId) : ("" + TextTools::toString(nodeId));
   const vector<size_t>* rootPatternLinks = &likelihood_->getLikelihoodData()->getRootArrayPositions();
-  const TransitionModel* model = likelihood_->getSubstitutionModel(tree_.getNodesId()[0], 0); // We assume all nodes have a model with the same number of states.
+  const TransitionModel* model = likelihood_->getModelForSite(tree_.getNodesId()[0], 0); // We assume all nodes have a model with the same number of states.
   vector<size_t> states;
   vector<int> allStates(nbSites_);
   VVdouble patternedProbs;
@@ -153,7 +153,7 @@ void MarginalAncestralStateReconstruction::recursiveMarginalAncestralStates(
     // This is a tricky way to store the real sequence as an ancestral one...
     // In case of Markov Modulated models, we consider that the real sequences
     // Are all in the first category.
-    const TransitionModel* model = likelihood_->getSubstitutionModel(tree_.getNodesId()[0], 0); // We assume all nodes have a model with the same number of states.
+    const TransitionModel* model = likelihood_->getModelForSite(tree_.getNodesId()[0], 0); // We assume all nodes have a model with the same number of states.
     for (size_t i = 0; i < seq.size(); i++)
     {
       (*v)[i] = model->getModelStates(seq[i])[0];
diff --git a/src/Bpp/Phyl/Likelihood/NonHomogeneousTreeLikelihood.h b/src/Bpp/Phyl/Likelihood/NonHomogeneousTreeLikelihood.h
index 83833f7..35c1325 100755
--- a/src/Bpp/Phyl/Likelihood/NonHomogeneousTreeLikelihood.h
+++ b/src/Bpp/Phyl/Likelihood/NonHomogeneousTreeLikelihood.h
@@ -6,36 +6,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 _NONHOMOGENEOUSTREELIKELIHOOD_H_
@@ -57,32 +57,33 @@ namespace bpp
  *
  * @see SubstitutionModelSet.
  */
-class NonHomogeneousTreeLikelihood :
-	public virtual TreeLikelihood
-{
-	public:
+  
+  class NonHomogeneousTreeLikelihood :
+    public virtual TreeLikelihood
+  {
+  public:
 
     NonHomogeneousTreeLikelihood* clone() const = 0;
 
   public:
-    const TransitionModel* getSubstitutionModel(int nodeId, size_t siteIndex) const throw (NodeNotFoundException)
+    const TransitionModel* getModelForSite(int nodeId, size_t siteIndex) const
     {
-      return getSubstitutionModelForNode(nodeId);
+      return getModelForNode(nodeId);
     }
 
-    TransitionModel* getSubstitutionModel(int nodeId, size_t siteIndex) throw (NodeNotFoundException)
+    TransitionModel* getModelForSite(int nodeId, size_t siteIndex)
     {
-      return getSubstitutionModelForNode(nodeId);
+      return getModelForNode(nodeId);
     }
 
     /**
-     * @brief Get the substitution model associated to a given node.
+     * @brief Get the model associated to a given node.
      *
      * @param nodeId The id of the request node.
      * @return A pointer toward the corresponding model.
      * @throw NodeNotFoundException This exception may be thrown if the node is not found (depending on the implementation).
      */
-    virtual const TransitionModel* getSubstitutionModelForNode(int nodeId) const throw (NodeNotFoundException) = 0;
+    virtual const TransitionModel* getModelForNode(int nodeId) const throw (NodeNotFoundException) = 0;
 
     /**
      * @brief Get the substitution model associated to a given node.
@@ -91,7 +92,7 @@ class NonHomogeneousTreeLikelihood :
      * @return A pointer toward the corresponding model.
      * @throw NodeNotFoundException This exception may be thrown if the node is not found (depending on the implementation).
      */
-    virtual TransitionModel* getSubstitutionModelForNode(int nodeId) throw (NodeNotFoundException) = 0;
+    virtual TransitionModel* getModelForNode(int nodeId) throw (NodeNotFoundException) = 0;
 
     /**
      * @return The set of substitution models associated to this instance.
@@ -114,7 +115,7 @@ class NonHomogeneousTreeLikelihood :
      */
     virtual ParameterList getRootFrequenciesParameters() const = 0;
 
-};
+  };
 
 } //end of namespace bpp.
 
diff --git a/src/Bpp/Phyl/Likelihood/SitePartitionTreeLikelihood.h b/src/Bpp/Phyl/Likelihood/SitePartitionTreeLikelihood.h
index ce85a32..f575257 100644
--- a/src/Bpp/Phyl/Likelihood/SitePartitionTreeLikelihood.h
+++ b/src/Bpp/Phyl/Likelihood/SitePartitionTreeLikelihood.h
@@ -61,14 +61,14 @@ class SitePartitionHomogeneousTreeLikelihood :
     SitePartitionHomogeneousTreeLikelihood* clone() const = 0;
 
   public:
-    const TransitionModel* getSubstitutionModel(int nodeId, size_t siteIndex) const throw (NodeNotFoundException)
+    const TransitionModel* getModel(int nodeId, size_t siteIndex) const throw (NodeNotFoundException)
     {
-      return getSubstitutionModelForSite(siteIndex);
+      return getModelForSite(siteIndex);
     }
 
-    TransitionModel* getSubstitutionModel(int nodeId, size_t siteIndex) throw (NodeNotFoundException)
+    TransitionModel* getModel(int nodeId, size_t siteIndex) throw (NodeNotFoundException)
     {
-      return getSubstitutionModelForSite(siteIndex);
+      return getModelForSite(siteIndex);
     }
 
     /**
@@ -77,7 +77,7 @@ class SitePartitionHomogeneousTreeLikelihood :
      * @param siteIndex The position in the alignment.
      * @return A pointer toward the corresponding model.
      */
-    virtual const TransitionModel* getSubstitutionModelForSite(size_t siteIndex) const = 0;
+    virtual const TransitionModel* getModelForSite(size_t siteIndex) const = 0;
 
     /**
      * @brief Get the substitution model associated to a given node.
@@ -85,7 +85,7 @@ class SitePartitionHomogeneousTreeLikelihood :
      * @param siteIndex The position in the alignment.
      * @return A pointer toward the corresponding model.
      */
-    virtual TransitionModel* getSubstitutionModelForSite(size_t siteIndex) = 0;
+    virtual TransitionModel* getModelForSite(size_t siteIndex) = 0;
 
 };
 
diff --git a/src/Bpp/Phyl/Likelihood/TreeLikelihood.h b/src/Bpp/Phyl/Likelihood/TreeLikelihood.h
index dd47c84..1aa0a7b 100755
--- a/src/Bpp/Phyl/Likelihood/TreeLikelihood.h
+++ b/src/Bpp/Phyl/Likelihood/TreeLikelihood.h
@@ -352,9 +352,8 @@ namespace bpp
      * @param siteIndex The index of the alignment position.
      * @see getSiteIndex
      * @return A pointer toward the corresponding model.
-     * @throw NodeNotFoundException This exception may be thrown if the node is not found (depending on the implementation).
      */
-    virtual const TransitionModel* getSubstitutionModel(int nodeId, size_t siteIndex) const throw (NodeNotFoundException) = 0;
+    virtual const TransitionModel* getModelForSite(int nodeId, size_t siteIndex) const = 0;
 
     /**
      * @brief Get the substitution model associated to a given node and alignment column.
@@ -365,7 +364,7 @@ namespace bpp
      * @return A pointer toward the corresponding model.
      * @throw NodeNotFoundException This exception may be thrown if the node is not found (depending on the implementation).
      */
-    virtual TransitionModel* getSubstitutionModel(int nodeId, size_t siteIndex) throw (NodeNotFoundException) = 0;
+    virtual TransitionModel* getModelForSite(int nodeId, size_t siteIndex) = 0;
 
     /**
      * @brief Retrieves all Pij(t) for a particular branch, defined by the upper node and site.
diff --git a/src/Bpp/Phyl/Mapping/CategorySubstitutionRegister.h b/src/Bpp/Phyl/Mapping/CategorySubstitutionRegister.h
index be5b8c6..e645794 100644
--- a/src/Bpp/Phyl/Mapping/CategorySubstitutionRegister.h
+++ b/src/Bpp/Phyl/Mapping/CategorySubstitutionRegister.h
@@ -78,7 +78,7 @@ namespace bpp
      * @param within Specifies if within categories substitutions should be counted as well.
      */
     CategorySubstitutionRegister(const SubstitutionModel* model, bool within = false) :
-      AbstractSubstitutionRegister(model),
+      AbstractSubstitutionRegister(model,"Category"),
       within_(within),
       nbCategories_(0),
       categories_(),
@@ -338,6 +338,31 @@ namespace bpp
       setAlphabetCategories<int>(categories);
     }
 
+    GCSynonymousSubstitutionRegister(const SubstitutionModel* model, const GeneticCode& gencod, bool within = false) :
+      CategorySubstitutionRegister(model, within),
+      code_(&gencod)
+    {
+      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++)
+      {
+        int n = pCA->getThirdPosition(i);
+        switch (n)
+        {
+        case 0:
+        case 3:
+          categories[i] = 1;
+          break;
+        case 1:
+        case 2:
+          categories[i] = 2;
+          break;
+        }
+      }
+      setAlphabetCategories<int>(categories);
+    }
+
     GCSynonymousSubstitutionRegister(const GCSynonymousSubstitutionRegister& reg) :
       CategorySubstitutionRegister(reg),
       code_(reg.code_)
diff --git a/src/Bpp/Phyl/Mapping/DecompositionMethods.cpp b/src/Bpp/Phyl/Mapping/DecompositionMethods.cpp
new file mode 100644
index 0000000..5e01f0e
--- /dev/null
+++ b/src/Bpp/Phyl/Mapping/DecompositionMethods.cpp
@@ -0,0 +1,300 @@
+//
+// File: DecompositionMethods.cpp
+// Created by: Laurent Guéguen
+// Created on: mardi 18 juillet 2017, à 22h 44
+//
+
+/*
+  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 "DecompositionMethods.h"
+
+#include <Bpp/Numeric/Matrix/MatrixTools.h>
+
+#include <vector>
+#include <typeinfo>
+
+using namespace std;
+
+using namespace bpp;
+
+/******************************************************************************/
+
+DecompositionMethods::DecompositionMethods(const SubstitutionModel* model, SubstitutionRegister* reg) :
+  model_(model),
+  nbStates_(model->getNumberOfStates()),
+  nbTypes_(reg->getNumberOfSubstitutionTypes()),
+  jMat_(nbStates_, nbStates_),
+  jIMat_(0,0),
+  rightEigenVectors_(0,0),
+  rightIEigenVectors_(0,0),
+  leftEigenVectors_(0,0),
+  leftIEigenVectors_(0,0),
+  bMatrices_(reg->getNumberOfSubstitutionTypes()),
+  insideProducts_(reg->getNumberOfSubstitutionTypes()),
+  insideIProducts_(0)
+{
+  setSubstitutionModel(model);
+}				
+
+
+DecompositionMethods::DecompositionMethods(const SubstitutionModel* model) :
+  model_(model),
+  nbStates_(model->getNumberOfStates()),
+  nbTypes_(1),
+  jMat_(nbStates_, nbStates_),
+  jIMat_(0,0),
+  rightEigenVectors_(0,0),
+  rightIEigenVectors_(0,0),
+  leftEigenVectors_(0,0),
+  leftIEigenVectors_(0,0),
+  bMatrices_(1),
+  insideProducts_(1),
+  insideIProducts_(0)
+{
+  setSubstitutionModel(model);
+}				
+
+void DecompositionMethods::computeProducts_()
+{
+  //vInv_ %*% bMatrices_[i] %*% v_;
+  if (model_->isDiagonalizable())
+  {
+    for (size_t i = 0; i < nbTypes_; ++i) {
+      RowMatrix<double> tmp(nbStates_, nbStates_);
+      MatrixTools::mult(model_->getRowLeftEigenVectors(), bMatrices_[i], tmp);
+      MatrixTools::mult(tmp, model_->getColumnRightEigenVectors(), insideProducts_[i]);
+    }
+  }
+  else
+  {
+    for (size_t i = 0; i < nbTypes_; ++i) {
+      //vInv_ %*% bMatrices_[i] %*% v_;
+      RowMatrix<double> tmp(nbStates_, nbStates_), itmp(nbStates_, nbStates_);
+      
+      MatrixTools::mult(leftEigenVectors_, bMatrices_[i], tmp);
+      MatrixTools::mult(leftIEigenVectors_, bMatrices_[i], itmp);
+      MatrixTools::mult(tmp, itmp, rightEigenVectors_, rightIEigenVectors_, insideProducts_[i], insideIProducts_[i]);
+    }
+  }
+}
+
+void DecompositionMethods::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 DecompositionMethods::jFunction_(const std::vector<double>& lambda, const std::vector<double>& ilambda, double t, RowMatrix<double>& result, RowMatrix<double>& iresult) const
+{
+  vector<double> expLam = VectorTools::exp(lambda * t);
+  vector<double> cosLam = expLam * VectorTools::cos(ilambda * t);
+  vector<double> sinLam = expLam * VectorTools::sin(ilambda * t);
+
+  for (unsigned int i = 0; i < nbStates_; ++i) {
+    for (unsigned int j = 0; j < nbStates_; ++j) {
+      double dd = lambda[i] - lambda[j];
+      double idd = ilambda[i] - ilambda[j];
+      if (dd == 0 && idd == 0) {
+        result(i, j) = t * cosLam[i];
+        iresult(i, j) = t * sinLam[i];
+      }
+      else
+      {
+        double es = sinLam[i] - sinLam[j];
+        double ec = cosLam[i] - cosLam[j];
+        double num = dd * dd + idd * idd;
+        
+        result(i, j) = (dd * ec + idd * es) / num;
+        iresult(i, j) = (dd * es - idd * ec) / num;
+      }
+    }
+  }
+}
+
+
+void DecompositionMethods::computeExpectations(RowMatrix<double>& mapping, double length) const
+{
+  RowMatrix<double> tmp1(nbStates_, nbStates_), tmp2(nbStates_, nbStates_);
+  if (model_->isDiagonalizable())
+  {
+    jFunction_(model_->getEigenValues(), length, jMat_);
+    
+    MatrixTools::hadamardMult(jMat_, insideProducts_[0], tmp1);
+    MatrixTools::mult(model_->getColumnRightEigenVectors(), tmp1, tmp2);
+    MatrixTools::mult(tmp2, model_->getRowLeftEigenVectors(), mapping);
+  }
+  else if (model_->isNonSingular())
+  {
+    jFunction_(model_->getEigenValues(), model_->getIEigenValues(), length, jMat_, jIMat_);
+    
+    RowMatrix<double> itmp1(nbStates_, nbStates_), itmp2(nbStates_, nbStates_);
+    RowMatrix<double> imat(nbStates_, nbStates_);
+    
+    MatrixTools::hadamardMult(jMat_, jIMat_, insideProducts_[0], insideIProducts_[0], tmp1, itmp1);
+    MatrixTools::mult(rightEigenVectors_, rightIEigenVectors_, tmp1, itmp1, tmp2, itmp2);
+    MatrixTools::mult(tmp2, itmp2, leftEigenVectors_, leftIEigenVectors_, mapping, imat);
+  }
+  else
+    throw Exception("void DecompositionMethods::computeMappings : substitution mapping is not implemented for singular generators.");
+}
+
+
+void DecompositionMethods::computeExpectations(std::vector< RowMatrix<double> >& mappings, double length) const
+{
+  RowMatrix<double> tmp1(nbStates_, nbStates_), tmp2(nbStates_, nbStates_);
+
+  if (model_->isDiagonalizable())
+  {
+    jFunction_(model_->getEigenValues(), length, jMat_);
+
+    for (size_t i = 0; i < nbTypes_; ++i) {
+      MatrixTools::hadamardMult(jMat_, insideProducts_[i], tmp1);
+      MatrixTools::mult(model_->getColumnRightEigenVectors(), tmp1, tmp2);
+      MatrixTools::mult(tmp2, model_->getRowLeftEigenVectors(), mappings[i]);
+    }
+  }
+  else if (model_->isNonSingular())
+  {
+    jFunction_(model_->getEigenValues(), model_->getIEigenValues(), length, jMat_, jIMat_);
+    
+    RowMatrix<double> itmp1(nbStates_, nbStates_), itmp2(nbStates_, nbStates_);
+    RowMatrix<double> imat(nbStates_, nbStates_);
+
+    for (size_t i = 0; i < nbTypes_; ++i) {
+      MatrixTools::hadamardMult(jMat_, jIMat_, insideProducts_[i], insideIProducts_[i], tmp1, itmp1);
+      MatrixTools::mult(rightEigenVectors_, rightIEigenVectors_, tmp1, itmp1, tmp2, itmp2);
+      MatrixTools::mult(tmp2, itmp2, leftEigenVectors_, leftIEigenVectors_, mappings[i], imat);
+    }
+  }
+  else
+    throw Exception("void DecompositionMethods::computeMappings : substitution mapping is not implemented for singular generators.");
+
+} 
+
+
+void DecompositionMethods::initStates_()
+{
+  jMat_.resize(nbStates_, nbStates_);
+}
+
+/******************************************************************************/
+
+void DecompositionMethods::setSubstitutionModel(const SubstitutionModel* model)
+{
+  model_ = model;
+  size_t n = model->getNumberOfStates();
+  if (n != nbStates_)
+  {
+    nbStates_ = n;
+    jMat_.resize(nbStates_, nbStates_);
+    initBMatrices_();
+  }
+  
+  if (!model_->isDiagonalizable())
+  {
+    jIMat_.resize(nbStates_, nbStates_);
+    insideIProducts_.resize(nbTypes_);
+    for (size_t i = 0; i < nbTypes_; ++i) 
+      insideIProducts_[i].resize(nbStates_, nbStates_);
+
+    // sets the imaginary parts of the eigenvectors
+    if (rightEigenVectors_.getNumberOfRows()!=nbStates_)
+    {
+      rightEigenVectors_.resize(nbStates_,nbStates_);
+      leftEigenVectors_.resize(nbStates_,nbStates_);
+      rightIEigenVectors_.resize(nbStates_,nbStates_);
+      leftIEigenVectors_.resize(nbStates_,nbStates_);
+    }
+
+    const ColMatrix<double>& rEV=model_->getColumnRightEigenVectors();
+    const RowMatrix<double>& lEV=model_->getRowLeftEigenVectors();
+    const vector<double>& vi=model_->getIEigenValues();
+
+    for (size_t i=0; i<nbStates_; i++)
+    {
+      if (vi[i]==0)
+      {
+        rightEigenVectors_.getCol(i)=rEV.col(i);
+        VectorTools::fill(rightIEigenVectors_.getCol(i),0.);
+        leftEigenVectors_.getRow(i)=lEV.row(i);
+        VectorTools::fill(leftIEigenVectors_.getRow(i),0.);
+      }
+      else if (vi[i]>0)
+      {
+        rightEigenVectors_.getCol(i)=rEV.col(i);
+        rightIEigenVectors_.getCol(i)=rEV.col(i+1);
+        leftEigenVectors_.getRow(i)=lEV.row(i)/2;
+        leftIEigenVectors_.getRow(i)=lEV.row(i+1)*(-1./2);
+      }
+      else
+      {
+        rightEigenVectors_.getCol(i)=rEV.col(i-1);
+        rightIEigenVectors_.getCol(i)=rEV.col(i)*(-1);
+        leftEigenVectors_.getRow(i)=lEV.row(i-1)/2;
+        leftIEigenVectors_.getRow(i)=lEV.row(i)/2;
+      }
+    }
+  }
+}
+
+void DecompositionMethods::initBMatrices_()
+{
+  //Re-initialize all B matrices according to substitution register.
+  bMatrices_.resize(nbTypes_);
+  insideProducts_.resize(nbTypes_);
+  
+  for (size_t i = 0; i < nbTypes_; ++i) {
+    bMatrices_[i].resize(nbStates_, nbStates_);
+    insideProducts_[i].resize(nbStates_, nbStates_);
+  }
+
+  if (!model_->isDiagonalizable())
+  {
+    insideIProducts_.resize(nbTypes_);
+    for (size_t i = 0; i < nbTypes_; ++i) 
+      insideIProducts_[i].resize(nbStates_, nbStates_);
+  }
+}
+
+
+
diff --git a/src/Bpp/Phyl/Mapping/DecompositionMethods.h b/src/Bpp/Phyl/Mapping/DecompositionMethods.h
new file mode 100644
index 0000000..98072d9
--- /dev/null
+++ b/src/Bpp/Phyl/Mapping/DecompositionMethods.h
@@ -0,0 +1,174 @@
+//
+// File: DecompositionMethods.h
+// Created by: Laurent Guéguen
+// Created on: mardi 18 juillet 2017, à 22h 42
+//
+
+/*
+  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 _DECOMPOSITION_METHODS_H_
+#define _DECOMPOSITION_METHODS_H_
+
+#include <Bpp/Numeric/Matrix/Matrix.h>
+#include <Bpp/Numeric/Matrix/MatrixTools.h>
+
+#include "../Model/SubstitutionModel.h"
+#include "SubstitutionRegister.h"
+
+namespace bpp
+{
+
+/**
+ * @brief Methods useful for analytical substitution count and rewards
+ * using the eigen decomposition method.
+ *
+ * The code is adapted from the original R code by Paula Tataru and
+ * Asger Hobolth.
+ *
+ * @author Julien Dutheil, Laurent Guéguen
+ */
+
+  class DecompositionMethods
+  {
+  protected:
+    const SubstitutionModel* model_;
+    size_t nbStates_;
+    size_t nbTypes_;
+    mutable RowMatrix<double> jMat_, jIMat_;
+
+    /*
+     * @brief Real and imaginary eigenvectors, for non-reversible
+     * computation
+     */
+    
+    ColMatrix<double> rightEigenVectors_, rightIEigenVectors_;
+    RowMatrix<double> leftEigenVectors_, leftIEigenVectors_;
+
+    /*
+     * @brief computation matrices
+     *
+     */
+    
+    std::vector< RowMatrix<double> > bMatrices_, insideProducts_, insideIProducts_;
+    
+  public:
+    DecompositionMethods(const SubstitutionModel* model, SubstitutionRegister* reg);
+
+    DecompositionMethods(const SubstitutionModel* model);
+
+    DecompositionMethods(const DecompositionMethods& dm) :
+      model_(dm.model_),
+      nbStates_(dm.nbStates_),
+      nbTypes_(dm.nbTypes_),
+      jMat_(dm.jMat_),
+      jIMat_(dm.jIMat_),
+      rightEigenVectors_(dm.rightEigenVectors_),
+      rightIEigenVectors_(dm.rightIEigenVectors_),
+      leftEigenVectors_(dm.leftEigenVectors_),
+      leftIEigenVectors_(dm.leftIEigenVectors_),
+      bMatrices_(dm.bMatrices_),
+      insideProducts_(dm.insideProducts_),
+      insideIProducts_(dm.insideIProducts_)
+    {}				
+    
+    DecompositionMethods& operator=(const DecompositionMethods& dm)
+    {
+      model_          = dm.model_;
+      nbStates_       = dm.nbStates_;
+      nbTypes_        = dm.nbTypes_;
+      jMat_           = dm.jMat_;
+      jIMat_          = dm.jIMat_;
+      
+      rightEigenVectors_ = dm.rightEigenVectors_;
+      rightIEigenVectors_ = dm.rightIEigenVectors_;
+      leftEigenVectors_ = dm.leftEigenVectors_;
+      leftIEigenVectors_ = dm.leftIEigenVectors_;
+      bMatrices_      = dm.bMatrices_;
+      insideProducts_ = dm.insideProducts_;
+      insideIProducts_ =  dm.insideIProducts_;
+      
+      return *this;
+    }				
+    
+    DecompositionMethods* clone() const { return new DecompositionMethods(*this); }
+
+    virtual ~DecompositionMethods() {};
+
+
+    /**
+     * @brief Set the substitution model.
+     *
+     * @param model A pointer toward the substitution model to use.
+     */
+    
+    void setSubstitutionModel(const SubstitutionModel* model);
+
+
+  protected:
+
+    void initStates_();
+    
+    void initBMatrices_();
+
+    void computeProducts_();
+
+    /*
+     * @brief Perform the computation of the conditional expectations
+     *
+     */
+
+    void computeExpectations(RowMatrix<double>& mapping, double length) const;
+
+    void computeExpectations(std::vector< RowMatrix<double> >& mappings, double leangth) const;
+
+    /**
+     * @brief Compute the integral part of the computation
+     *
+     */
+    
+    void jFunction_(const std::vector<double>& lambda, double t, RowMatrix<double>& result) const;
+
+    /**
+     * @brief Compute the integral part of the computation, in complex numbers
+     *
+     */
+    
+    void jFunction_(const std::vector<double>& lambda, const std::vector<double>& ilambda, double t, RowMatrix<double>& result, RowMatrix<double>& iresult) const;
+    
+  };
+
+} //end of namespace bpp.
+
+#endif // _DECOMPOSITION_METHODS_H_
+
diff --git a/src/Bpp/Phyl/Mapping/DecompositionReward.cpp b/src/Bpp/Phyl/Mapping/DecompositionReward.cpp
index 5a7cb72..21c4888 100644
--- a/src/Bpp/Phyl/Mapping/DecompositionReward.cpp
+++ b/src/Bpp/Phyl/Mapping/DecompositionReward.cpp
@@ -41,6 +41,7 @@ knowledge of the CeCILL license and that you accept its terms.
 
 #include "Bpp/Numeric/Matrix/MatrixTools.h"
 #include <vector>
+#include <typeinfo>
 
 using namespace bpp;
 using namespace std;
@@ -49,95 +50,52 @@ 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_),
-  bMatrice_(nbStates_, nbStates_),
-  insideProduct_(nbStates_, nbStates_),
+  DecompositionMethods(model),
   rewards_(nbStates_, nbStates_),
   currentLength_(-1.)
 {
   //Check compatiblity between model and alphabet Index:
-  if (model->getAlphabet()->getAlphabetType() != alphIndex_->getAlphabet()->getAlphabetType())
+  if (typeid(model->getAlphabet()) != typeid(alphIndex_->getAlphabet()))
     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_();
+
+  initBMatrices_();
+  initRewards_();
+  
+  fillBMatrice_();
   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_()
+void DecompositionReward::initRewards_()
 {
-  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
+/******************************************************************************/
+
+void DecompositionReward::fillBMatrice_()
 {
-  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;
-      }
-    }
-  }
+  vector<int> supportedStates = model_->getAlphabetStates();
+  for (size_t j = 0; j < nbStates_; ++j) 
+    bMatrices_[0](j, j) = getAlphabetIndex()->getIndex(supportedStates[j]);
 }
 
 /******************************************************************************/
 
 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_);
+  computeExpectations(rewards_, length);
 
   // 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 (std::isnan(rewards_(j, k)))
+      if (std::isnan(rewards_(j, k)) || std::isnan(-rewards_(j, k)) || std::isinf(rewards_(j, k)))
         rewards_(j, k) = 0.;
     }
   }
@@ -150,10 +108,10 @@ 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;
-    }
+  {
+    computeRewards_(length);
+    currentLength_ = length;
+  }
   return new RowMatrix<double>(rewards_);
 }
 
@@ -175,35 +133,31 @@ double DecompositionReward::getReward(size_t initialState, size_t finalState, do
 
 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())
+  if (typeid(model->getAlphabet()) != typeid(alphIndex_->getAlphabet()))
     throw Exception("DecompositionReward::setSubstitutionModel: alphabets do not match between alphabet index and model.");
-  model_ = rModel;
-  size_t n = model->getNumberOfStates();
-  if (n != nbStates_) {
-    nbStates_ = n;
-    resetStates_();
-  }
-  computeEigen_();
+
+  DecompositionMethods::setSubstitutionModel(model);
+
+  initRewards_();
+  
+  fillBMatrice_();  
   computeProducts_();
 
   //Recompute rewards:
+
   computeRewards_(currentLength_);
 }
 
 /******************************************************************************/
 
-void DecompositionReward::alphabetIndexHasChanged() throw (Exception)
+void DecompositionReward::alphabetIndexHasChanged()
 {
   //Check compatiblity between model and substitution register:
-  if (model_->getAlphabet()->getAlphabetType() != alphIndex_->getAlphabet()->getAlphabetType())
+  if (typeid(model_->getAlphabet()) != typeid(alphIndex_->getAlphabet()))
     throw Exception("DecompositionReward::AlphabetIndexHasChanged: alphabets do not match between alphbaet index and model.");
 
-  computeBMatrice_();
+  fillBMatrice_();
   computeProducts_();
 
   //Recompute rewards:
diff --git a/src/Bpp/Phyl/Mapping/DecompositionReward.h b/src/Bpp/Phyl/Mapping/DecompositionReward.h
index acbfde4..fe82cea 100644
--- a/src/Bpp/Phyl/Mapping/DecompositionReward.h
+++ b/src/Bpp/Phyl/Mapping/DecompositionReward.h
@@ -5,36 +5,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.
+  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_
@@ -42,7 +42,7 @@ knowledge of the CeCILL license and that you accept its terms.
 
 #include "Reward.h"
 
-#include <Bpp/Numeric/Matrix/Matrix.h>
+#include "DecompositionMethods.h"
 
 namespace bpp
 {
@@ -62,81 +62,63 @@ namespace bpp
  * @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_;
+  class DecompositionReward:
+    public AbstractReward,
+    public DecompositionMethods
+  {
+  private:
+    mutable RowMatrix<double> rewards_;
+    mutable double currentLength_;
 	
-public:
-  DecompositionReward(const SubstitutionModel* model, AlphabetIndex1* alphIndex);
+  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(const DecompositionReward& dr) :
+      AbstractReward(dr),
+      DecompositionMethods(dr),
+      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;
-  }				
+    DecompositionReward& operator=(const DecompositionReward& dr)
+    {
+      AbstractReward::operator=(dr);
+      DecompositionMethods::operator=(dr);
+
+      rewards_        = dr.rewards_;
+      currentLength_  = dr.currentLength_;
+      return *this;
+    }				
 		
-  virtual ~DecompositionReward() {}
+    virtual ~DecompositionReward() {}
 		
-  DecompositionReward* clone() const { return new DecompositionReward(*this); }
+    DecompositionReward* clone() const { return new DecompositionReward(*this); }
 
-public:
-  double getReward(size_t initialState, size_t finalState, double length) const;
+  public:
+    double getReward(size_t initialState, size_t finalState, double length) const;
 
-  Matrix<double>* getAllRewards(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_();
-};
+    /**
+     * @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 initRewards_();
+    
+    void computeRewards_(double length) const;
+
+    void alphabetIndexHasChanged();
+
+  private:
+    void fillBMatrice_();
+  };
 
 } //end of namespace bpp.
 
diff --git a/src/Bpp/Phyl/Mapping/DecompositionSubstitutionCount.cpp b/src/Bpp/Phyl/Mapping/DecompositionSubstitutionCount.cpp
index f457e75..7d8e9a9 100644
--- a/src/Bpp/Phyl/Mapping/DecompositionSubstitutionCount.cpp
+++ b/src/Bpp/Phyl/Mapping/DecompositionSubstitutionCount.cpp
@@ -41,39 +41,41 @@
 
 #include "Bpp/Numeric/Matrix/MatrixTools.h"
 #include <vector>
+#include <typeinfo>
 
 using namespace bpp;
 using namespace std;
 
 /******************************************************************************/
 
-DecompositionSubstitutionCount::DecompositionSubstitutionCount(const ReversibleSubstitutionModel* model, SubstitutionRegister* reg, const AlphabetIndex2* weights) :
+DecompositionSubstitutionCount::DecompositionSubstitutionCount(const SubstitutionModel* model, SubstitutionRegister* reg, const AlphabetIndex2* weights) :
   AbstractSubstitutionCount(reg),
   AbstractWeightedSubstitutionCount(weights, true),
-  model_(model),
-  nbStates_(model->getNumberOfStates()),
-  jMat_(nbStates_, nbStates_),
-  v_(nbStates_, nbStates_),
-  vInv_(nbStates_, nbStates_),
-  lambda_(nbStates_),
-  bMatrices_(reg->getNumberOfSubstitutionTypes()),
-  insideProducts_(reg->getNumberOfSubstitutionTypes()),
+  DecompositionMethods(model, reg),
   counts_(reg->getNumberOfSubstitutionTypes()),
-  currentLength_(-1.)
+  currentLength_(0)
 {
   //Check compatiblity between model and substitution register:
-  if (model->getAlphabet()->getAlphabetType() != reg->getAlphabet()->getAlphabetType())
+  if (typeid(model->getAlphabet())!=typeid(reg->getAlphabet()))
     throw Exception("DecompositionSubstitutionCount (constructor): alphabets do not match between register and model.");
 
-  //Initialize all B matrices according to substitution register. This is done once for all,
-  //unless the number of states changes:
   initBMatrices_();
+  initCounts_();
+
   fillBMatrices_();
-  computeEigen_();
   computeProducts_();
-}				
-    
-/******************************************************************************/
+}
+
+void DecompositionSubstitutionCount::initCounts_()
+{
+  counts_.resize(register_->getNumberOfSubstitutionTypes());
+  //Re-initialize all count matrices according to substitution register.
+  for (size_t i = 0; i < register_->getNumberOfSubstitutionTypes(); ++i) {
+    counts_[i].resize(nbStates_, nbStates_);
+  }
+}
+
+/*************************************************/
 
 void DecompositionSubstitutionCount::fillBMatrices_()
 {
@@ -82,91 +84,27 @@ void DecompositionSubstitutionCount::fillBMatrices_()
     for (size_t k = 0; k < nbStates_; ++k) {
       size_t i = register_->getType(j, k);
       if (i > 0 && k != j) {
-        //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);
       }
     }
   }
 }
 
-void DecompositionSubstitutionCount::computeEigen_()
-{
-  v_      = model_->getColumnRightEigenVectors();
-  vInv_   = model_->getRowLeftEigenVectors();
-  lambda_ = model_->getEigenValues();
-}
-
-void DecompositionSubstitutionCount::computeProducts_()
-{
-  for (size_t i = 0; i < register_->getNumberOfSubstitutionTypes(); ++i) {
-    //vInv_ %*% bMatrices_[i] %*% v_;
-    RowMatrix<double> tmp(nbStates_, nbStates_);
-    MatrixTools::mult(vInv_, bMatrices_[i], tmp);
-    MatrixTools::mult(tmp, v_, insideProducts_[i]);
-  }
-}
-
-void DecompositionSubstitutionCount::resetBMatrices_()
-{
-  size_t nbTypes = register_->getNumberOfSubstitutionTypes();
-  bMatrices_.resize(nbTypes);
-  insideProducts_.resize(nbTypes);
-  counts_.resize(nbTypes);
-}
-
-void DecompositionSubstitutionCount::resetStates_()
-{
-  jMat_.resize(nbStates_, nbStates_);
-  v_.resize(nbStates_, nbStates_);
-  vInv_.resize(nbStates_, nbStates_);
-  lambda_.resize(nbStates_);
-}
-
-void DecompositionSubstitutionCount::initBMatrices_()
-{
-  //Re-initialize all B matrices according to substitution register.
-  for (size_t i = 0; i < register_->getNumberOfSubstitutionTypes(); ++i) {
-    bMatrices_[i].resize(nbStates_, nbStates_);
-    insideProducts_[i].resize(nbStates_, nbStates_);
-    counts_[i].resize(nbStates_, nbStates_);
-  }
-}
-
-void DecompositionSubstitutionCount::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 DecompositionSubstitutionCount::computeCounts_(double length) const
 {
-  jFunction_(lambda_, length, jMat_);
-  for (size_t i = 0; i < register_->getNumberOfSubstitutionTypes(); ++i) {
-    RowMatrix<double> tmp1(nbStates_, nbStates_), tmp2(nbStates_, nbStates_);
-    MatrixTools::hadamardMult(jMat_, insideProducts_[i], tmp1);
-    MatrixTools::mult(v_, tmp1, tmp2);
-    MatrixTools::mult(tmp2, vInv_, counts_[i]);
-  }
+  computeExpectations(counts_, length);
+
   // 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 i = 0; i < nbTypes_; 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 (std::isnan(counts_[i](j, k)) || counts_[i](j, k) < 0.) {
+        if (std::isinf(counts_[i](j, k)) || std::isnan(counts_[i](j, k)) || counts_[i](j, k) < 0.) {
           counts_[i](j, k) = 0.;
           //Weights:
           if (weights_)
@@ -185,23 +123,7 @@ Matrix<double>* DecompositionSubstitutionCount::getAllNumbersOfSubstitutions(dou
     throw Exception("DecompositionSubstitutionCount::getAllNumbersOfSubstitutions. Negative branch length: " + TextTools::toString(length) + ".");
   if (length != currentLength_)
   {
-    //if (length < 0.000001) // Limit case!
-    //{ 
-    //  unsigned int s = model_->getAlphabet()->getSize();
-    //  for (unsigned int i = 0; i < s; i++)
-    //  {
-    //    for (unsigned int j = 0; j < s; j++)
-    //    {
-    //      m_(i, j) = i == j ? 0. : 1.;
-    //    }
-    //  }
-    //}
-    //else
-    //{
-    // Else we need to recompute M:
     computeCounts_(length);
-    //}
-
     currentLength_ = length;
   }
   return new RowMatrix<double>(counts_[type - 1]);
@@ -243,24 +165,17 @@ std::vector<double> DecompositionSubstitutionCount::getNumberOfSubstitutionsForE
 
 void DecompositionSubstitutionCount::setSubstitutionModel(const SubstitutionModel* model)
 {
-  const ReversibleSubstitutionModel* rModel = dynamic_cast<const ReversibleSubstitutionModel*>(model);
-  if (!rModel)
-    throw Exception("DecompositionSubstitutionCount::setSubstitutionModel. Only works with reversible models for now.");
-
   //Check compatiblity between model and substitution register:
-  if (model->getAlphabet()->getAlphabetType() != register_->getAlphabet()->getAlphabetType())
-    throw Exception("DecompositionSubstitutionCount::setSubstitutionModel: alphabets do not match between register and model.");
-  model_ = rModel;
-  size_t n = model->getNumberOfStates();
-  if (n != nbStates_) {
-    nbStates_ = n;
-    resetStates_();
-    initBMatrices_();
-  }
+  if (typeid(model->getAlphabet()) != typeid(register_->getAlphabet()))
+    throw Exception("DecompositionMethods::setSubstitutionModel: alphabets do not match between register and model.");
+
+  DecompositionMethods::setSubstitutionModel(model);
+
+  initCounts_();
+  
   fillBMatrices_();
-  computeEigen_();
   computeProducts_();
-
+  
   //Recompute counts:
   computeCounts_(currentLength_);
 }
@@ -269,15 +184,18 @@ void DecompositionSubstitutionCount::setSubstitutionModel(const SubstitutionMode
 
 void DecompositionSubstitutionCount::substitutionRegisterHasChanged() throw (Exception)
 {
-  //Check compatiblity between model and substitution register:
+//Check compatiblity between model and substitution register:
   if (model_->getAlphabet()->getAlphabetType() != register_->getAlphabet()->getAlphabetType())
-    throw Exception("DecompositionSubstitutionCount::substitutionRegisterHasChanged: alphabets do not match between register and model.");
+    throw Exception("DecompositionMethods::substitutionRegisterHasChanged: alphabets do not match between register and model.");
 
-  resetBMatrices_();
   initBMatrices_();
+  initStates_();
+  
+  initCounts_();
+
   fillBMatrices_();
   computeProducts_();
-
+  
   //Recompute counts:
   if (currentLength_ > 0)
     computeCounts_(currentLength_);
@@ -287,12 +205,9 @@ void DecompositionSubstitutionCount::substitutionRegisterHasChanged() throw (Exc
 
 void DecompositionSubstitutionCount::weightsHaveChanged() throw (Exception)
 {
-  if (weights_->getAlphabet()->getAlphabetType() != register_->getAlphabet()->getAlphabetType())
+  if (typeid(weights_->getAlphabet()) != typeid(register_->getAlphabet()))
     throw Exception("DecompositionSubstitutionCount::weightsHaveChanged. Incorrect alphabet type.");
 
-  //jdutheil on 25/07/14: not necessary if weights are only accounted for in the end.
-  //fillBMatrices_();
-  
   //Recompute counts:
   if (currentLength_ > 0)
     computeCounts_(currentLength_);
diff --git a/src/Bpp/Phyl/Mapping/DecompositionSubstitutionCount.h b/src/Bpp/Phyl/Mapping/DecompositionSubstitutionCount.h
index 8f8ea63..003518e 100644
--- a/src/Bpp/Phyl/Mapping/DecompositionSubstitutionCount.h
+++ b/src/Bpp/Phyl/Mapping/DecompositionSubstitutionCount.h
@@ -41,6 +41,7 @@ knowledge of the CeCILL license and that you accept its terms.
 #define _DECOMPOSITIONSUBSTITUTIONCOUNT_H_
 
 #include "WeightedSubstitutionCount.h"
+#include "DecompositionMethods.h"
 
 #include <Bpp/Numeric/Matrix/Matrix.h>
 
@@ -51,37 +52,25 @@ namespace bpp
  * @brief Analytical substitution count using the eigen decomposition method.
  *
  * The codes is adapted from the original R code by Paula Tataru and Asger Hobolth.
- * Only reversible models are supported for now.
  *
  * @author Julien Dutheil
  */
   class DecompositionSubstitutionCount:
     public AbstractSubstitutionCount,
-    public AbstractWeightedSubstitutionCount
+    public AbstractWeightedSubstitutionCount,
+    public DecompositionMethods
   {
   private:
-    const ReversibleSubstitutionModel* model_;
-    size_t nbStates_;
-    mutable RowMatrix<double> jMat_, v_, vInv_;
-    mutable std::vector<double> lambda_;
-    std::vector< RowMatrix<double> > bMatrices_, insideProducts_;
     mutable std::vector< RowMatrix<double> > counts_;
     mutable double currentLength_;
-	
+
   public:
-    DecompositionSubstitutionCount(const ReversibleSubstitutionModel* model, SubstitutionRegister* reg, const AlphabetIndex2* weights = 0);
+    DecompositionSubstitutionCount(const SubstitutionModel* model, SubstitutionRegister* reg, const AlphabetIndex2* weights = 0);
 		
     DecompositionSubstitutionCount(const DecompositionSubstitutionCount& dsc) :
       AbstractSubstitutionCount(dsc),
       AbstractWeightedSubstitutionCount(dsc),
-      model_(dsc.model_),
-      nbStates_(dsc.nbStates_),
-      jMat_(dsc.jMat_),
-      v_(dsc.v_),
-      vInv_(dsc.vInv_),
-      lambda_(dsc.lambda_),
-      bMatrices_(dsc.bMatrices_),
-      insideProducts_(dsc.insideProducts_),
+      DecompositionMethods(dsc),
       counts_(dsc.counts_),
       currentLength_(dsc.currentLength_)
     {}				
@@ -90,14 +79,7 @@ namespace bpp
     {
       AbstractSubstitutionCount::operator=(dsc);
       AbstractWeightedSubstitutionCount::operator=(dsc);
-      model_          = dsc.model_;
-      nbStates_       = dsc.nbStates_;
-      jMat_           = dsc.jMat_;
-      v_              = dsc.v_;
-      vInv_           = dsc.vInv_;
-      lambda_         = dsc.lambda_;
-      bMatrices_      = dsc.bMatrices_;
-      insideProducts_ = dsc.insideProducts_;
+      DecompositionMethods::operator=(dsc);
       counts_         = dsc.counts_;
       currentLength_  = dsc.currentLength_;
       return *this;
@@ -117,23 +99,24 @@ namespace bpp
     /**
      * @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.
+     * @param model A pointer toward the substitution model to use.
      */
+
     void setSubstitutionModel(const SubstitutionModel* model);
 
   protected:
+
+    void initCounts_();
+
     void computeCounts_(double length) const;
-    void jFunction_(const std::vector<double>& lambda, double t, RowMatrix<double>& result) const;
+
     void substitutionRegisterHasChanged() throw (Exception);
+
     void weightsHaveChanged() throw (Exception);
 
   private:
-    void resetStates_();
-    void resetBMatrices_();
-    void initBMatrices_();
     void fillBMatrices_();
-    void computeEigen_();
-    void computeProducts_();
+
   };
 
 } //end of namespace bpp.
diff --git a/src/Bpp/Phyl/Mapping/RewardMappingTools.cpp b/src/Bpp/Phyl/Mapping/RewardMappingTools.cpp
index 5aaea56..4f52d82 100644
--- a/src/Bpp/Phyl/Mapping/RewardMappingTools.cpp
+++ b/src/Bpp/Phyl/Mapping/RewardMappingTools.cpp
@@ -332,9 +332,8 @@ ProbabilisticRewardMapping* RewardMappingTools::computeRewardVectors(
 
     // 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)
   {
diff --git a/src/Bpp/Phyl/Mapping/SubstitutionMappingTools.cpp b/src/Bpp/Phyl/Mapping/SubstitutionMappingTools.cpp
index 2ce3fd1..2753440 100644
--- a/src/Bpp/Phyl/Mapping/SubstitutionMappingTools.cpp
+++ b/src/Bpp/Phyl/Mapping/SubstitutionMappingTools.cpp
@@ -288,6 +288,7 @@ ProbabilisticSubstitutionMapping* SubstitutionMappingTools::computeSubstitutionV
         {
           VVdouble* nxy_c_t = &(*nxy_c)[t];
           Matrix<double>* nijt = substitutionCount.getAllNumbersOfSubstitutions(d * rc, t + 1);
+           
           nxy_c_t->resize(nbStates);
           for (size_t x = 0; x < nbStates; ++x)
           {
@@ -345,6 +346,7 @@ ProbabilisticSubstitutionMapping* SubstitutionMappingTools::computeSubstitutionV
               }
             }
           }
+          
         }
       }
     }
@@ -1356,9 +1358,8 @@ vector<double> SubstitutionMappingTools::computeTotalSubstitutionVectorForSitePe
   {
     v[t] = 0;
     for (size_t l = 0; l < nbBranches; ++l)
-    {
       v[t] += smap(l, siteIndex, t);
-    }
+
   }
   return v;
 }
@@ -1612,10 +1613,6 @@ vector< vector<double> > SubstitutionMappingTools::getNormalizationsPerBranch(
     }
   }
 
-  const WordAlphabet* wAlp=dynamic_cast<const WordAlphabet*>(nullModel->getAlphabet());
-  
-  float sizeWord=float(wAlp?wAlp->getLength():1);
-  
   // compute the normalization for each substitutionType
   vector< vector<double> > rewards(ids.size());
 
@@ -1645,7 +1642,7 @@ vector< vector<double> > SubstitutionMappingTools::getNormalizationsPerBranch(
         }
         s += tmp;
       }
-      rewards[k][nbt] = s*sizeWord;
+      rewards[k][nbt] = s;
     }
     reward.reset();
     mapping.reset();
@@ -1678,9 +1675,6 @@ vector< vector<double> > SubstitutionMappingTools::getNormalizationsPerBranch(
 
   vector<UserAlphabetIndex1 >  usai(nbTypes, UserAlphabetIndex1(nullModelSet->getAlphabet()));
 
-  const WordAlphabet* wAlp=dynamic_cast<const WordAlphabet*>(nullModelSet->getAlphabet());
-  float sizeWord=float(wAlp?wAlp->getLength():1);
-
   for (size_t nbm = 0; nbm < nbModels; nbm++)
   {
     vector<int> mids = VectorTools::vectorIntersection(ids, nullModelSet->getNodesWithModel(nbm));
@@ -1730,7 +1724,7 @@ vector< vector<double> > SubstitutionMappingTools::getNormalizationsPerBranch(
               s += tmp;
           }
           
-          rewards[VectorTools::which(ids, mids[k])][nbt] = s * sizeWord;
+          rewards[VectorTools::which(ids, mids[k])][nbt] = s;
         }
         reward.reset();
         mapping.reset();
@@ -1738,111 +1732,136 @@ vector< vector<double> > SubstitutionMappingTools::getNormalizationsPerBranch(
     }
   }
 
+
   return rewards;
 }
 
 /**************************************************************************************************/
 
-vector< vector<double> > SubstitutionMappingTools::getNormalizedCountsPerBranch(
+void SubstitutionMappingTools::computeCountsPerTypePerBranch(
   DRTreeLikelihood& drtl,
   const vector<int>& ids,
   SubstitutionModel* model,
   SubstitutionModel* nullModel,
   const SubstitutionRegister& reg,
+  VVdouble& result,
+  bool perTime,
+  bool perWord,
   bool verbose)
 {
-  vector< vector<double> > counts;
   vector< vector<double> > factors;
 
-  counts = getCountsPerBranch(drtl, ids, model, reg, -1, verbose);
+  result = getCountsPerBranch(drtl, ids, model, reg, -1, verbose);
   factors = getNormalizationsPerBranch(drtl, ids, nullModel, reg, verbose);
 
-  size_t nbTypes = counts[0].size();
+
+  // check if perWord
+
+  const CoreWordAlphabet* wAlp=dynamic_cast<const CoreWordAlphabet*>(nullModel->getAlphabet());
+
+  float sizeWord=float((wAlp!=NULL) & !perWord ?wAlp->getLength():1);
+  
+
+  size_t nbTypes = result[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];
+        result[k][t] /= (factors[k][t]*sizeWord);
     }
   }
 
   // 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)
+  if (!perTime)
   {
-    double l = tree.getNode(ids[k])->getDistanceToFather();
-    for (size_t t = 0; t < nbTypes; ++t)
+    const TreeTemplate<Node> tree(drtl.getTree());
+
+    for (size_t k = 0; k < ids.size(); ++k)
     {
-      counts[k][t] *= l;
+      double l = tree.getNode(ids[k])->getDistanceToFather();
+      for (size_t t = 0; t < nbTypes; ++t)
+      {
+        result[k][t] *= l;
+      }
     }
   }
-
-  return counts;
+  
 }
 
 /**************************************************************************************************/
 
-vector< vector<double> > SubstitutionMappingTools::getNormalizedCountsPerBranch(
+void SubstitutionMappingTools::computeCountsPerTypePerBranch(
   DRTreeLikelihood& drtl,
   const vector<int>& ids,
   SubstitutionModelSet* modelSet,
   SubstitutionModelSet* nullModelSet,
   const SubstitutionRegister& reg,
+  VVdouble& result,
+  bool perTime,
+  bool perWord,
   bool verbose)
 {
-  vector< vector<double> > counts;
   vector< vector<double> > factors;
 
-  counts = getCountsPerBranch(drtl, ids, modelSet->getSubstitutionModel(0), reg, -1, verbose);
+  result = getCountsPerBranch(drtl, ids, *modelSet, reg, -1, verbose);
   factors = getNormalizationsPerBranch(drtl, ids, nullModelSet, reg, verbose);
 
-  size_t nbTypes = counts[0].size();
+  size_t nbTypes = result[0].size();
+
+  // check if perWord
+
+  const CoreWordAlphabet* wAlp=dynamic_cast<const CoreWordAlphabet*>(nullModelSet->getAlphabet());
+
+  float sizeWord=float((wAlp!=NULL) & !perWord?wAlp->getLength():1);
+  
 
   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];
+        result[k][t] /= (factors[k][t]*sizeWord);
     }
   }
 
   // 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)
+  if (!perTime)
   {
-    double l = tree.getNode(ids[k])->getDistanceToFather();
-    for (size_t t = 0; t < nbTypes; ++t)
+    const TreeTemplate<Node> tree(drtl.getTree());
+
+    for (size_t k = 0; k < ids.size(); ++k)
     {
-      counts[k][t] *= l;
+      double l = tree.getNode(ids[k])->getDistanceToFather();
+      for (size_t t = 0; t < nbTypes; ++t)
+      {
+        result[k][t] *= l;
+      }
     }
   }
-
-  return counts;
 }
 
 /**************************************************************************************************/
 
-vector< vector<double> > SubstitutionMappingTools::getRelativeCountsPerBranch(
+void SubstitutionMappingTools::computeCountsPerTypePerBranch(
   DRTreeLikelihood& drtl,
   const vector<int>& ids,
   SubstitutionModel* model,
   const SubstitutionRegister& reg,
-  double threshold)
+  VVdouble& result,
+  double threshold,
+  bool verbose)
 {
-  vector< vector<double> > counts = getCountsPerBranch(drtl, ids, model, reg, threshold);
+  result = getCountsPerBranch(drtl, ids, model, reg, threshold, verbose);
 
   const CategorySubstitutionRegister* creg = dynamic_cast<const CategorySubstitutionRegister*>(&reg);
 
   if ((creg!=NULL) && !creg->isStationary())
   {
-    size_t nbTypes = counts[0].size();
+    size_t nbTypes = result[0].size();
 
     for (size_t k = 0; k < ids.size(); ++k)
     {
@@ -1856,84 +1875,612 @@ vector< vector<double> > SubstitutionMappingTools::getRelativeCountsPerBranch(
       }
 
       // We devide the counts by the frequencies and rescale:
-      double s = VectorTools::sum(counts[k]);
+      double s = VectorTools::sum(result[k]);
       for (size_t t = 0; t < nbTypes; ++t)
       {
-        counts[k][t] /= freqsTypes[creg->getCategoryFrom(t + 1) - 1];
+        result[k][t] /= freqsTypes[creg->getCategoryFrom(t + 1) - 1];
       }
 
-      double s2 = VectorTools::sum(counts[k]);
+      double s2 = VectorTools::sum(result[k]);
       // Scale:
-      counts[k] = (counts[k] / s2) * s;
+      result[k] = (result[k] / s2) * s;
     }
   }
-
-  return counts;
 }
 
 /**************************************************************************************************/
 
-void SubstitutionMappingTools::outputTotalCountsPerBranchPerSite(
-  string& filename,
+void SubstitutionMappingTools::computeCountsPerSitePerBranch(
   DRTreeLikelihood& drtl,
   const vector<int>& ids,
   SubstitutionModel* model,
-  const SubstitutionRegister& reg)
+  const SubstitutionRegister& reg,
+  VVdouble& result)
 {
   unique_ptr<SubstitutionCount> count(new UniformizationSubstitutionCount(model, reg.clone()));
   unique_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();
 
+  VectorTools::resize2(result, nbSites, nbBr);
+
   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)
+  for (size_t k = 0; k < nbSites; ++k)
   {
-    file << "\t" << ids[i];
+    vector<double> countsf = SubstitutionMappingTools::computeTotalSubstitutionVectorForSitePerBranch(*smap, k);
+    Vdouble* resS=&result[k];
+    
+    for (size_t i = 0; i < nbBr; ++i)
+      (*resS)[i]= countsf[sdi[i]];
   }
-  file << endl;
+}
+
 
+/**************************************************************************************************/
+
+void SubstitutionMappingTools::computeCountsPerSitePerType(
+  DRTreeLikelihood& drtl,
+  const vector<int>& ids,
+  SubstitutionModel* model,
+  const SubstitutionRegister& reg,
+  VVdouble& result)
+{
+  unique_ptr<SubstitutionCount> count(new UniformizationSubstitutionCount(model, reg.clone()));
+  unique_ptr<ProbabilisticSubstitutionMapping> smap(SubstitutionMappingTools::computeSubstitutionVectors(drtl, ids, *count, false));
+
+  size_t nbSites = smap->getNumberOfSites();
+  size_t nbTypes = smap->getNumberOfSubstitutionTypes();
+
+  VectorTools::resize2(result, nbSites, nbTypes);
+
+  vector<unique_ptr<ProbabilisticRewardMapping> > rmap;
+  
   for (size_t k = 0; k < nbSites; ++k)
   {
-    vector<double> countsf = SubstitutionMappingTools::computeTotalSubstitutionVectorForSitePerBranch(*smap, k);
-    file << k;
-    for (size_t i = 0; i < nbBr; ++i)
+    vector<double> countsf = SubstitutionMappingTools::computeTotalSubstitutionVectorForSitePerType(*smap, k);
+
+    Vdouble* resS=&result[k];
+    
+    for (size_t i = 0; i < nbTypes; ++i)
+      (*resS)[i]=countsf[i];
+  }
+}
+
+
+/**************************************************************************************************/
+
+void SubstitutionMappingTools::computeCountsPerSitePerType(
+  DRTreeLikelihood& drtl,
+  const vector<int>& ids,
+  SubstitutionModel* model,
+  SubstitutionModel* nullModel,
+  const SubstitutionRegister& reg,
+  VVdouble& result,
+  bool perTime,
+  bool perWord)
+{
+  
+  unique_ptr<SubstitutionCount> count(new UniformizationSubstitutionCount(model, reg.clone()));
+
+  unique_ptr<ProbabilisticSubstitutionMapping> smap(SubstitutionMappingTools::computeSubstitutionVectors(drtl, ids, *count, false));
+
+  size_t nbSites = smap->getNumberOfSites();
+  size_t nbTypes = smap->getNumberOfSubstitutionTypes();
+  size_t nbStates = nullModel->getAlphabet()->getSize();
+  vector<int> supportedStates = nullModel->getAlphabetStates();
+
+  VectorTools::resize2(result, nbSites, nbTypes);
+
+  // compute the AlphabetIndex for each substitutionType
+  vector<UserAlphabetIndex1 > usai(nbTypes, UserAlphabetIndex1(nullModel->getAlphabet()));
+
+  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++)
     {
-      file << "\t" << countsf[sdi[i]];
+      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 site for each substitutionType
+  vector< vector<double> > rewards(nbSites);
+
+  for (size_t k = 0; k < nbSites; ++k)
+  {
+    rewards[k].resize(nbTypes);
+  }
+  
+  for (size_t nbt = 0; nbt < nbTypes; nbt++)
+  {
+    unique_ptr<Reward> reward(new DecompositionReward(nullModel, &usai[nbt]));
+
+    unique_ptr<ProbabilisticRewardMapping> mapping(RewardMappingTools::computeRewardVectors(drtl, ids, *reward, false));
+
+    for (size_t i = 0; i < nbSites; ++i)
+    {
+      double s = 0;
+      for (size_t k = 0; k < ids.size(); ++k)
+      {
+        double tmp = (*mapping)(mapping->getNodeIndex(ids[k]), i);
+        if (std::isnan(tmp))
+        {
+          s = 0;
+          break;
+        }
+        s += tmp;
+      }
+      rewards[i][nbt] = s;
+    }
+    
+    reward.reset();
+    mapping.reset();
+  }
+
+  // Compute the sum of lengths of concerned branchs
+  
+  double brlen=0;
+
+  if (!perTime)
+  {
+    const TreeTemplate<Node> tree(drtl.getTree());
+    for (size_t k = 0; k < ids.size(); ++k)
+      brlen += tree.getNode(ids[k])->getDistanceToFather();
+  }
+  else
+    brlen=1;
+
+  // check if perWord
+
+  const CoreWordAlphabet* wAlp=dynamic_cast<const CoreWordAlphabet*>(nullModel->getAlphabet());
+
+  float sizeWord=float((wAlp!=NULL) & !perWord?wAlp->getLength():1);
+  
+  // output
+  
+  for (size_t k = 0; k < nbSites; ++k)
+  {
+    vector<double> countsf = SubstitutionMappingTools::computeTotalSubstitutionVectorForSitePerType(*smap, k);
+
+    Vdouble& resS=result[k];
+    for (size_t i = 0; i < nbTypes; ++i)
+    {
+      resS[i] = countsf[i]/rewards[k][i]*brlen/sizeWord;
+    }
+  }
+}
+
+
+/**************************************************************************************************/
+
+void SubstitutionMappingTools::computeCountsPerSitePerType(
+  DRTreeLikelihood& drtl,
+  const vector<int>& ids,
+  SubstitutionModelSet* modelSet,
+  SubstitutionModelSet* nullModelSet,
+  const SubstitutionRegister& reg,
+  VVdouble& result,
+  bool perTime,
+  bool perWord)
+{
+  unique_ptr<SubstitutionCount> count(new UniformizationSubstitutionCount(modelSet->getSubstitutionModel(0), reg.clone()));
+
+  unique_ptr<ProbabilisticSubstitutionMapping> smap(SubstitutionMappingTools::computeSubstitutionVectors(drtl, ids, *count, false));
+
+  size_t nbSites = smap->getNumberOfSites();
+  size_t nbTypes = smap->getNumberOfSubstitutionTypes();
+  size_t nbStates = nullModelSet->getAlphabet()->getSize();
+  size_t nbModels = nullModelSet->getNumberOfModels();
+
+  VectorTools::resize2(result, nbSites, nbTypes);
+  
+  // compute the normalization for each site for each substitutionType
+  vector< vector<double> > rewards(nbSites);
+
+  for (size_t k = 0; k < nbSites; ++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->getSubstitutionModel(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++)
+      {
+        unique_ptr<Reward> reward(new DecompositionReward(nullModelSet->getSubstitutionModel(nbm), &usai[nbt]));
+        
+        unique_ptr<ProbabilisticRewardMapping> mapping(RewardMappingTools::computeRewardVectors(drtl, mids, *reward, false));
+        
+        for (size_t i = 0; i < nbSites; ++i)
+        {
+          double s = 0;
+          for (size_t k = 0; k < mids.size(); k++)
+          {
+            double tmp = (*mapping)(mapping->getNodeIndex(mids[k]), i);
+
+            if (std::isnan(tmp))
+            {
+              s = 0;
+              break;
+            }
+            else
+              s += tmp;
+          }
+          rewards[i][nbt] += s;
+        }
+        reward.reset();
+        mapping.reset();
+      }
+    }
+  }
+  
+  // Compute the sum of lengths of concerned branchs
+  
+
+  double brlen=0;
+
+  if (!perTime){
+    const TreeTemplate<Node> tree(drtl.getTree());
+    for (size_t k = 0; k < ids.size(); ++k)
+      brlen += tree.getNode(ids[k])->getDistanceToFather();
+  }
+  else
+    brlen = 1.;
+  
+      
+  // check if perWord
+
+   
+  const CoreWordAlphabet* wAlp=dynamic_cast<const CoreWordAlphabet*>(nullModelSet->getAlphabet());
+
+  float sizeWord=float((wAlp!=NULL) & !perWord?wAlp->getLength():1);
+ 
+  // output
+  
+  for (size_t k = 0; k < nbSites; ++k)
+  {
+    vector<double> countsf = SubstitutionMappingTools::computeTotalSubstitutionVectorForSitePerType(*smap, k);
+
+    Vdouble& resS=result[k];
+    
+    for (size_t i = 0; i < nbTypes; ++i)
+    {
+      resS[i] = countsf[i]/rewards[k][i]*brlen/sizeWord;
     }
-    file << endl;
   }
-  file.close();
 }
 
+
 /**************************************************************************************************/
 
-void SubstitutionMappingTools::outputTotalCountsPerTypePerSite(
-  string& filename,
+void SubstitutionMappingTools::computeCountsPerSitePerBranchPerType(
   DRTreeLikelihood& drtl,
   const vector<int>& ids,
   SubstitutionModel* model,
-  const SubstitutionRegister& reg)
+  const SubstitutionRegister& reg,
+  VVVdouble& result)
 {
   unique_ptr<SubstitutionCount> count(new UniformizationSubstitutionCount(model, reg.clone()));
   unique_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();
+  size_t nbTypes= reg.getNumberOfSubstitutionTypes();
+
+  VectorTools::resize3(result, nbSites, nbBr, nbTypes);
+  
+  for (size_t i = 0; i < nbTypes; ++i)
+  {
+    for (size_t j = 0; j < nbSites; ++j)
+    {
+      VVdouble& resS=result[j];
+      
+      for (size_t k = 0; k < nbBr; ++k)
+      {
+        resS[k][i] = (*smap)(smap->getNodeIndex(ids[k]), j, i);
+      }
+    }
+  }
+}
 
+/**************************************************************************************************/
+
+void SubstitutionMappingTools::computeCountsPerSitePerBranchPerType(
+  DRTreeLikelihood& drtl,
+  const vector<int>& ids,
+  SubstitutionModel* model,
+  SubstitutionModel* nullModel,
+  const SubstitutionRegister& reg,
+  VVVdouble& result,
+  bool perTime,
+  bool perWord)
+{
+  unique_ptr<SubstitutionCount> count(new UniformizationSubstitutionCount(model, reg.clone()));
+
+  unique_ptr<ProbabilisticSubstitutionMapping> smap(SubstitutionMappingTools::computeSubstitutionVectors(drtl, ids, *count, false));
+  
   size_t nbSites = smap->getNumberOfSites();
   size_t nbTypes = smap->getNumberOfSubstitutionTypes();
+  size_t nbStates = nullModel->getAlphabet()->getSize();
+  size_t nbBr = ids.size();
+
+  VectorTools::resize3(result, nbSites, nbBr, nbTypes);
+
+  // compute the normalization for each site for each substitutionType
+  map<int, vector< vector<double> > > rewards;
+
+  for (auto id : ids)
+    VectorTools::resize2(rewards[id], nbSites, nbTypes);
+
+  vector<int> supportedStates = nullModel->getAlphabetStates();
+
+  // compute the AlphabetIndex for each substitutionType
+  vector<UserAlphabetIndex1 > usai(nbTypes, UserAlphabetIndex1(nullModel->getAlphabet()));
+
+  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]) + nullModel->Qij(i, j));
+      }
+    }
+  }
+
+  for (size_t nbt = 0; nbt < nbTypes; nbt++)
+  {
+    unique_ptr<Reward> reward(new DecompositionReward(nullModel, &usai[nbt]));
+
+    unique_ptr<ProbabilisticRewardMapping> mapping(RewardMappingTools::computeRewardVectors(drtl, ids, *reward, false));
+
+    for (size_t i = 0; i < nbSites; ++i)
+    {
+      for (size_t k = 0; k < ids.size(); ++k)
+      {
+        double tmp = (*mapping)(mapping->getNodeIndex(ids[k]), i);
+
+        if (std::isnan(tmp))
+          tmp = 0;
+        
+        rewards[ids[k]][i][nbt] = tmp;
+      }
+    }
+        
+    reward.reset();
+    mapping.reset();
+  }
+
+  // check if perWord
+
+  const CoreWordAlphabet* wAlp=dynamic_cast<const CoreWordAlphabet*>(nullModel->getAlphabet());
+
+  float sizeWord=float((wAlp!=NULL) & !perWord?wAlp->getLength():1);
+  
+
+  // output
+  const TreeTemplate<Node>& tree=drtl.getTree();
+
+  for (size_t i = 0; i < nbTypes; ++i)
+  {
+    for (size_t j = 0; j < nbSites; ++j)
+    {
+      VVdouble& resS=result[j];
+      
+      for (size_t k = 0; k < nbBr; ++k)
+      {
+        resS[k][i] = (*smap)(smap->getNodeIndex(ids[k]), j, i)/rewards[ids[k]][j][i]*(perTime?1:tree.getNode(ids[k])->getDistanceToFather())/sizeWord;
+      }
+    }
+  }
+}
+
+/**************************************************************************************************/
+
+void SubstitutionMappingTools::computeCountsPerSitePerBranchPerType(
+  DRTreeLikelihood& drtl,
+  const vector<int>& ids,
+  SubstitutionModelSet* modelSet,
+  SubstitutionModelSet* nullModelSet,
+  const SubstitutionRegister& reg,
+  VVVdouble& result,
+  bool perTime,
+  bool perWord)
+{
+  unique_ptr<SubstitutionCount> count(new UniformizationSubstitutionCount(modelSet->getSubstitutionModel(0), reg.clone()));
+
+  unique_ptr<ProbabilisticSubstitutionMapping> smap(SubstitutionMappingTools::computeSubstitutionVectors(drtl, ids, *count, false));
+  
+  size_t nbSites = smap->getNumberOfSites();
+  size_t nbTypes = smap->getNumberOfSubstitutionTypes();
+  size_t nbStates = nullModelSet->getAlphabet()->getSize();
+  size_t nbModels = nullModelSet->getNumberOfModels();
+  size_t nbBr = ids.size();
+
+  VectorTools::resize3(result, nbSites, nbBr, nbTypes);
+
+  // compute the normalization for each site for each substitutionType
+  map<int, vector< vector<double> > > rewards;
+
+  for (auto id : ids)
+    VectorTools::resize2(rewards[id], nbSites, 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->getSubstitutionModel(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++)
+      {
+        unique_ptr<Reward> reward(new DecompositionReward(nullModelSet->getSubstitutionModel(nbm), &usai[nbt]));
+        
+        unique_ptr<ProbabilisticRewardMapping> mapping(RewardMappingTools::computeRewardVectors(drtl, mids, *reward, false));
+        
+        for (size_t i = 0; i < nbSites; ++i)
+        {
+          for (size_t k = 0; k < mids.size(); k++)
+          {
+            double tmp =  (*mapping)(mapping->getNodeIndex(mids[k]), i);
+
+            if (std::isnan(tmp))
+              tmp = 0;
+
+            rewards[mids[k]][i][nbt] = tmp;
+          }
+        }
+        
+        reward.reset();
+        mapping.reset();
+      }
+    }
+  }
+
+  // check if perWord
+
+  const CoreWordAlphabet* wAlp=dynamic_cast<const CoreWordAlphabet*>(nullModelSet->getAlphabet());
+
+  float sizeWord=float((wAlp!=NULL) & !perWord?wAlp->getLength():1);
+  
+
+  // output
+  const TreeTemplate<Node>& tree=drtl.getTree();
+
+  for (size_t i = 0; i < nbTypes; ++i)
+  {
+    for (size_t j = 0; j < nbSites; ++j)
+    {
+      VVdouble& resS=result[j];
+      
+      for (size_t k = 0; k < nbBr; ++k)
+      {
+        resS[k][i] = (*smap)(smap->getNodeIndex(ids[k]), j, i)/rewards[ids[k]][j][i]*(perTime?1:tree.getNode(ids[k])->getDistanceToFather())/sizeWord;
+      }
+    }
+  }
+}
+
+
+/**************************************************************************************************/
+
+void SubstitutionMappingTools::outputPerSitePerBranch(
+  const string& filename,
+  const vector<int>& ids,
+  const VVdouble& counts)
+{
+  size_t nbSites=counts.size();
+  if (nbSites==0)
+    return;
+  size_t nbBr=counts[0].size();
+  
+  ofstream file;
+  file.open(filename.c_str());
 
   file << "sites";
+  for (size_t i = 0; i < nbBr; ++i)
+  {
+    file << "\t" << ids[i];
+  }
+  file << endl;
+
+  for (size_t k = 0; k < nbSites; ++k)
+  {
+    const Vdouble& countS=counts[k];
+    file << k;
+    for (size_t i = 0; i < nbBr; ++i)
+    {
+      file << "\t" << countS[i];
+    }
+    file << endl;
+  }
+  file.close();
+}
+
+
+/**************************************************************************************************/
+
+void SubstitutionMappingTools::outputPerSitePerType(
+  const string& filename,
+  const SubstitutionRegister& reg,
+  const VVdouble& counts)
+{
+  
+  size_t nbSites=counts.size();
+  if (nbSites==0)
+    return;
+  size_t nbTypes=counts[0].size();
+  
+  ofstream file;
+  file.open(filename.c_str());
+  
+  file << "sites";
   for (size_t i = 0; i < nbTypes; ++i)
   {
     file << "\t" << reg.getTypeName(i + 1);
@@ -1942,11 +2489,11 @@ void SubstitutionMappingTools::outputTotalCountsPerTypePerSite(
 
   for (size_t k = 0; k < nbSites; ++k)
   {
-    vector<double> countsf = SubstitutionMappingTools::computeTotalSubstitutionVectorForSitePerType(*smap, k);
     file << k;
+    const Vdouble& resS=counts[k];
     for (size_t i = 0; i < nbTypes; ++i)
     {
-      file << "\t" << countsf[i];
+      file << "\t" << resS[i];
     }
     file << endl;
   }
@@ -1956,22 +2503,23 @@ void SubstitutionMappingTools::outputTotalCountsPerTypePerSite(
 
 /**************************************************************************************************/
 
-void SubstitutionMappingTools::outputIndividualCountsPerBranchPerSite(
+void SubstitutionMappingTools::outputPerSitePerBranchPerType(
   const string& filenamePrefix,
-  DRTreeLikelihood& drtl,
   const vector<int>& ids,
-  SubstitutionModel* model,
-  const SubstitutionRegister& reg)
+  const SubstitutionRegister& reg,
+  const VVVdouble& counts)
 {
-  unique_ptr<SubstitutionCount> count(new UniformizationSubstitutionCount(model, reg.clone()));
-  unique_ptr<ProbabilisticSubstitutionMapping> smap(SubstitutionMappingTools::computeSubstitutionVectors(drtl, ids, *count, false));
+  size_t nbSites=counts.size();
+  if (nbSites==0)
+    return;
+  size_t nbBr = counts[0].size();
+  if (nbBr==0)
+    return;
+  size_t nbTypes = counts[0][0].size();
 
   ofstream file;
 
-  size_t nbSites = smap->getNumberOfSites();
-  size_t nbBr = ids.size();
-
-  for (size_t i = 0; i < reg.getNumberOfSubstitutionTypes(); ++i)
+  for (size_t i = 0; i < nbTypes; ++i)
   {
     string name=reg.getTypeName(i+1);
     if (name=="")
@@ -1981,25 +2529,25 @@ void SubstitutionMappingTools::outputIndividualCountsPerBranchPerSite(
     
     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 << "\t" << ids[k];
     }
     file << endl;
 
     for (size_t j = 0; j < nbSites; ++j)
     {
+      const VVdouble& resS=counts[j];
+      
       file << j;
       for (size_t k = 0; k < nbBr; ++k)
       {
-        file << "\t" << (*smap)(smap->getNodeIndex(ids[k]), j, i);
+        file << "\t" << resS[k][i];
       }
       file << endl;
     }
     file.close();
   }
 }
-
-/**************************************************************************************************/
diff --git a/src/Bpp/Phyl/Mapping/SubstitutionMappingTools.h b/src/Bpp/Phyl/Mapping/SubstitutionMappingTools.h
index 37eaf87..155bef8 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_
@@ -60,410 +60,759 @@ namespace bpp
  *
  * @author Julien Dutheil
  */
-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)
-  {
-    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)
+  class SubstitutionMappingTools
   {
-    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> computeTotalSubstitutionVectorForSitePerBranch(const SubstitutionMapping& smap, size_t siteIndex);
-
-  /**
-   * @brief Sum all type of substitutions for each type 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 branches summed.
-   */
-  static std::vector<double> computeTotalSubstitutionVectorForSitePerType(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
-   *
-   *           If the SubstitutionRegister is a non-stationary
-   *           CategorySubstitutionRegister, a correction is made.
-   *
-   * @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,
-    double threshold = -1);
-
-  /**
-   * @brief Output the sum over all types of the counts per 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 the sum over all branches of the counts per type 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 outputTotalCountsPerTypePerSite(
-    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);
-};
+  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> computeTotalSubstitutionVectorForSitePerBranch(const SubstitutionMapping& smap, size_t siteIndex);
+
+    /**
+     * @brief Sum all type of substitutions for each type 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 branches summed.
+     */
+    
+    static std::vector<double> computeTotalSubstitutionVectorForSitePerType(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 Per Branch methods
+     *
+     *@{
+     *
+     */
+
+    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 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
+     *
+     *           If the SubstitutionRegister is a non-stationary
+     *           CategorySubstitutionRegister, a correction is made.
+     *
+     * @param threshold         value above which counts are considered saturated
+     *                                        (default: -1 means no threshold).
+     *
+     * @param verbose           Display progress messages.
+     */
+
+    static std::vector< std::vector<double> > getRelativeCountsPerBranch(
+      DRTreeLikelihood& drtl,
+      const std::vector<int>& ids,
+      SubstitutionModel* model,
+      const SubstitutionRegister& reg,
+      double threshold = -1,
+      bool verbose= true)
+    {
+      std::vector< std::vector<double> > result;
+      computeCountsPerTypePerBranch(drtl, ids, model, reg, result, threshold, verbose);
+      return result;
+    }
+
+    /**
+     * @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 perTime           If true, normalized counts are per unit of
+     *                          time (otherwise they are multiplied by
+     *                          the length of the branches).
+     * @param perWord           If true, normalized counts are per unit of
+     *                          length (otherwise they are divided per
+     *                          word length).
+     * @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 perTime,
+      bool perWord,
+      bool verbose = true)
+    {
+      std::vector< std::vector<double> > result;
+      computeCountsPerTypePerBranch(drtl, ids, model, nullModel, reg, result, perTime, perWord, verbose);
+      return result;
+    }
+
+    /**
+     * @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 perTime           If true, normalized counts are per unit of
+     *                          time (otherwise they are multiplied by
+     *                          the length of the branches).
+     * @param perWord           If true, normalized counts are per unit of
+     *                          length (otherwise they are divided per
+     *                          word length).
+     * @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 perTime,
+      bool perWord,
+      bool verbose = true)
+    {
+      std::vector< std::vector<double> > result;
+      computeCountsPerTypePerBranch(drtl, ids, modelSet, nullModelSet, reg, result, perTime, perWord, verbose);
+      return result;
+    }
+
+    /**
+     *@}
+     *
+     */
+
+    /**
+     *@ brief Per Branch Per Site methods
+     *
+     *@{
+     *
+     */
+
+    /**
+     * @brief Compute the sum over all types of the counts per site
+     * per 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 array       The resulted counts as an tabular site X branchid 
+     *
+     */
+
+    static void computeCountsPerSitePerBranch(
+      DRTreeLikelihood& drtl,
+      const std::vector<int>& ids,
+      SubstitutionModel* model,
+      const SubstitutionRegister& reg,
+      VVdouble& array);
+
+
+    /**
+     *@}
+     *
+     */
+
+    /**
+     *@ brief Per Type Per Branch methods
+     *
+     *@{
+     *
+     */
+
+    /**
+     * @brief Compute the sum over all branches of the counts per type
+     * per 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 result            the resulted counts as an tabular
+     *                          TypeId X branchId
+     * @param threshold         value above which counts are considered saturated
+     *                                        (default: -1 means no threshold).
+     * @param verbose           Display progress messages.
+     *
+     */
+
+    static void computeCountsPerTypePerBranch(
+      DRTreeLikelihood& drtl,
+      const std::vector<int>& ids,
+      SubstitutionModel* model,
+      const SubstitutionRegister& reg,
+      VVdouble& result,
+      double threshold = -1,
+      bool verbose = true);
+
+    /**
+     * @brief Compute the sum over all branches of the normalized
+     * counts per type per 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 nullModel         The null model used for normalization.
+     * @param reg               the Substitution Register
+     * @param result            the resulted counts as an tabular
+     *                          TypeId X branchId
+     * @param perTime           If true, normalized counts are per unit of
+     *                          time (otherwise they are multiplied by
+     *                          the length of the branches).
+     * @param perWord           If true, normalized counts are per unit of
+     *                          length (otherwise they are divided per
+     *                          word length).
+     * @param verbose           Display progress messages.
+     *
+     */
+
+    static void computeCountsPerTypePerBranch(
+      DRTreeLikelihood& drtl,
+      const std::vector<int>& ids,
+      SubstitutionModel* model,
+      SubstitutionModel* nullModel,
+      const SubstitutionRegister& reg,
+      VVdouble& result,
+      bool perTime,
+      bool perWord,
+      bool verbose = true);
+
+    /**
+     * @brief Compute the sum over all branches of the normalized
+     * counts per type per branch.
+     *
+     * @param drtl              A DRTreeLikelihood object.
+     * @param ids               The numbers of the nodes of the tree
+     * @param modelSet          The modelset on which the SubstitutionCount is built
+     * @param nullModelSet      The null modelSet used for normalization.
+     * @param reg               the Substitution Register
+     * @param result            the resulted counts as an tabular     
+     *                          TypeId X branchId
+     * @param perTime           If true, normalized counts are per unit of
+     *                          time (otherwise they are multiplied by
+     *                          the length of the branches).
+     *                          time (otherwise they are multiplied by
+     * @param perWord           If true, normalized counts are per unit of
+     *                          length (otherwise they are divided per
+     *                          word length).
+     * @param verbose           Display progress messages.
+     *
+     */
+
+    static void computeCountsPerTypePerBranch(
+      DRTreeLikelihood& drtl,
+      const std::vector<int>& ids,
+      SubstitutionModelSet* modelSet,
+      SubstitutionModelSet* nullModelSet,
+      const SubstitutionRegister& reg,
+      VVdouble& result,
+      bool perTime,
+      bool perWord,
+      bool verbose = true);
+
+    /**
+     *@}
+     *
+     */
+
+    /**
+     *@ brief Per Type Per Site methods
+     *
+     *@{
+     *
+     */
+
+    /**
+     * @brief Compute the sum over all branches of the counts per type per site,
+     *
+     * @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 result            the resulted counts as an tabular
+     *                          site X TypeId 
+     *
+     */
+
+    static void computeCountsPerSitePerType(
+      DRTreeLikelihood& drtl,
+      const std::vector<int>& ids,
+      SubstitutionModel* model,
+      const SubstitutionRegister& reg,
+      VVdouble& result);
+
+    /**
+     * @brief Compute the sum over all branches of the normalized
+     * counts per site per type.
+     *
+     * @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 result            the resulted counts as an tabular
+     *                          site X TypeId 
+     * @param perTime           If true, normalized counts are per unit of
+     *                          time (otherwise they are multiplied by
+     *                          the length of the branches).
+     * @param perWord           If true, normalized counts are per unit of
+     *                          length (otherwise they are divided per
+     *                          word length).
+     *
+     */
+
+    static void computeCountsPerSitePerType(
+      DRTreeLikelihood& drtl,
+      const std::vector<int>& ids,
+      SubstitutionModel* model,
+      SubstitutionModel* nullModel,
+      const SubstitutionRegister& reg,
+      VVdouble& result,
+      bool perTime,
+      bool perWord);
+
+    /**
+     * @brief Compute the sum over all branches of the normalized
+     * counts per site per type.
+     *
+     * @param drtl              A DRTreeLikelihood object.
+     * @param ids               The numbers of the nodes of the tree
+     * @param modelSet          The modelset on which the SubstitutionCount is built
+     * @param nullModelSet      The null modelSet used for normalization.
+     * @param reg               the Substitution Register
+     * @param result            the resulted counts as an tabular
+     *                          site X TypeId 
+     * @param perTime           If true, normalized counts are per unit of
+     *                          time (otherwise they are multiplied by
+     *                          the length of the branches).
+     * @param perWord           If true, normalized counts are per unit of
+     *                          length (otherwise they are divided per
+     *                          word length).
+     *
+     */
+
+    static void computeCountsPerSitePerType(
+      DRTreeLikelihood& drtl,
+      const std::vector<int>& ids,
+      SubstitutionModelSet* modelSet,
+      SubstitutionModelSet* nullModelSet,
+      const SubstitutionRegister& reg,
+      VVdouble& result,
+      bool perTime,
+      bool perWord);
+
+    /**
+     *@}
+     *
+     */
+
+    /**
+     *@ brief Per Branch Per Site Per Type methods
+     *
+     *@{
+     *
+     */
+
+    /**
+     * @brief Compute counts per site per branch per type.
+     *
+     * @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 result            the resulted counts as an tabular
+     *                          site X branchid X typeId
+     * @author Iakov Davydov
+     */
+    
+    static void computeCountsPerSitePerBranchPerType(
+      DRTreeLikelihood& drtl,
+      const std::vector<int>& ids,
+      SubstitutionModel* model,
+      const SubstitutionRegister& reg,
+      VVVdouble& result);
+
+    /** 
+     * @brief Compute normalized counts per site per branch per type.
+     *
+     * @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 result            the resulted counts as an tabular
+     *                          site X branchid * Typeid
+     * @param perTime           If true, normalized counts are per unit of
+     *                          time (otherwise they are multiplied by
+     *                          the length of the branches).
+     * @param perWord           If true, normalized counts are per unit of
+     *                          length (otherwise they are divided per
+     *                          word length).
+     *
+     */
+
+    static void computeCountsPerSitePerBranchPerType(
+      DRTreeLikelihood& drtl,
+      const std::vector<int>& ids,
+      SubstitutionModel* model,
+      SubstitutionModel* nullModel,
+      const SubstitutionRegister& reg,
+      VVVdouble& result,
+      bool perTime,
+      bool perWord);
+
+    /**
+     * @brief Compute normalized counts per site per branch per type.
+     *
+     * @param drtl              A DRTreeLikelihood object.
+     * @param ids               The numbers of the nodes of the tree
+     * @param modelSet          The modelset on which the SubstitutionCount is built
+     * @param nullModelSet      The null modelSet used for normalization.
+     * @param reg               the Substitution Register
+     * @param result            the resulted counts as an tabular
+     *                          site X branchid * Typeid
+     * @param perTime           If true, normalized counts are per unit of
+     *                          time (otherwise they are multiplied by
+     *                          the length of the branches).
+     * @param perWord           If true, normalized counts are per unit of
+     *                          length (otherwise they are divided per
+     *                          word length).
+     *
+     */
+
+    static void computeCountsPerSitePerBranchPerType(
+      DRTreeLikelihood& drtl,
+      const std::vector<int>& ids,
+      SubstitutionModelSet* modelSet,
+      SubstitutionModelSet* nullModelSet,
+      const SubstitutionRegister& reg,
+      VVVdouble& result,
+      bool perTime,
+      bool perWord);
+
+    /*
+     *
+     * @brief Outputs of counts
+     *
+     * @{
+     */
+
+    /**
+     * @brief Output Per Site Per Branch
+     *
+     */
+    
+    static void outputPerSitePerBranch(const std::string& filename,
+                                       const std::vector<int>& ids,
+                                       const VVdouble& counts);
+
+    /**
+     * @brief Output Per Site Per Type
+     *
+     */
+    
+    static void outputPerSitePerType(const std::string& filename,
+                                     const SubstitutionRegister& reg,
+                                     const VVdouble& counts);
+    
+    /**
+     * @brief Output Per Site Per Branch Per Type
+     *
+     */
+    
+    static void outputPerSitePerBranchPerType(const std::string& filenamePrefix,
+                                              const std::vector<int>& ids,
+                                              const SubstitutionRegister& reg,
+                                              const VVVdouble& counts);
+    
+
+    /*
+     *
+     *@}
+     */
+
+     
+    /**
+     *@}
+     *
+     */
+
+  };
 } // end of namespace bpp.
 
 #endif // _SUBSTITUTIONMAPPINGTOOLS_H_
diff --git a/src/Bpp/Phyl/Mapping/SubstitutionRegister.h b/src/Bpp/Phyl/Mapping/SubstitutionRegister.h
index 252b024..2eb913f 100644
--- a/src/Bpp/Phyl/Mapping/SubstitutionRegister.h
+++ b/src/Bpp/Phyl/Mapping/SubstitutionRegister.h
@@ -97,6 +97,14 @@ namespace bpp
     virtual size_t getNumberOfSubstitutionTypes() const = 0;
 
     /**
+     * @brief Get the name of the register.
+     *
+     * @return A string describing the register.
+     */
+    
+    virtual const std::string& getName() const = 0;
+
+    /**
      * @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).
@@ -123,19 +131,21 @@ namespace bpp
   {
   protected:
     const SubstitutionModel* model_;
-
+    std::string name_;
+    
   public:
-    AbstractSubstitutionRegister(const SubstitutionModel* model) :
-      model_(model)
+    AbstractSubstitutionRegister(const SubstitutionModel* model, const std::string& name) :
+      model_(model), name_(name)
     {}
 
     AbstractSubstitutionRegister(const AbstractSubstitutionRegister& asr) :
-      model_(asr.model_)
+      model_(asr.model_), name_(asr.name_)
     {}
 
     AbstractSubstitutionRegister& operator=(const AbstractSubstitutionRegister& asr)
     {
       model_ = asr.model_;
+      name_ = asr.name_;
       return *this;
     }
 
@@ -145,6 +155,12 @@ namespace bpp
     const SubstitutionModel* getSubstitutionModel() const { return model_; }
 
     const Alphabet* getAlphabet() const { return model_->getAlphabet(); }
+
+    const std::string& getName() const
+    {
+      return name_;
+    }
+    
   };
 
 /**
@@ -159,7 +175,7 @@ namespace bpp
   {
   public:
     TotalSubstitutionRegister(const SubstitutionModel* model) :
-      AbstractSubstitutionRegister(model)
+      AbstractSubstitutionRegister(model,"Total")
     {}
 
     TotalSubstitutionRegister* clone() const { return new TotalSubstitutionRegister(*this); }
@@ -176,7 +192,7 @@ namespace bpp
     {
       if (type == 0)
       {
-        return "no substitution";
+        return "nosub";
       }
       else if (type == 1)
       {
@@ -194,6 +210,7 @@ namespace bpp
  * all substitutions. The new substitutions are considered in an
  * additional type.
  */
+  
   class CompleteSubstitutionRegister :
     public AbstractSubstitutionRegister
   {
@@ -204,7 +221,7 @@ namespace bpp
 
   public:
     CompleteSubstitutionRegister(const SubstitutionRegister& reg) :
-      AbstractSubstitutionRegister(reg.getSubstitutionModel()),
+      AbstractSubstitutionRegister(reg.getSubstitutionModel(),reg.getName()),
       preg_(reg.clone()),
       isRegComplete_(true)
     {
@@ -272,7 +289,7 @@ namespace bpp
       catch (Exception& e)
       {
         if (type == getNumberOfSubstitutionTypes())
-          return "Completion substitution";
+          return "Completion_substitution";
         else
           throw Exception("CompleteSubstitutionRegister::getTypeName. Bad substitution type.");
       }
@@ -303,7 +320,7 @@ namespace bpp
   public:
 
     VectorOfSubstitionRegisters(const SubstitutionModel* model) :
-      AbstractSubstitutionRegister(model),
+      AbstractSubstitutionRegister(model, "Combination"),
       vSubReg_()
     {}
 
@@ -395,19 +412,19 @@ namespace bpp
     std::string getTypeName(size_t type) const
     {
       if (type == 0)
-        return "no substitution";
+        return "nosub";
 
       std::string res="";
       size_t ty=type-1;
       
       for (size_t p=vSubReg_.size(); p>0; p--)
       {
-        res+=vSubReg_[p-1]->getTypeName((ty%vSubReg_[p-1]->getNumberOfSubstitutionTypes())+1);
+        if (p!=vSubReg_.size())
+          res="_X_" + res;
+        res=vSubReg_[p-1]->getTypeName((ty%vSubReg_[p-1]->getNumberOfSubstitutionTypes())+1) + res;
 
         ty/=vSubReg_[p-1]->getNumberOfSubstitutionTypes();
         
-        if (p!=1)
-          res+="_";
       }
 
       return res;
@@ -450,14 +467,14 @@ namespace bpp
 
   public:
     GeneralSubstitutionRegister(const SubstitutionModel* model) :
-      AbstractSubstitutionRegister(model),
+      AbstractSubstitutionRegister(model,"General"),
       size_(model->getNumberOfStates()),
       matrix_(size_, size_),
       types_()
     {}
 
     GeneralSubstitutionRegister(const SubstitutionModel* model, const RowMatrix<size_t>& matrix) :
-      AbstractSubstitutionRegister(model),
+      AbstractSubstitutionRegister(model,"General"),
       size_(model->getNumberOfStates()),
       matrix_(matrix),
       types_()
@@ -608,6 +625,40 @@ namespace bpp
       GeneralSubstitutionRegister(model),
       categoryCorrespondance_()
     {
+      updateMatrix_(model, *model->getGeneticCode());
+      updateTypes_();
+    }
+
+    AAInteriorSubstitutionRegister(const SubstitutionModel* model, const GeneticCode& gencod) :
+      GeneralSubstitutionRegister(model),
+      categoryCorrespondance_()
+    {
+      updateMatrix_(model, gencod);
+      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.");
+    }
+
+  protected:    
+    void updateMatrix_(const SubstitutionModel* model, const GeneticCode& gencod)
+    {
       size_t categoryIndex = 1;
       for (size_t i = 1; i <= model->getAlphabet()->getSize(); ++i)
       {
@@ -615,11 +666,11 @@ namespace bpp
         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 (!(gencod.isStop(state1)) && !(gencod.isStop(state2)))
           {
-            if (model->getGeneticCode()->translate(state1) == model->getGeneticCode()->translate(state2))
+            if (gencod.translate(state1) == gencod.translate(state2))
             {
-              std::string aminoAcid = model->getGeneticCode()->getTargetAlphabet()->intToChar(model->getGeneticCode()->translate(state1));
+              std::string aminoAcid = gencod.getTargetAlphabet()->intToChar(gencod.translate(state1));
               if (categoryCorrespondance_.find(aminoAcid) == categoryCorrespondance_.end())
               {
                 categoryCorrespondance_[aminoAcid] = categoryIndex;
@@ -631,26 +682,8 @@ namespace bpp
           }
         }
       }
-      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.");
-    }
   };
 
 /**
@@ -670,6 +703,40 @@ namespace bpp
       GeneralSubstitutionRegister(model),
       categoryCorrespondance_()
     {
+      updateMatrix_(model, *model->getGeneticCode());
+      updateTypes_();
+    }
+
+    AAExteriorSubstitutionRegister (const SubstitutionModel* model, const GeneticCode& gencod) :
+      GeneralSubstitutionRegister(model),
+      categoryCorrespondance_()
+    {
+      updateMatrix_(model, gencod);
+      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.");
+    }
+
+  protected:
+    void updateMatrix_(const SubstitutionModel* model, const GeneticCode& gencod)
+    {
+      
       size_t categoryIndex = 1;
       for (size_t i = 1; i <= model->getAlphabet()->getSize(); ++i)
       {
@@ -677,12 +744,12 @@ namespace bpp
         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 (!(gencod.isStop(state1)) && !(gencod.isStop(state2)))
           {
-            if (model->getGeneticCode()->translate(state1) != model->getGeneticCode()->translate(state2))
+            if (gencod.translate(state1) != gencod.translate(state2))
             {
-              std::string aminoAcid1 = model->getGeneticCode()->getTargetAlphabet()->intToChar(model->getGeneticCode()->translate(state1));
-              std::string aminoAcid2 = model->getGeneticCode()->getTargetAlphabet()->intToChar(model->getGeneticCode()->translate(state2));
+              std::string aminoAcid1 = gencod.getTargetAlphabet()->intToChar(gencod.translate(state1));
+              std::string aminoAcid2 = gencod.getTargetAlphabet()->intToChar(gencod.translate(state2));
               bool AA1IsNotInGroup = ((categoryCorrespondance_.find(aminoAcid1 + "->" + aminoAcid2) == categoryCorrespondance_.end()));
               bool AA2IsNotInGroup = ((categoryCorrespondance_.find(aminoAcid2 + "->" + aminoAcid1) == categoryCorrespondance_.end()));
               if (AA1IsNotInGroup)
@@ -701,25 +768,8 @@ namespace bpp
           }
         }
       }
-      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.");
-    }
   };
 
 /**
@@ -744,15 +794,20 @@ namespace bpp
 
   public:
     TsTvSubstitutionRegister(const NucleotideSubstitutionModel* model) :
-      AbstractSubstitutionRegister(model),
+      AbstractSubstitutionRegister(model,"TsTv"),
       code_()
     {}
 
     TsTvSubstitutionRegister(const CodonSubstitutionModel* model) :
-      AbstractSubstitutionRegister(model),
+      AbstractSubstitutionRegister(model,"TsTv"),
       code_(model->getGeneticCode())
     {}
 
+    TsTvSubstitutionRegister(const SubstitutionModel* model, const GeneticCode& gencod) :
+      AbstractSubstitutionRegister(model,"TsTv"),
+      code_(&gencod)
+    {}
+
     TsTvSubstitutionRegister(const TsTvSubstitutionRegister& reg) :
       AbstractSubstitutionRegister(reg),
       code_(reg.code_)
@@ -814,15 +869,15 @@ namespace bpp
     {
       if (type == 0)
       {
-        return "no substitution";
+        return "nosub";
       }
       else if (type == 1)
       {
-        return "transition";
+        return "Ts";
       }
       else if (type == 2)
       {
-        return "transversion";
+        return "Tv";
       }
       else
       {
@@ -831,6 +886,147 @@ namespace bpp
     }
   };
 
+  /**
+   * @brief Distinguishes substitutions given the link between the
+   * changed nucleotides : S for strong (GC) and W for weak (AT).
+   *
+   * This register has 4 substitution types, mapped as:
+   * - 0 not a substitution
+   * - 1 S->S
+   * - 2 S->W
+   * - 3 W->S
+   * - 4 W->W
+   */
+
+  class SWSubstitutionRegister :
+    public AbstractSubstitutionRegister
+  {
+  private:
+    /**
+     *  @brief useful for codon alphabet
+     *
+     */
+    
+    const GeneticCode* code_;
+
+  public:
+    SWSubstitutionRegister(const NucleotideSubstitutionModel* model) :
+      AbstractSubstitutionRegister(model,"SW"),
+      code_()
+    {}
+
+    SWSubstitutionRegister(const CodonSubstitutionModel* model) :
+      AbstractSubstitutionRegister(model,"SW"),
+      code_(model->getGeneticCode())
+    {}
+
+    SWSubstitutionRegister(const SubstitutionModel* model, const GeneticCode& gencod) :
+      AbstractSubstitutionRegister(model,"SW"),
+      code_(&gencod)
+    {}
+
+    SWSubstitutionRegister(const SWSubstitutionRegister& reg) :
+      AbstractSubstitutionRegister(reg),
+      code_(reg.code_)
+    {}
+
+    SWSubstitutionRegister& operator=(const SWSubstitutionRegister& reg)
+    {
+      AbstractSubstitutionRegister::operator=(reg);
+      code_ = reg.code_;
+      return *this;
+    }
+
+    SWSubstitutionRegister* clone() const { return new SWSubstitutionRegister(*this); }
+
+  public:
+    size_t getNumberOfSubstitutionTypes() const { return 4; }
+
+    size_t getType(size_t fromState, size_t toState) const
+    {
+      int x = model_->getAlphabetStateAsInt(fromState);
+      int y = model_->getAlphabetStateAsInt(toState);
+      if (x == y)
+        return 0;                     // nothing happens
+
+      const CodonAlphabet* cAlpha = dynamic_cast<const CodonAlphabet*>(model_->getAlphabet());
+      int nd, na;
+      
+      if (cAlpha)
+      {
+        if (code_->getSourceAlphabet()->isGap(x)
+            || code_->getSourceAlphabet()->isGap(y)
+            || code_->isStop(x)
+            || code_->isStop(y))
+          return 0;
+        
+        nd=cAlpha->getFirstPosition(x);
+        na=cAlpha->getFirstPosition(y);
+        if (na!=nd)
+        {
+          if (cAlpha->getSecondPosition(x) != cAlpha->getSecondPosition(y)
+              || (cAlpha->getThirdPosition(x) != cAlpha->getThirdPosition(y)))
+            return 0;
+        }
+        else
+        {
+          nd=cAlpha->getSecondPosition(x);
+          na=cAlpha->getSecondPosition(y);
+          if (na!=nd)
+          {
+            if (cAlpha->getThirdPosition(x) != cAlpha->getThirdPosition(y))
+              return 0;
+          }
+          else
+          {
+            nd=cAlpha->getThirdPosition(x);
+            na=cAlpha->getThirdPosition(y);
+          }
+        }
+      }
+      else
+      {
+        nd=x;
+        na=y;
+      }
+      
+      switch(nd)
+      {
+      case 0:
+        return (na==3)?4:3;
+      case 1:
+        return (na==2)?1:2;
+      case 2:
+        return (na==1)?1:2;
+      case 3:
+        return (na==0)?4:3;
+      default:
+        return 0;
+      }
+    }
+
+    std::string getTypeName(size_t type) const
+    {
+      switch(type)
+      {
+      case 0:
+        return "nosub";
+      case 1:
+        return "S->S";
+      case 2:
+        return "S->W";
+      case 3:
+        return "W->S";
+      case 4:
+        return "W->W";
+      default:
+        throw Exception("SWSubstitutionRegister::getTypeName. Bad substitution type.");
+      }
+    }
+    
+  };
+
+
 /**
  * @brief Distinguishes synonymous from non-synonymous substitutions.
  *
@@ -848,11 +1044,17 @@ namespace bpp
 
   public:
     DnDsSubstitutionRegister(const CodonSubstitutionModel* model, bool countMultiple = false) :
-      AbstractSubstitutionRegister(model),
+      AbstractSubstitutionRegister(model,"DnDs"),
       code_(model->getGeneticCode()),
       countMultiple_(countMultiple)
     {}
 
+    DnDsSubstitutionRegister(const SubstitutionModel* model, const GeneticCode& gencod, bool countMultiple = false) :
+      AbstractSubstitutionRegister(model,"DnDs"),
+      code_(&gencod),
+      countMultiple_(countMultiple)
+    {}
+
     DnDsSubstitutionRegister(const DnDsSubstitutionRegister& reg) :
       AbstractSubstitutionRegister(reg),
       code_(reg.code_),
@@ -876,7 +1078,7 @@ namespace bpp
     {
       int x = model_->getAlphabetStateAsInt(fromState);
       int y = model_->getAlphabetStateAsInt(toState);
-      const CodonAlphabet* cAlpha = dynamic_cast<const CodonAlphabet*>(model_->getAlphabet());
+      const CodonAlphabet* cAlpha = static_cast<const CodonAlphabet*>(model_->getAlphabet());
       if (code_->getSourceAlphabet()->isGap(x)
           || code_->getSourceAlphabet()->isGap(y)
           || code_->isStop(x)
@@ -903,7 +1105,7 @@ namespace bpp
     {
       if (type == 0)
       {
-        return "no substitution";
+        return "nosub";
       }
       else if (type == 1)
       {
@@ -935,10 +1137,51 @@ namespace bpp
   private:
     std::vector< std::vector<bool> > types_;
 
+    // In case of codon model
+    const GeneticCode* code_;
+
   public:
     KrKcSubstitutionRegister(const ProteinSubstitutionModel* model) :
-      AbstractSubstitutionRegister(model),
-      types_(20)
+      AbstractSubstitutionRegister(model,"KrKc"),
+      types_(20),
+      code_(0)
+    {
+      init();
+    }
+
+    KrKcSubstitutionRegister(const CodonSubstitutionModel* model) :
+      AbstractSubstitutionRegister(model,"KrKc"),
+      types_(20),
+      code_(model->getGeneticCode())
+    {
+      init();
+    }
+
+    KrKcSubstitutionRegister(const SubstitutionModel* model, const GeneticCode& gencod) :
+      AbstractSubstitutionRegister(model,"KrKc"),
+      types_(20),
+      code_(&gencod)
+    {
+      init();
+    }
+
+    KrKcSubstitutionRegister(const KrKcSubstitutionRegister& kreg) :
+      AbstractSubstitutionRegister(kreg),
+      types_(kreg.types_),
+      code_(kreg.code_)
+    {
+    }
+
+    KrKcSubstitutionRegister& operator=(const KrKcSubstitutionRegister& kreg)
+    {
+      AbstractSubstitutionRegister::operator=(kreg);
+      types_=kreg.types_;
+      code_=kreg.code_;
+
+      return *this;
+    }
+
+    void init()
     {
       for (size_t i = 0; i < 20; ++i) {
         types_[i].resize(20);
@@ -1049,6 +1292,34 @@ namespace bpp
         return 0;  // nothing happens
       int x = model_->getAlphabetStateAsInt(fromState);
       int y = model_->getAlphabetStateAsInt(toState);
+
+      if (code_) //Codon model
+      {
+        if (code_->getSourceAlphabet()->isGap(x)
+            || code_->getSourceAlphabet()->isGap(y)
+            || code_->isStop(x)
+            || code_->isStop(y))
+          return 0;
+        if (code_->areSynonymous(x, y))
+          return 0;
+
+        // avoid multiple substitutions
+        const CodonAlphabet* cAlpha = static_cast<const CodonAlphabet*>(model_->getAlphabet());
+        
+        size_t countPos = 0;
+        if (cAlpha->getFirstPosition(x) != cAlpha->getFirstPosition(y))
+          countPos++;
+        if (cAlpha->getSecondPosition(x) != cAlpha->getSecondPosition(y))
+          countPos++;
+        if (cAlpha->getThirdPosition(x) != cAlpha->getThirdPosition(y))
+          countPos++;
+        if (countPos > 1)
+          return 0;
+
+        x=code_->translate(x);
+        y=code_->translate(y);
+      }
+
       return types_[static_cast<size_t>(x)][static_cast<size_t>(y)] ? 1 : 2;
     }
 
@@ -1056,15 +1327,15 @@ namespace bpp
     {
       if (type == 0)
       {
-        return "no substitution";
+        return "nosub";
       }
       else if (type == 1)
       {
-        return "conservative";
+        return "Kc";
       }
       else if (type == 2)
       {
-        return "radical";
+        return "Kr";
       }
       else
       {
diff --git a/src/Bpp/Phyl/Mapping/UniformizationSubstitutionCount.cpp b/src/Bpp/Phyl/Mapping/UniformizationSubstitutionCount.cpp
index f62b0dc..bac0490 100644
--- a/src/Bpp/Phyl/Mapping/UniformizationSubstitutionCount.cpp
+++ b/src/Bpp/Phyl/Mapping/UniformizationSubstitutionCount.cpp
@@ -163,7 +163,7 @@ void UniformizationSubstitutionCount::computeCounts_(double length) const
     for (size_t j = 0; j < nbStates_; j++) {
       for(size_t k = 0; k < nbStates_; k++) {
         counts_[i](j, k) /= P(j, k);
-        if (std::isnan(counts_[i](j, k)) || counts_[i](j, k) < 0.)
+        if (std::isinf(counts_[i](j, k)) || std::isnan(counts_[i](j, k)) || counts_[i](j, k) < 0.)
           counts_[i](j, k) = 0;
         //Weights:
         if (weights_)
diff --git a/src/Bpp/Phyl/Model/AbstractBiblioMixedSubstitutionModel.cpp b/src/Bpp/Phyl/Model/AbstractBiblioMixedSubstitutionModel.cpp
index 0606b4a..5b50855 100644
--- a/src/Bpp/Phyl/Model/AbstractBiblioMixedSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/AbstractBiblioMixedSubstitutionModel.cpp
@@ -44,22 +44,27 @@ using namespace std;
 /******************************************************************************/
 
 AbstractBiblioMixedSubstitutionModel::AbstractBiblioMixedSubstitutionModel(const std::string& prefix):
-  AbstractBiblioSubstitutionModel(prefix)
+  AbstractBiblioSubstitutionModel(prefix),
+  pmixmodel_()
 {}
   
-AbstractBiblioMixedSubstitutionModel::AbstractBiblioMixedSubstitutionModel(const AbstractBiblioMixedSubstitutionModel& mod2) : AbstractBiblioSubstitutionModel(mod2)
-{}
+AbstractBiblioMixedSubstitutionModel::AbstractBiblioMixedSubstitutionModel(const AbstractBiblioMixedSubstitutionModel& mod2) :
+  AbstractBiblioSubstitutionModel(mod2),
+  pmixmodel_(mod2.pmixmodel_->clone())
+{
+}
 
 AbstractBiblioMixedSubstitutionModel& AbstractBiblioMixedSubstitutionModel::operator=(const AbstractBiblioMixedSubstitutionModel& mod2)
 {
   AbstractBiblioSubstitutionModel::operator=(mod2);
+  pmixmodel_.reset(mod2.pmixmodel_->clone());
   return *this;
 }
 
 AbstractBiblioMixedSubstitutionModel::~AbstractBiblioMixedSubstitutionModel()
 {}
 
-Vint AbstractBiblioMixedSubstitutionModel::getSubmodelNumbers(std::string& desc) const
+Vint AbstractBiblioMixedSubstitutionModel::getSubmodelNumbers(const std::string& desc) const
 {
   std::string desc2;
 
diff --git a/src/Bpp/Phyl/Model/AbstractBiblioMixedSubstitutionModel.h b/src/Bpp/Phyl/Model/AbstractBiblioMixedSubstitutionModel.h
index 79c4789..76def84 100644
--- a/src/Bpp/Phyl/Model/AbstractBiblioMixedSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/AbstractBiblioMixedSubstitutionModel.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 _ABSTRACTBIBLIOMIXEDSUBSTITUTIONMODEL_H_
 #define _ABSTRACTBIBLIOMIXEDSUBSTITUTIONMODEL_H_
@@ -50,134 +50,147 @@ namespace bpp
  * @author Laurent Guéguen
  */
 
-class AbstractBiblioMixedSubstitutionModel :
-  public virtual MixedSubstitutionModel,
-  public AbstractBiblioSubstitutionModel
-{
-public:
-  AbstractBiblioMixedSubstitutionModel(const std::string& prefix);
-
-  AbstractBiblioMixedSubstitutionModel(const AbstractBiblioMixedSubstitutionModel& model);
-
-  AbstractBiblioMixedSubstitutionModel& operator=(const AbstractBiblioMixedSubstitutionModel& model);
-
-  virtual ~AbstractBiblioMixedSubstitutionModel();
-
-  virtual AbstractBiblioMixedSubstitutionModel* clone() const = 0;
-
-public:
-  virtual const MixedSubstitutionModel& getMixedModel() const = 0;
-
-  /*
-   *@brief Returns the submodel from the mixture.
-   *
-   */
-  
-  const SubstitutionModel* getNModel(size_t i) const
-  {
-    return getMixedModel().getNModel(i);
-  }
-
-  SubstitutionModel* getNModel(size_t i)
-  {
-    return getMixedModel().getNModel(i);
-  }
-
-  /**
-   * @brief Returns the  probability of a specific model from the mixture
-   */
-  double getNProbability(size_t i) const
+  class AbstractBiblioMixedSubstitutionModel :
+    public virtual MixedSubstitutionModel,
+    public AbstractBiblioSubstitutionModel
   {
-    return getMixedModel().getNProbability(i);
-  }
+  protected:
+    std::unique_ptr<MixedSubstitutionModel> pmixmodel_;
+    
+  public:
+    AbstractBiblioMixedSubstitutionModel(const std::string& prefix);
 
-  /**
-   * @brief Returns the vector of the probabilities of the
-   * submodels of the mixture.
-   *
-   */
+    AbstractBiblioMixedSubstitutionModel(const AbstractBiblioMixedSubstitutionModel& model);
 
-  const std::vector<double>& getProbabilities() const
-  {
-    return getMixedModel().getProbabilities();
-  }
-
-  /**
-   * @brief Sets the probabilities of the submodels of the mixture.
-   *
-   */
-  void setNProbability(size_t i, double prob)
-  {
-    getMixedModel().setNProbability(i, prob);
-  }
-
-  /**
-   * @brief Returns the number of submodels
-   *
-   */
-  size_t getNumberOfModels() const
-  {
-    return getMixedModel().getNumberOfModels();
-  }
-
-  /**
-   * @brief sets the rates of the submodels.
-   *
-   **/
-  void setVRates(const Vdouble& vd)
-  {
-    getMixedModel().setVRates(vd);
-  }
-
-  /**
-   * @brief normalizes the rates of the submodels.
-   *
-   **/
-  void normalizeVRates()
-  {
-    getMixedModel().normalizeVRates();
-  }
+    AbstractBiblioMixedSubstitutionModel& operator=(const AbstractBiblioMixedSubstitutionModel& model);
 
-  /**
-   * @brief Returns the vector of all the rates of the mixture
-   */
+    virtual ~AbstractBiblioMixedSubstitutionModel();
 
-  const std::vector<double>& getVRates() const
-  {
-    return getMixedModel().getVRates();
-  }
+    virtual AbstractBiblioMixedSubstitutionModel* clone() const
+    {
+      return new AbstractBiblioMixedSubstitutionModel(*this);
+    }
+    
 
-  /**
-   * @brief Returns the rate of a specific model from the mixture
-   */
-  double getNRate(size_t i) const
-  {
-    return getMixedModel().getNRate(i);
-  }
-
-  /**
-   * @brief retrieve a pointer to the submodel with the given name.
-   *
-   * Return Null if not found.
-   *
-   */
+  public:
+    /*
+     *@brief Returns the submodel from the mixture.
+     *
+     */
   
-  const SubstitutionModel* getSubModelWithName(const std::string& name) const
-  {
-    return getMixedModel().getSubModelWithName(name);
-  }
+    const SubstitutionModel* getNModel(size_t i) const
+    {
+      return getMixedModel().getNModel(i);
+    }
+
+    SubstitutionModel* getNModel(size_t i)
+    {
+      return getMixedModel().getNModel(i);
+    }
+
+    /**
+     * @brief Returns the  probability of a specific model from the mixture
+     */
+    double getNProbability(size_t i) const
+    {
+      return getMixedModel().getNProbability(i);
+    }
+
+    /**
+     * @brief Returns the vector of the probabilities of the
+     * submodels of the mixture.
+     *
+     */
+
+    const std::vector<double>& getProbabilities() const
+    {
+      return getMixedModel().getProbabilities();
+    }
+
+    /**
+     * @brief Sets the probabilities of the submodels of the mixture.
+     *
+     */
+    void setNProbability(size_t i, double prob)
+    {
+      getMixedModel().setNProbability(i, prob);
+    }
+
+    /**
+     * @brief Returns the number of submodels
+     *
+     */
+    size_t getNumberOfModels() const
+    {
+      return getMixedModel().getNumberOfModels();
+    }
+
+    /**
+     * @brief sets the rates of the submodels.
+     *
+     **/
+    void setVRates(const Vdouble& vd)
+    {
+      getMixedModel().setVRates(vd);
+    }
+
+    /**
+     * @brief normalizes the rates of the submodels.
+     *
+     **/
+    void normalizeVRates()
+    {
+      getMixedModel().normalizeVRates();
+    }
+
+    /**
+     * @brief Returns the vector of all the rates of the mixture
+     */
+
+    const std::vector<double>& getVRates() const
+    {
+      return getMixedModel().getVRates();
+    }
+
+    /**
+     * @brief Returns the rate of a specific model from the mixture
+     */
+    double getNRate(size_t i) const
+    {
+      return getMixedModel().getNRate(i);
+    }
+
+    /**
+     * @brief retrieve a pointer to the submodel with the given name.
+     *
+     * Return Null if not found.
+     *
+     */
+  
+    const SubstitutionModel* getSubModelWithName(const std::string& name) const
+    {
+      return getMixedModel().getSubModelWithName(name);
+    }
   
-  /*
+    /*
      *@brief Returns the vector of numbers of the submodels in the
      *mixture that match a description.
-   *
-   */
-  Vint getSubmodelNumbers(std::string& desc) const;
-  
-private:
-  virtual MixedSubstitutionModel& getMixedModel() = 0;
+     *
+     */
+    Vint getSubmodelNumbers(const std::string& desc) const;
+
+    const SubstitutionModel& getSubstitutionModel() const { return *pmixmodel_.get(); }
+
+    const MixedSubstitutionModel& getMixedModel() const { return *pmixmodel_.get(); }
+    
+  protected:
+    SubstitutionModel& getSubstitutionModel() { return *pmixmodel_.get(); }
+    
+    MixedSubstitutionModel& getMixedModel() { return *pmixmodel_.get(); }
+
+    const FrequenciesSet* getFrequenciesSet() const {return pmixmodel_->getNModel(1)->getFrequenciesSet();}
+  };
 
-};
 } // end of namespace bpp.
 
 #endif  // _AbstractBiblioMixedSubstitutionModel_H_
diff --git a/src/Bpp/Phyl/Model/AbstractBiblioSubstitutionModel.cpp b/src/Bpp/Phyl/Model/AbstractBiblioSubstitutionModel.cpp
index 00bad09..8828d7d 100644
--- a/src/Bpp/Phyl/Model/AbstractBiblioSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/AbstractBiblioSubstitutionModel.cpp
@@ -97,6 +97,7 @@ void AbstractBiblioSubstitutionModel::addRateParameter()
 {
   getModel().addRateParameter();
   addParameter_(new Parameter(getNamespace() + "rate", getModel().getRate(), &Parameter::R_PLUS_STAR));
+  
   mapParNamesFromPmodel_[getNamespace() + "rate"] = "rate";
   lParPmodel_.reset();
   lParPmodel_.addParameters(getModel().getParameters());
@@ -110,8 +111,8 @@ void AbstractBiblioSubstitutionModel::setNamespace(const std::string& name)
 
   std::map<std::string, std::string> mapParNamesFromPmodel_new;
 
-  for (auto it=mapParNamesFromPmodel_.begin(); it!=mapParNamesFromPmodel_.end(); it++)
-    mapParNamesFromPmodel_new[name+getModel().getParameterNameWithoutNamespace(it->first)]=it->second;
+  for (const auto& it : mapParNamesFromPmodel_)
+    mapParNamesFromPmodel_new[name+getModel().getParameterNameWithoutNamespace(it.first)]=it.second;
   
   mapParNamesFromPmodel_.clear();
   mapParNamesFromPmodel_=mapParNamesFromPmodel_new;
@@ -127,12 +128,12 @@ void AbstractBiblioSubstitutionModel::setNamespace(const std::string& name)
 
 void AbstractBiblioSubstitutionModel::setFreq(std::map<int, double>& m)
 {
-  getModel().setFreq(m);
+  AbstractTotallyWrappedSubstitutionModel::setFreq(m);
 
   ParameterList pl;
-  for (auto it = mapParNamesFromPmodel_.begin(); it != mapParNamesFromPmodel_.end(); it++)
+  for (const auto& it : mapParNamesFromPmodel_)
   {
-    pl.addParameter(Parameter(getNamespace() + it->second, getModel().getParameterValue(getModel().getParameterNameWithoutNamespace(it->first))));
+    pl.addParameter(Parameter(getNamespace() + it.second, getModel().getParameterValue(getModel().getParameterNameWithoutNamespace(it.first))));
   }
 
   matchParametersValues(pl);
@@ -141,11 +142,12 @@ void AbstractBiblioSubstitutionModel::setFreq(std::map<int, double>& m)
 
 void AbstractBiblioSubstitutionModel::setFreqFromData(const SequenceContainer& data, double pseudoCount)
 {
-  getModel().setFreqFromData(data, pseudoCount);
+  AbstractTotallyWrappedSubstitutionModel::setFreqFromData(data, pseudoCount);
+  
   ParameterList pl;
-  for (auto it = mapParNamesFromPmodel_.begin(); it != mapParNamesFromPmodel_.end(); it++)
+  for (const auto& it : mapParNamesFromPmodel_)
   {
-    pl.addParameter(Parameter(getNamespace() + it->second, getModel().getParameterValue(getModel().getParameterNameWithoutNamespace(it->first))));
+    pl.addParameter(Parameter(getNamespace() + it.second, getModel().getParameterValue(getModel().getParameterNameWithoutNamespace(it.first))));
   }
 
   matchParametersValues(pl);
diff --git a/src/Bpp/Phyl/Model/AbstractBiblioSubstitutionModel.h b/src/Bpp/Phyl/Model/AbstractBiblioSubstitutionModel.h
index f2d1095..ec841b9 100644
--- a/src/Bpp/Phyl/Model/AbstractBiblioSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/AbstractBiblioSubstitutionModel.h
@@ -37,10 +37,11 @@
   knowledge of the CeCILL license and that you accept its terms.
 */
 
-#ifndef _ABSTRACTBIBLIOSUBSTITUTIONMODEL_H_
-#define _ABSTRACTBIBLIOSUBSTITUTIONMODEL_H_
+#ifndef _ABSTRACT_BIBLIO_SUBSTITUTIONMODEL_H_
+#define _ABSTRACT_BIBLIO_SUBSTITUTIONMODEL_H_
 
 #include "SubstitutionModel.h"
+#include "AbstractWrappedModel.h"
 
 #include <Bpp/Numeric/AbstractParameterAliasable.h>
 
@@ -54,7 +55,7 @@ namespace bpp
  */
 
   class AbstractBiblioSubstitutionModel :
-    public virtual SubstitutionModel,
+    public virtual AbstractTotallyWrappedSubstitutionModel,
     public AbstractParameterAliasable
   {
   protected:
@@ -79,14 +80,9 @@ namespace bpp
 
     virtual AbstractBiblioSubstitutionModel* clone() const = 0;
 
-  public:
-    virtual const SubstitutionModel& getModel() const = 0;
-
   protected:
     virtual void updateMatrices();
 
-    virtual SubstitutionModel& getModel() = 0;
-    
   public:
 
     
@@ -105,73 +101,12 @@ namespace bpp
      * @{
      */
 
-    const std::vector<int>& getAlphabetStates() const { return getModel().getAlphabetStates(); }
-
-    const StateMap& getStateMap() const { return getModel().getStateMap(); }
-
-    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); }
-
-    virtual double Qij(size_t i, size_t j) const { return getModel().Qij(i, j); }
-
-    virtual double Pij_t    (size_t i, size_t j, double t) const { return getModel().Pij_t(i, j, t); }
-    virtual double dPij_dt  (size_t i, size_t j, double t) const { return getModel().dPij_dt (i, j, t); }
-    virtual double d2Pij_dt2(size_t i, size_t j, double t) const { return getModel().d2Pij_dt2(i, j, t); }
-
-    virtual const Vdouble& getFrequencies() const { return getModel().getFrequencies(); }
-
-    const Matrix<double>& getGenerator() const { return getModel().getGenerator(); }
-
-    const Matrix<double>& getExchangeabilityMatrix() const { return getModel().getExchangeabilityMatrix(); }
-
-    double Sij(size_t i, size_t j) const { return getModel().Sij(i, j); }
-
-    const Matrix<double>& getPij_t(double t) const { return getModel().getPij_t(t); }
-
-    const Matrix<double>& getdPij_dt(double t) const { return getModel().getdPij_dt(t); }
-
-    const Matrix<double>& getd2Pij_dt2(double t) const { return getModel().getd2Pij_dt2(t); }
-
-    void enableEigenDecomposition(bool yn) { getModel().enableEigenDecomposition(yn); }
-
-    bool enableEigenDecomposition() { return getModel().enableEigenDecomposition(); }
-
-    bool isDiagonalizable() const { return getModel().isDiagonalizable(); }
-
-    bool isNonSingular() const { return getModel().isNonSingular(); }
-
-    const Vdouble& getEigenValues() const { return getModel().getEigenValues(); }
-
-    const Vdouble& getIEigenValues() const { return getModel().getIEigenValues(); }
-
-    const Matrix<double>& getRowLeftEigenVectors() const { return getModel().getRowLeftEigenVectors(); }
-    const Matrix<double>& getColumnRightEigenVectors() const { return getModel().getColumnRightEigenVectors(); }
-
-    double getRate() const { return getModel().getRate(); }
-
-    void setRate(double rate) { return getModel().setRate(rate); }
-
     void addRateParameter();
 
     void setFreqFromData(const SequenceContainer& data, double pseudoCount = 0);
 
     void setFreq(std::map<int, double>& frequ);
 
-    const Alphabet* getAlphabet() const { return getModel().getAlphabet(); }
-
-    size_t getNumberOfStates() const { return getModel().getNumberOfStates(); }
-
-    double getInitValue(size_t i, int state) const throw (BadIntException) { return getModel().getInitValue(i, state); }
-
-    const FrequenciesSet* getFrequenciesSet() const {return getModel().getFrequenciesSet(); }
-
     /*
      * @}
      *
@@ -182,7 +117,7 @@ namespace bpp
      *
      * @{
      */
-
+    
     /**
      * @brief Tells the model that a parameter value has changed.
      *
@@ -204,26 +139,6 @@ namespace bpp
 
     void setNamespace(const std::string& name);
   
-  public:
-    bool isScalable() const 
-    {
-      return getModel().isScalable();
-    }
-
-    void setScalable(bool scalable)
-    {
-      getModel().setScalable(scalable);
-    }
-
-    void normalize()
-    {
-      getModel().normalize();
-    }
-    
-    double getScale() const { return getModel().getScale(); }
-
-    void setScale(double scale) { getModel().setScale(scale); }
-
     /*
      * @}
      */
diff --git a/src/Bpp/Phyl/Model/AbstractFromSubstitutionModelTransitionModel.cpp b/src/Bpp/Phyl/Model/AbstractFromSubstitutionModelTransitionModel.cpp
index 6523a56..c8a7ed7 100644
--- a/src/Bpp/Phyl/Model/AbstractFromSubstitutionModelTransitionModel.cpp
+++ b/src/Bpp/Phyl/Model/AbstractFromSubstitutionModelTransitionModel.cpp
@@ -44,15 +44,15 @@ using namespace std;
 
 /******************************************************************************/
 
-AbstractFromSubstitutionModelTransitionModel::AbstractFromSubstitutionModelTransitionModel(const SubstitutionModel& subModel) :
-  AbstractParameterAliasable(subModel.getName()),
+AbstractFromSubstitutionModelTransitionModel::AbstractFromSubstitutionModelTransitionModel(const SubstitutionModel& subModel, const std::string& prefix) :
+  AbstractParameterAliasable(prefix+subModel.getNamespace()),
   subModel_(std::unique_ptr<SubstitutionModel>(subModel.clone())),
   size_(subModel.getNumberOfStates()),
   pij_t(size_, size_),
   dpij_t(size_, size_),
   d2pij_t(size_, size_)
 {
-  subModel_->setNamespace(getName());
+  subModel_->setNamespace(getNamespace());
   addParameters_(subModel_->getParameters());
 }
 
diff --git a/src/Bpp/Phyl/Model/AbstractFromSubstitutionModelTransitionModel.h b/src/Bpp/Phyl/Model/AbstractFromSubstitutionModelTransitionModel.h
index 33dc2b8..6f3e57c 100644
--- a/src/Bpp/Phyl/Model/AbstractFromSubstitutionModelTransitionModel.h
+++ b/src/Bpp/Phyl/Model/AbstractFromSubstitutionModelTransitionModel.h
@@ -40,7 +40,7 @@
 #ifndef _ABSTRACT_FROM_SUBSTITUTION_MODEL_TRANSITION_MODEL_H_
 #define _ABSTRACT_FROM_SUBSTITUTION_MODEL_TRANSITION_MODEL_H_
 
-#include "SubstitutionModel.h"
+#include "AbstractWrappedModel.h"
 
 namespace bpp
 {
@@ -52,8 +52,8 @@ namespace bpp
  */
 
   class AbstractFromSubstitutionModelTransitionModel :
-    public virtual TransitionModel,
-    public AbstractParameterAliasable
+    public virtual AbstractWrappedModel,
+    virtual public AbstractParameterAliasable
   {
   protected:
     /*
@@ -78,7 +78,7 @@ namespace bpp
     mutable RowMatrix<double> d2pij_t;
 
   public:
-    AbstractFromSubstitutionModelTransitionModel(const SubstitutionModel& subModel);
+    AbstractFromSubstitutionModelTransitionModel(const SubstitutionModel& subModel, const std::string& prefix);
 
     AbstractFromSubstitutionModelTransitionModel(const AbstractFromSubstitutionModelTransitionModel& fmsm);
 
@@ -89,91 +89,61 @@ namespace bpp
     virtual AbstractFromSubstitutionModelTransitionModel* clone() const = 0;
     
   public:
-    const SubstitutionModel& getModel() const
+    const SubstitutionModel& getSubstitutionModel() const
     {
       return *subModel_.get();
     }
 
-  protected:
-    SubstitutionModel& getModel()
+    const TransitionModel& getModel() const
     {
       return *subModel_.get();
     }
+
+    bool computeFrequencies() const
+    {
+      return subModel_->computeFrequencies();
+    }
+
+    /**
+     * @return Set if equilibrium frequencies should be computed from
+     * the generator
+     */
     
-  public:
+    void computeFrequencies(bool yn)
+    {
+      subModel_->computeFrequencies(yn);
+    }
+
     /*
-     *@ brief Methods to supersede SubstitutionModel methods.
+     * @}
      *
-     * @{
      */
 
-    const Alphabet* getAlphabet() const { return getModel().getAlphabet(); }
-
-    size_t getNumberOfStates() const { return getModel().getNumberOfStates(); }
-
-    const std::vector<int>& getAlphabetStates() const { return getModel().getAlphabetStates(); }
-
-    const StateMap& getStateMap() const { return getModel().getStateMap(); }
-
-    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); }
+  protected:
 
-    std::vector<size_t> getModelStates(const std::string& code) const { return getModel().getModelStates(code); }
+    Vdouble& getFrequencies_()
+    {
+      return subModel_->getFrequencies_();
+    }
 
-    virtual double freq(size_t i) const = 0;
+    SubstitutionModel& getSubstitutionModel()
+    {
+      return *subModel_.get();
+    }
 
-    virtual double Pij_t (size_t i, size_t j, double t) const = 0;
-    
-    virtual double dPij_dt (size_t i, size_t j, double t) const = 0;
     
-    virtual double d2Pij_dt2(size_t i, size_t j, double t) const = 0;
-
-    virtual const Vdouble& getFrequencies() const = 0;
-
-    virtual const Matrix<double>& getPij_t(double t) const = 0;
-
-    virtual const Matrix<double>& getdPij_dt(double t) const = 0;
-
-    virtual const Matrix<double>& getd2Pij_dt2(double t) const = 0;
-
-    double getRate() const { return getModel().getRate(); }
-
-    void setRate(double rate) { return getModel().setRate(rate); }
+    TransitionModel& getModel()
+    {
+      return *subModel_.get();
+    }
 
-    void addRateParameter()
+  public:
+    virtual void addRateParameter()
     {
       getModel().addRateParameter();
       addParameter_(new Parameter(getNamespace() + "rate", getModel().getRate(), &Parameter::R_PLUS_STAR));
     }
 
-    void setFreqFromData(const SequenceContainer& data, double pseudoCount = 0){getModel().setFreqFromData(data, pseudoCount); }
-
-    void setFreq(std::map<int, double>& frequ) {getModel().setFreq(frequ); }
-
-    double getInitValue(size_t i, int state) const throw (BadIntException) { return getModel().getInitValue(i, state); }
-
-    virtual const FrequenciesSet* getFrequenciesSet() const = 0;
-
-    /*
-     * @}
-     *
-     */
-
-    /*
-     *@ brief Methods to supersede AbstractSubstitutionModel methods.
-     *
-     * @{
-     */
-
-    /**
-     * @brief Tells the model that a parameter value has changed.
-     *
-     * This updates the matrices consequently.
-     */
-    
     virtual void fireParameterChanged(const ParameterList& parameters)
     {
       AbstractParameterAliasable::fireParameterChanged(parameters);
@@ -186,15 +156,6 @@ namespace bpp
       getModel().setNamespace(name);
     }
 
-    /*
-     * @}
-     */
-
-    virtual std::string getName() const
-    {
-      return getModel().getName();
-    }
-    
   };
 } // end of namespace bpp.
 
diff --git a/src/Bpp/Phyl/Model/AbstractKroneckerWordSubstitutionModel.cpp b/src/Bpp/Phyl/Model/AbstractKroneckerWordSubstitutionModel.cpp
index 989174f..4a2c2a0 100644
--- a/src/Bpp/Phyl/Model/AbstractKroneckerWordSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/AbstractKroneckerWordSubstitutionModel.cpp
@@ -56,6 +56,9 @@ AbstractKroneckerWordSubstitutionModel::AbstractKroneckerWordSubstitutionModel(
   vGenerators_()
 {
   enableEigenDecomposition(true);
+  for (auto& submod : VSubMod_)
+    submod->enableEigenDecomposition(false);
+
   initGenerators_();
 }
 
@@ -72,6 +75,9 @@ AbstractKroneckerWordSubstitutionModel::AbstractKroneckerWordSubstitutionModel(
     throw Exception("AbstractKroneckerWordSubstitutionModel::AbstractKroneckerWordSubstitutionModel: Bad set of changing positions ");
 
   enableEigenDecomposition(true);
+  for (auto& submod : VSubMod_)
+    submod->enableEigenDecomposition(false);
+
   initGenerators_();
 }
 
@@ -85,6 +91,9 @@ AbstractKroneckerWordSubstitutionModel::AbstractKroneckerWordSubstitutionModel(
   vGenerators_()
 {
   enableEigenDecomposition(true);
+  for (auto& submod : VSubMod_)
+    submod->enableEigenDecomposition(false);
+
   initGenerators_();  
 }
 
@@ -102,6 +111,9 @@ AbstractKroneckerWordSubstitutionModel::AbstractKroneckerWordSubstitutionModel(
     throw Exception("AbstractKroneckerWordSubstitutionModel::AbstractKroneckerWordSubstitutionModel: Bad set of changing positions ");
 
   enableEigenDecomposition(true);
+  for (auto& submod : VSubMod_)
+    submod->enableEigenDecomposition(false);
+
   initGenerators_();
 }
 
@@ -115,6 +127,8 @@ AbstractKroneckerWordSubstitutionModel::AbstractKroneckerWordSubstitutionModel(
   vGenerators_()
 {
   enableEigenDecomposition(true);
+  for (auto& submod : VSubMod_)
+    submod->enableEigenDecomposition(false);
 }
 
 AbstractKroneckerWordSubstitutionModel::AbstractKroneckerWordSubstitutionModel(
@@ -168,9 +182,9 @@ bool AbstractKroneckerWordSubstitutionModel::checkChangingPositions_()
 {
   size_t nbmod = VSubMod_.size();
   
-  for (auto i=sChangingPos_.begin(); i!=sChangingPos_.end(); i++)
+  for (const auto& i : sChangingPos_)
   {
-    if (*(--((*i).end()))>nbmod || *((*i).begin())==0)
+    if (*(--(i.end()))>nbmod || *(i.begin())==0)
       return false;
   }
   
@@ -195,15 +209,15 @@ void AbstractKroneckerWordSubstitutionModel::fillBasicGenerator()
   }
   else
   {
-    for (auto i=sChangingPos_.begin(); i!=sChangingPos_.end(); i++)
+    bool begin(true);
+    
+    for (const auto& i : sChangingPos_)
     {
-      const set<size_t>& sPos=(*i);
-
       size_t pos=0;
 
-      for (auto iPos=sPos.begin(); iPos!=sPos.end(); iPos++)
+      for (const auto& iPos : i)
       {
-        size_t posok=(*iPos)-1; // position of the next generator to multiply
+        size_t posok=iPos-1; // position of the next generator to multiply
 
         if (pos==0)
         {
@@ -242,8 +256,11 @@ void AbstractKroneckerWordSubstitutionModel::fillBasicGenerator()
         pos++;
       }
 
-      if (i==sChangingPos_.begin())
+      if (begin)
+      {
+        begin=false;
         generator_=vGenerators_[nbmod-1];
+      }
       else
         MatrixTools::add(generator_, vGenerators_[nbmod-1]);
     }
diff --git a/src/Bpp/Phyl/Model/AbstractSubstitutionModel.cpp b/src/Bpp/Phyl/Model/AbstractSubstitutionModel.cpp
index 98cc9a0..babc06e 100644
--- a/src/Bpp/Phyl/Model/AbstractSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/AbstractSubstitutionModel.cpp
@@ -53,7 +53,7 @@ using namespace std;
 
 /******************************************************************************/
 
-AbstractSubstitutionModel::AbstractSubstitutionModel(const Alphabet* alpha, StateMap* stateMap, const std::string& prefix) :
+AbstractSubstitutionModel::AbstractSubstitutionModel(const Alphabet* alpha, const StateMap* stateMap, const std::string& prefix) :
   AbstractParameterAliasable(prefix),
   alphabet_(alpha),
   stateMap_(stateMap),
@@ -62,6 +62,7 @@ AbstractSubstitutionModel::AbstractSubstitutionModel(const Alphabet* alpha, Stat
   rate_(1),
   generator_(size_, size_),
   freq_(size_),
+  computeFreq_(true),
   exchangeability_(size_, size_),
   pijt_(size_, size_),
   dpijt_(size_, size_),
@@ -76,57 +77,243 @@ AbstractSubstitutionModel::AbstractSubstitutionModel(const Alphabet* alpha, Stat
   vPowGen_(),
   tmpMat_(size_, size_)
 {
-  for (size_t i = 0; i < size_; i++)
-  {
-    freq_[i] = 1.0 / static_cast<double>(size_);
-  }
+  if (computeFrequencies())
+    for (auto& fr : freq_)
+      fr = 1.0 / static_cast<double>(size_);
 }
 
+
 /******************************************************************************/
 
 void AbstractSubstitutionModel::updateMatrices()
 {
-  // if the object is not an AbstractReversibleSubstitutionModel,
-  // computes the exchangeability_ Matrix (otherwise the generator_
-  // has been computed from the exchangeability_)
+  // Compute eigen values and vectors:
+  if (enableEigenDecomposition())
+  {
+    // Look for null lines (such as stop lines)
+    // ie null diagonal elements
+
+    size_t nbStop=0;
+    size_t salph = getNumberOfStates();
+    vector<bool> vnull(salph); // vector of the indices of lines with
+                               // only zeros
 
-  if (!dynamic_cast<AbstractReversibleSubstitutionModel*>(this)) {
-    for (size_t i = 0; i < size_; i++)
+    for (size_t i = 0; i < salph; i++)
     {
-      for (size_t j = 0; j < size_; j++)
+      if (abs(generator_(i, i)) < NumConstants::TINY())
       {
-        exchangeability_(i, j) = generator_(i, j) / freq_[j];
+        nbStop++;
+        vnull[i]=true;
       }
+      else
+        vnull[i]=false;
     }
-  }
+        
+    if (nbStop != 0)
+    {
+      size_t salphok=salph - nbStop;
+      
+      RowMatrix<double> gk(salphok, salphok);
+      size_t gi = 0, gj = 0;
 
-  // Compute eigen values and vectors:
-  if (enableEigenDecomposition())
-  {
-    EigenValue<double> ev(generator_);
-    rightEigenVectors_ = ev.getV();
-    eigenValues_ = ev.getRealEigenValues();
-    iEigenValues_ = ev.getImagEigenValues();
+      for (size_t i = 0; i < salph; i++)
+      {
+        if (!vnull[i])
+        {
+          gj = 0;
+          for (size_t j = 0; j < salph; j++)
+          {
+            if (!vnull[j])
+            {
+              gk(i - gi, j - gj) = generator_(i, j);
+            }
+            else
+              gj++;
+          }
+        }
+        else
+          gi++;
+      }
+
+      EigenValue<double> ev(gk);
+      eigenValues_ = ev.getRealEigenValues();
+      iEigenValues_ = ev.getImagEigenValues();
+
+      for (size_t i = 0; i < nbStop; i++)
+      {
+        eigenValues_.push_back(0);
+        iEigenValues_.push_back(0);
+      }
+
+      RowMatrix<double> rev = ev.getV();
+      rightEigenVectors_.resize(salph, salph);
+      gi = 0;
+      for (size_t i = 0; i < salph; i++)
+      {
+        if (vnull[i])
+        {
+          gi++;
+          for (size_t j = 0; j < salph; j++)
+          {
+            rightEigenVectors_(i, j) = 0;
+          }
+
+          rightEigenVectors_(i, salphok + gi - 1) = 1;
+        }
+        else
+        {
+          for (size_t j = 0; j < salphok; j++)
+          {
+            rightEigenVectors_(i, j) = rev(i - gi, j);
+          }
+
+          for (size_t j = salphok; j < salph; j++)
+          {
+            rightEigenVectors_(i, j) = 0;
+          }
+        }
+      }
+    }
+    else
+    {
+      EigenValue<double> ev(generator_);
+      rightEigenVectors_ = ev.getV();
+      eigenValues_ = ev.getRealEigenValues();
+      iEigenValues_ = ev.getImagEigenValues();
+      nbStop = 0;
+    }
+
+    /// Now check inversion and diagonalization
     try
     {
       MatrixTools::inv(rightEigenVectors_, leftEigenVectors_);
-      isNonSingular_ = true;
+
+      // is it diagonalizable ?
       isDiagonalizable_ = true;
-      for (size_t i = 0; i < size_ && isDiagonalizable_; i++)
+
+      if (!dynamic_cast<ReversibleSubstitutionModel*>(this))
       {
-        if (abs(iEigenValues_[i]) > NumConstants::TINY())
-          isDiagonalizable_ = false;
+        for (auto& vi : iEigenValues_)
+        {
+          if (abs(vi) > NumConstants::TINY())
+          {
+            isDiagonalizable_ = false;
+            break;
+          }
+        }
+      }
+      
+      // looking for the vector of 0 eigenvalues
+
+      vector<size_t> vNullEv;
+      for (size_t i = 0; i< salph - nbStop; i++)
+        if ((abs(eigenValues_[i]) < NumConstants::SMALL()) && (abs(iEigenValues_[i]) < NumConstants::SMALL()))
+          vNullEv.push_back(i);
+      
+
+      // pb to find unique null eigenvalue      
+      isNonSingular_=(vNullEv.size()==1);
+
+      size_t nulleigen;
+      
+      double val;
+      if (!isNonSingular_)
+      {
+        //look or check which non-stop right eigen vector elements are
+        //equal.
+        for (auto cnull : vNullEv)
+        {
+          size_t i = 0;
+          while (vnull[i])
+            i++;
+          
+          val = rightEigenVectors_(i, cnull);
+          i++;
+          
+          while (i < salph)
+          {
+            if (!vnull[i])
+            {
+              if (abs(rightEigenVectors_(i, cnull) - val) > NumConstants::SMALL())
+                break;
+            }
+            i++;
+          }
+          
+          if (i >= salph)
+          {
+            isNonSingular_ = true;
+            nulleigen=cnull;
+            break;
+          }
+        }
+      }
+      else
+        nulleigen=vNullEv[0];
+      
+      if (isNonSingular_)
+      {
+        eigenValues_[nulleigen] = 0; // to avoid approximation errors on long long branches
+        iEigenValues_[nulleigen] = 0; // to avoid approximation errors on long long branches
+
+        if (computeFrequencies())
+        {
+          for (size_t i = 0; i < salph; i++)
+            freq_[i] = leftEigenVectors_(nulleigen, i);
+        
+          double x = VectorTools::sum(freq_);        
+          freq_ /= x;
+        }
+      }
+      else
+      {
+        ApplicationTools::displayMessage("AbstractSubstitutionModel::updateMatrices : Unable to find eigenvector for eigenvalue 0. Taylor series used instead.");
+        isDiagonalizable_ = false;
       }
     }
+    // if rightEigenVectors_ is singular
     catch (ZeroDivisionException& e)
     {
-      ApplicationTools::displayMessage("Singularity during diagonalization. Taylor series used instead.");
-
+      ApplicationTools::displayMessage("AbstractSubstitutionModel::updateMatrices : Singularity during diagonalization. Taylor series used instead.");
       isNonSingular_ = false;
       isDiagonalizable_ = false;
-      MatrixTools::Taylor(generator_, 30, vPowGen_);
     }
+
+    if (!isNonSingular_)
+    {
+      double min = generator_(0, 0);
+      for (size_t i = 1; i < salph; i++)
+      {
+        if (min > generator_(i, i))
+          min = generator_(i, i);
+      }
+
+      setScale(-1 / min);
+
+      if (vPowGen_.size() == 0)
+        vPowGen_.resize(30);
+
+      
+      if (computeFrequencies())
+      {
+        MatrixTools::getId(salph, tmpMat_);    // to compute the equilibrium frequency  (Q+Id)^256
+        MatrixTools::add(tmpMat_, generator_);
+        MatrixTools::pow(tmpMat_, 256, vPowGen_[0]);
+
+        for (size_t i = 0; i < salph; i++)
+          freq_[i] = vPowGen_[0](0, i);
+      }
+
+      MatrixTools::getId(salph, vPowGen_[0]);
+    }
+
+    // normalization
+    normalize();
+    
+    if (!isNonSingular_)
+      MatrixTools::Taylor(generator_, 30, vPowGen_);
   }
+
 }
 
 
@@ -373,13 +560,14 @@ void AbstractSubstitutionModel::setFreqFromData(const SequenceContainer& data, d
 {
   map<int, int> counts;
   SequenceContainerTools::getCounts(data, counts);
-  double t = 0;
   map<int, double> freqs;
 
-  for (int i = 0; i < static_cast<int>(size_); i++)
-  {
-    t += (counts[i] + pseudoCount);
-  }
+  double t = 0;
+  for (auto& ci : counts)
+    t+=ci.second;
+
+  t+= pseudoCount*(double)counts.size();
+  
   for (int i = 0; i < static_cast<int>(size_); i++)
   {
     freqs[i] = (static_cast<double>(counts[i]) + pseudoCount) / t;
@@ -425,6 +613,25 @@ void AbstractSubstitutionModel::setScale(double scale)
 
 /******************************************************************************/
 
+void AbstractSubstitutionModel::setDiagonal()
+{
+  for (size_t i = 0; i < size_; i++)
+  {
+    double lambda=0;
+    Vdouble& row=generator_.getRow(i);
+    
+    for (size_t j = 0; j < size_; j++)
+    {
+      if (j != i)
+        lambda += row[j];
+    }
+    row[i] = -lambda;
+  }
+}
+
+
+/******************************************************************************/
+
 void AbstractSubstitutionModel::normalize() 
 {
   if (isScalable_)
@@ -460,32 +667,11 @@ void AbstractSubstitutionModel::addRateParameter()
 
 void AbstractReversibleSubstitutionModel::updateMatrices()
 {
-  RowMatrix<double> Pi;
-  MatrixTools::diag(freq_, Pi);
-  MatrixTools::mult(exchangeability_, Pi, generator_); // Diagonal elements of the exchangability matrix will be ignored.
+  MatrixTools::hadamardMult(exchangeability_, freq_, generator_, false); // Diagonal elements of the exchangeability matrix will be ignored.
 
-  // Compute diagonal elements of the generator:
-  for (size_t i = 0; i < size_; i++)
-  {
-    double lambda = 0;
-    for (size_t j = 0; j < size_; j++)
-    {
-      if (j != i)
-        lambda += generator_(i, j);
-    }
-    generator_(i, i) = -lambda;
-  }
-  
   // Normalization:
   normalize();
   
-  // Compute diagonal elements of the exchangeability matrix:
-  for (size_t i = 0; i < size_; i++)
-    for (size_t j = 0; j < size_; j++)
-    {
-      exchangeability_(i, j) = generator_(i, j) / freq_[i];
-    }
-  
   AbstractSubstitutionModel::updateMatrices();
 }
 
diff --git a/src/Bpp/Phyl/Model/AbstractSubstitutionModel.h b/src/Bpp/Phyl/Model/AbstractSubstitutionModel.h
index f8f18c6..785bc37 100755
--- a/src/Bpp/Phyl/Model/AbstractSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/AbstractSubstitutionModel.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 _ABSTRACTSUBSTITUTIONMODEL_H_
 #define _ABSTRACTSUBSTITUTIONMODEL_H_
@@ -65,6 +65,7 @@ namespace bpp
  * This class also provides the updateMatrices() method, which computes eigen values and vectors and fills the corresponding vector (eigenValues_)
  * and matrices (leftEigenVectors_ and rightEigenVectors_) from the generator.
  *
+ *
  * The freq_ vector and generator_ matrices are hence the only things to provide to
  * create a substitution model.
  * It is also possible to redefine one of these methods for better efficiency.
@@ -75,327 +76,357 @@ namespace bpp
  * @note This class is dedicated to "simple" substitution models, for which the number of states is equivalent to the number of characters in the alphabet.
  * Consider using the MarkovModulatedSubstitutionModel for more complexe cases.
  */
-class AbstractSubstitutionModel :
-  public virtual SubstitutionModel,
-  public virtual AbstractParameterAliasable
-{
-protected:
-  /**
-   * @brief The alphabet relevant to this model.
-   */
-  const Alphabet* alphabet_;
-
-  /**
-   * @brief The map of model states with alphabet states.
-   */
-  std::unique_ptr<StateMap> stateMap_;
-
-  /**
-   * @brief The size of the generator, i.e. the number of states.
-   */
-  size_t size_;
-
-  /**
-   * @brief If the model is scalable (ie generator can be normalized
-   * automatically).
-   */
+  class AbstractSubstitutionModel :
+    public virtual SubstitutionModel,
+    public virtual AbstractParameterAliasable
+  {
+  protected:
+    /**
+     * @brief The alphabet relevant to this model.
+     */
+    const Alphabet* alphabet_;
+
+    /**
+     * @brief The map of model states with alphabet states.
+     */
+    std::shared_ptr<const StateMap> stateMap_;
+
+    /**
+     * @brief The size of the generator, i.e. the number of states.
+     */
+    size_t size_;
+
+    /**
+     * @brief If the model is scalable (ie generator can be normalized
+     * automatically).
+     */
   
-  bool isScalable_;
-
-  /**
-   * @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 generator matrix \f$Q\f$ of the model.
-   */
-  RowMatrix<double> generator_;
-
-  /**
-   * @brief The vector \f$\pi_e\f$ of equilibrium frequencies.
-   */
-  Vdouble freq_;
-
-  /**
-   * @brief The exchangeability matrix \f$S\f$ of the model, defined
-   * as \f$ S_{ij}=\frac{Q_{ij}}{\pi_j}\f$. When the model is
-   * reversible, this matrix is symetric.
-   *
-   */
-  RowMatrix<double> exchangeability_;
-
-  /**
-   * @brief These ones are for bookkeeping:
-   */
-  mutable RowMatrix<double> pijt_;
-  mutable RowMatrix<double> dpijt_;
-  mutable RowMatrix<double> d2pijt_;
-
-  /**
-   * @brief Tell if the eigen decomposition should be performed.
-   */
-  bool eigenDecompose_;
-
-  /**
-   * @brief The vector of eigen values.
-   */
-  Vdouble eigenValues_;
-
-  /**
-   * @brief The vector of the imaginary part of the eigen values.
-   */
-  Vdouble iEigenValues_;
-
-  /**
-   * @brief boolean value for diagonalizability in R of the generator_
-   */
-  bool isDiagonalizable_;
-
-  /**
-   * @brief The \f$U^-1\f$ matrix made of right eigen vectors (by column).
-   */
-  RowMatrix<double> rightEigenVectors_;
-
-  /**
-   * @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_;
+    bool isScalable_;
+
+    /**
+     * @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 generator matrix \f$Q\f$ of the model.
+     */
+    RowMatrix<double> generator_;
+
+    /**
+     * @brief The vector \f$\pi_e\f$ of equilibrium frequencies.
+     */
+    Vdouble freq_;
+
+    /**
+     * @brief if the Frequencies must be computed from the generator
+     */
   
-public:
-  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_),
-    isScalable_(model.isScalable_),
-    rate_(model.rate_),
-    generator_(model.generator_),
-    freq_(model.freq_),
-    exchangeability_(model.exchangeability_),
-    pijt_(model.pijt_),
-    dpijt_(model.dpijt_),
-    d2pijt_(model.d2pijt_),
-    eigenDecompose_(model.eigenDecompose_),
-    eigenValues_(model.eigenValues_),
-    iEigenValues_(model.iEigenValues_),
-    isDiagonalizable_(model.isDiagonalizable_),
-    rightEigenVectors_(model.rightEigenVectors_),
-    isNonSingular_(model.isNonSingular_),
-    leftEigenVectors_(model.leftEigenVectors_),
-    vPowGen_(model.vPowGen_),
-    tmpMat_(model.tmpMat_)
-  {}
-
-  AbstractSubstitutionModel& operator=(const AbstractSubstitutionModel& model)
-  {
-    AbstractParameterAliasable::operator=(model);
-    alphabet_          = model.alphabet_;
-    stateMap_.reset(model.stateMap_->clone());
-    size_              = model.size_;
-    isScalable_        = model.isScalable_;
-    rate_              = model.rate_;
-    generator_         = model.generator_;
-    freq_              = model.freq_;
-    exchangeability_   = model.exchangeability_;
-    pijt_              = model.pijt_;
-    dpijt_             = model.dpijt_;
-    d2pijt_            = model.d2pijt_;
-    eigenDecompose_    = model.eigenDecompose_;
-    eigenValues_       = model.eigenValues_;
-    iEigenValues_      = model.iEigenValues_;
-    isDiagonalizable_  = model.isDiagonalizable_;
-    rightEigenVectors_ = model.rightEigenVectors_;
-    isNonSingular_     = model.isNonSingular_;
-    leftEigenVectors_  = model.leftEigenVectors_;
-    vPowGen_           = model.vPowGen_;
-    tmpMat_            = model.tmpMat_;
-    return *this;
-  }
+    bool computeFreq_;
+
+    /**
+     * @brief The exchangeability matrix \f$S\f$ of the model, defined
+     * as \f$ S_{ij}=\frac{Q_{ij}}{\pi_j}\f$. When the model is
+     * reversible, this matrix is symetric.
+     *
+     */
+    RowMatrix<double> exchangeability_;
+
+    /**
+     * @brief These ones are for bookkeeping:
+     */
+    mutable RowMatrix<double> pijt_;
+    mutable RowMatrix<double> dpijt_;
+    mutable RowMatrix<double> d2pijt_;
+
+    /**
+     * @brief Tell if the eigen decomposition should be performed.
+     */
+    bool eigenDecompose_;
+
+    /**
+     * @brief The vector of eigen values.
+     */
+    Vdouble eigenValues_;
+
+    /**
+     * @brief The vector of the imaginary part of the eigen values.
+     */
+    Vdouble iEigenValues_;
+
+    /**
+     * @brief boolean value for diagonalizability in R of the generator_
+     */
+    bool isDiagonalizable_;
+
+    /**
+     * @brief The \f$U^-1\f$ matrix made of right eigen vectors (by column).
+     */
+    RowMatrix<double> rightEigenVectors_;
+
+    /**
+     * @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 StateMap* stateMap, const std::string& prefix);
+
+    AbstractSubstitutionModel(const AbstractSubstitutionModel& model) :
+      AbstractParameterAliasable(model),
+      alphabet_(model.alphabet_),
+      stateMap_(model.stateMap_),
+      size_(model.size_),
+      isScalable_(model.isScalable_),
+      rate_(model.rate_),
+      generator_(model.generator_),
+      freq_(model.freq_),
+      computeFreq_(model.computeFreq_),
+      exchangeability_(model.exchangeability_),
+      pijt_(model.pijt_),
+      dpijt_(model.dpijt_),
+      d2pijt_(model.d2pijt_),
+      eigenDecompose_(model.eigenDecompose_),
+      eigenValues_(model.eigenValues_),
+      iEigenValues_(model.iEigenValues_),
+      isDiagonalizable_(model.isDiagonalizable_),
+      rightEigenVectors_(model.rightEigenVectors_),
+      isNonSingular_(model.isNonSingular_),
+      leftEigenVectors_(model.leftEigenVectors_),
+      vPowGen_(model.vPowGen_),
+      tmpMat_(model.tmpMat_)
+    {}
+
+    AbstractSubstitutionModel& operator=(const AbstractSubstitutionModel& model)
+    {
+      AbstractParameterAliasable::operator=(model);
+      alphabet_          = model.alphabet_;
+      stateMap_.reset(model.stateMap_->clone());
+      size_              = model.size_;
+      isScalable_        = model.isScalable_;
+      rate_              = model.rate_;
+      generator_         = model.generator_;
+      freq_              = model.freq_;
+      computeFreq_       = model.computeFreq_;
+      exchangeability_   = model.exchangeability_;
+      pijt_              = model.pijt_;
+      dpijt_             = model.dpijt_;
+      d2pijt_            = model.d2pijt_;
+      eigenDecompose_    = model.eigenDecompose_;
+      eigenValues_       = model.eigenValues_;
+      iEigenValues_      = model.iEigenValues_;
+      isDiagonalizable_  = model.isDiagonalizable_;
+      rightEigenVectors_ = model.rightEigenVectors_;
+      isNonSingular_     = model.isNonSingular_;
+      leftEigenVectors_  = model.leftEigenVectors_;
+      vPowGen_           = model.vPowGen_;
+      tmpMat_            = model.tmpMat_;
+      return *this;
+    }
   
-  virtual ~AbstractSubstitutionModel() {}
+    virtual ~AbstractSubstitutionModel() {}
 
-  virtual AbstractSubstitutionModel* clone() const = 0;
+    virtual AbstractSubstitutionModel* clone() const = 0;
 
-public:
-  const Alphabet* getAlphabet() const { return alphabet_; }
+  public:
+    const Alphabet* getAlphabet() const { return alphabet_; }
 
-  const StateMap& getStateMap() const { return *stateMap_; }
+    const StateMap& getStateMap() const { return *stateMap_; }
 
-  const std::vector<int>& getAlphabetStates() const { return stateMap_->getAlphabetStates(); }
+    const std::vector<int>& getAlphabetStates() const { return stateMap_->getAlphabetStates(); }
 
-  std::string getAlphabetStateAsChar(size_t index) const { return stateMap_->getAlphabetStateAsChar(index); }
+    std::string getAlphabetStateAsChar(size_t index) const { return stateMap_->getAlphabetStateAsChar(index); }
 
-  int getAlphabetStateAsInt(size_t index) const { return stateMap_->getAlphabetStateAsInt(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(int code) const { return stateMap_->getModelStates(code); }
   
-  std::vector<size_t> getModelStates(const std::string& 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_; }
 
-  virtual const Vdouble& getFrequencies() const { return freq_; }
+    bool computeFrequencies() const { return computeFreq_; }
 
-  const Matrix<double>& getGenerator() const { return generator_; }
+    void computeFrequencies(bool yn) { computeFreq_=yn; }
 
-  const Matrix<double>& getExchangeabilityMatrix() const { return exchangeability_; }
+    const Matrix<double>& getGenerator() const { return generator_; }
 
-  double Sij(size_t i, size_t j) const { return exchangeability_(i, j); }
+    const Matrix<double>& getExchangeabilityMatrix() const { return exchangeability_; }
 
-  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;
+    double Sij(size_t i, size_t j) const { return exchangeability_(i, j); }
 
-  const Vdouble& getEigenValues() const { return eigenValues_; }
+    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;
 
-  const Vdouble& getIEigenValues() const { return iEigenValues_; }
+    const Vdouble& getEigenValues() const { return eigenValues_; }
 
-  bool isDiagonalizable() const { return isDiagonalizable_; }
+    const Vdouble& getIEigenValues() const { return iEigenValues_; }
+
+    bool isDiagonalizable() const { return isDiagonalizable_; }
   
-  bool isNonSingular() const { return isNonSingular_; }
+    bool isNonSingular() const { return isNonSingular_; }
 
-  const Matrix<double>& getRowLeftEigenVectors() const { return leftEigenVectors_; }
+    const Matrix<double>& getRowLeftEigenVectors() const { return leftEigenVectors_; }
 
-  const Matrix<double>& getColumnRightEigenVectors() const { return rightEigenVectors_; }
+    const Matrix<double>& getColumnRightEigenVectors() const { return rightEigenVectors_; }
 
-  virtual double freq(size_t i) const { return freq_[i]; }
+    virtual double freq(size_t i) const { return freq_[i]; }
 
-  virtual double Qij(size_t i, size_t j) const { return generator_(i, j); }
+    virtual double Qij(size_t i, size_t j) const { return generator_(i, j); }
 
-  virtual double Pij_t    (size_t i, size_t j, double t) const { return getPij_t(t) (i, j); }
-  virtual double dPij_dt  (size_t i, size_t j, double t) const { return getdPij_dt(t) (i, j); }
-  virtual double d2Pij_dt2(size_t i, size_t j, double t) const { return getd2Pij_dt2(t) (i, j); }
+    virtual double Pij_t    (size_t i, size_t j, double t) const { return getPij_t(t) (i, j); }
+    virtual double dPij_dt  (size_t i, size_t j, double t) const { return getdPij_dt(t) (i, j); }
+    virtual double d2Pij_dt2(size_t i, size_t j, double t) const { return getd2Pij_dt2(t) (i, j); }
 
-  double getInitValue(size_t i, int state) const throw (IndexOutOfBoundsException, BadIntException);
+    double getInitValue(size_t i, int state) const throw (IndexOutOfBoundsException, BadIntException);
 
-  void setFreqFromData(const SequenceContainer& data, double pseudoCount = 0);
+    void setFreqFromData(const SequenceContainer& data, double pseudoCount = 0);
 
-  virtual void setFreq(std::map<int, double>&);
+    virtual void setFreq(std::map<int, double>&);
 
-  void enableEigenDecomposition(bool yn) { eigenDecompose_ = yn; }
+    void enableEigenDecomposition(bool yn) { eigenDecompose_ = yn; }
 
-  bool enableEigenDecomposition() { return eigenDecompose_; }
+    bool enableEigenDecomposition() { return eigenDecompose_; }
 
-  /**
-   * @brief Tells the model that a parameter value has changed.
-   *
-   * This updates the matrices consequently.
-   */
-  virtual void fireParameterChanged(const ParameterList& parameters)
-  {
-    AbstractParameterAliasable::fireParameterChanged(parameters);
-    
-    if (parameters.hasParameter(getNamespace()+"rate"))
+    /**
+     * @brief Tells the model that a parameter value has changed.
+     *
+     * This updates the matrices consequently.
+     */
+    virtual void fireParameterChanged(const ParameterList& parameters)
     {
-      rate_=parameters.getParameterValue(getNamespace()+"rate");
+      AbstractParameterAliasable::fireParameterChanged(parameters);
+    
+      if (parameters.hasParameter(getNamespace()+"rate"))
+      {
+        rate_=parameters.getParameterValue(getNamespace()+"rate");
       
-      if (parameters.size()!=1)
-        updateMatrices();
+        if (parameters.size()!=1)
+          updateMatrices();
+      }
+      else
+        updateMatrices();      
+    }
+
+    /**
+     * @brief add a "rate" parameter to the model, that handles the
+     * overall rate of the process.
+     *
+     */
+    void addRateParameter();
+
+  protected:
+    /**
+     * @brief Diagonalize the \f$Q\f$ matrix, and fill the eigenValues_, iEigenValues_, 
+     * leftEigenVectors_ and rightEigenVectors_ matrices.
+     *
+     * The generator_ matrix and freq_ vector must be initialized.
+     *
+     * Eigen values and vectors are computed from the generator and
+     * assigned to the eigenValues_ for the real part, iEigenValues_ for
+     * the imaginary part, rightEigenVectors_ and leftEigenVectors_
+     * variables. isDiagonalizable_ checks if the generator_ is
+     * diagonalizable in R.
+     *
+     * The optional rate parameter is not taken into account in this
+     * method to prevent unnecessary computation.
+     *
+     * !! Here there is no normalization of the generator.
+     * 
+     */
+    virtual void updateMatrices();
+
+    /*
+     * @brief : To update the eq freq
+     *
+     */
+    
+    Vdouble& getFrequencies_() {
+      return freq_;
     }
-    else
-      updateMatrices();      
-  }
-
-  /**
-   * @brief add a "rate" parameter to the model, that handles the
-   * overall rate of the process.
-   *
-   */
-  void addRateParameter();
-
-protected:
-  /**
-   * @brief Diagonalize the \f$Q\f$ matrix, and fill the eigenValues_, iEigenValues_, 
-   * leftEigenVectors_ and rightEigenVectors_ matrices.
-   *
-   * The generator_ matrix and freq_ vector must be initialized.
-   *
-   * Eigen values and vectors are computed from the generator and
-   * assigned to the eigenValues_ for the real part, iEigenValues_ for
-   * the imaginary part, rightEigenVectors_ and leftEigenVectors_
-   * variables. isDiagonalizable_ checks if the generator_ is
-   * diagonalizable in R.
-   *
-   * The optional rate parameter is not taken into account in this
-   * method to prevent unnecessary computation.
-   */
-  virtual void updateMatrices();
-
-public:
-
-  /**
-   * @brief sets if model is scalable, ie scale can be changed.
-   * Default : true, set to false to avoid normalization for example.
-   *
-   */
+
+  public:
+
+    /**
+     * @brief sets if model is scalable, ie scale can be changed.
+     * Default : true, set to false to avoid normalization for example.
+     *
+     */
   
-  void setScalable(bool scalable)
-  {
-    isScalable_=scalable;
-  }
+    void setScalable(bool scalable)
+    {
+      isScalable_=scalable;
+    }
   
-  /**
-   * @brief returns  if model is scalable
-   *
-   */
+    /**
+     * @brief returns  if model is scalable
+     *
+     */
 
-  virtual bool isScalable() const
-  {
-    return isScalable_;
-  }
+    virtual bool isScalable() const
+    {
+      return isScalable_;
+    }
 
-  /**
-   * @brief return scale
-   *
-   */
+    /**
+     * @brief return scale
+     *
+     */
   
-  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);
-
-  /**
-   * @brief normalize the generator
-   *
-   */
-
-  virtual void normalize();
+    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);
+
+    /**
+     * @brief normalize the generator
+     *
+     */
+
+    void normalize();
+
+    /**
+     * @brief set the diagonal of the generator such that sum on each
+     * line equals 0.
+     *
+     */
   
-  /**
-   * @brief The rate of the substitution process.
-   *
-   */
-  virtual double getRate() const;
+    void setDiagonal();
 
-  virtual void setRate(double rate);
+    /**
+     * @brief The rate of the substitution process.
+     *
+     */
+    virtual double getRate() const;
 
-  friend class AbstractBiblioSubstitutionModel;
+    virtual void setRate(double rate);
 
-};
+  };
 
 
 /**
@@ -421,48 +452,50 @@ public:
  * characters in the alphabet. Consider using the
  * MarkovModulatedSubstitutionModel for more complexe cases.
  */
-class AbstractReversibleSubstitutionModel :
-  public AbstractSubstitutionModel,
-  public virtual ReversibleSubstitutionModel
-{
-public:
-  AbstractReversibleSubstitutionModel(const Alphabet* alpha, StateMap* stateMap, const std::string& prefix) :
-    AbstractParameterAliasable(prefix),
-    AbstractSubstitutionModel(alpha, stateMap, prefix)
+  class AbstractReversibleSubstitutionModel :
+    public AbstractSubstitutionModel,
+    public virtual ReversibleSubstitutionModel
   {
-    isDiagonalizable_ = true;
-    isNonSingular_    = true;
-  }
-
-  virtual ~AbstractReversibleSubstitutionModel() {}
-
-  virtual AbstractReversibleSubstitutionModel* clone() const = 0;
-
-protected:
-
-  /**
-   * @brief Compute and diagonalize the \f$Q\f$ matrix, and fill the eigenValues_,
-   * leftEigenVectors_ and rightEigenVectors_ matrices.
-   *
-   * The exchangeability_ matrix and freq_ vector must be initialized.
-   * This function computes the generator_ matrix with the formula
-   * \f[
-   * Q = S \times \pi
-   * \f]
-   * where \f$Q\f$ is the generator matrix, \f$S\f$ is the exchangeability matrix and
-   * \f$Pi\f$ the diagonal matrix with frequencies.
-   *
-   * The generator is then scaled so that
-   * \f[
-   * \sum_i Q_{i,i} \times \pi_i = -1
-   * \f]
-   * (\f$\pi_i\f$ are the equilibrium frequencies).
-   *
-   * Eigen values and vectors are computed from the scaled generator and assigned to the
-   * eigenValues_, rightEigenVectors_ and leftEigenVectors_ variables.
-   */
-  virtual void updateMatrices();
-};
+  public:
+    AbstractReversibleSubstitutionModel(const Alphabet* alpha, const StateMap* stateMap, const std::string& prefix) :
+      AbstractParameterAliasable(prefix),
+      AbstractSubstitutionModel(alpha, stateMap, prefix)
+    {
+      isDiagonalizable_ = true;
+      isNonSingular_    = true;
+      computeFreq_ = false;
+    }
+
+    virtual ~AbstractReversibleSubstitutionModel() {}
+
+    virtual AbstractReversibleSubstitutionModel* clone() const = 0;
+
+  protected:
+
+    /**
+     * @brief Compute and diagonalize the \f$Q\f$ matrix, and fill the eigenValues_,
+     * leftEigenVectors_ and rightEigenVectors_ matrices.
+     *
+     * The exchangeability_ matrix and freq_ vector must be initialized.
+     * This function computes the generator_ matrix with the formula
+     * \f[
+     * Q = S \times \pi
+     * \f]
+     * where \f$Q\f$ is the generator matrix, \f$S\f$ is the exchangeability matrix and
+     * \f$Pi\f$ the diagonal matrix with frequencies.
+     *
+     * The generator is then scaled so that
+     * \f[
+     * \sum_i Q_{i,i} \times \pi_i = -1
+     * \f]
+     * (\f$\pi_i\f$ are the equilibrium frequencies).
+     *
+     * Eigen values and vectors are computed from the scaled generator and assigned to the
+     * eigenValues_, rightEigenVectors_ and leftEigenVectors_ variables.
+     */
+    virtual void updateMatrices();
+
+  };
 
 } //end of namespace bpp.
 
diff --git a/src/Bpp/Phyl/Model/AbstractWordSubstitutionModel.cpp b/src/Bpp/Phyl/Model/AbstractWordSubstitutionModel.cpp
index 4b96962..0514bb6 100644
--- a/src/Bpp/Phyl/Model/AbstractWordSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/AbstractWordSubstitutionModel.cpp
@@ -72,7 +72,6 @@ AbstractWordSubstitutionModel::AbstractWordSubstitutionModel(
   VnestedPrefix_(),
   Vrate_        (modelList.size())
 {
-  enableEigenDecomposition(false);
   size_t i, j;
   size_t n = modelList.size();
 
@@ -137,7 +136,6 @@ AbstractWordSubstitutionModel::AbstractWordSubstitutionModel(
   VnestedPrefix_(),
   Vrate_        (0)
 {
-  enableEigenDecomposition(false);
 }
 
 AbstractWordSubstitutionModel::AbstractWordSubstitutionModel(
@@ -153,7 +151,6 @@ AbstractWordSubstitutionModel::AbstractWordSubstitutionModel(
 {
   stateMap_=std::unique_ptr<StateMap>(new CanonicalStateMap(getAlphabet(), false));
 
-  enableEigenDecomposition(false);
   size_t i;
 
   string t = "";
@@ -280,8 +277,6 @@ void AbstractWordSubstitutionModel::updateMatrices()
     }
 
   size_t nbmod = VSubMod_.size();
-  size_t salph = getNumberOfStates();
-  size_t nbStop = 0;
   vector<bool> vnull; // vector of the indices of lines with only zeros
 
   // Generator
@@ -307,269 +302,52 @@ void AbstractWordSubstitutionModel::updateMatrices()
 
   // sets diagonal terms
 
-  double x;
-
-  for (i = 0; i < salph; i++)
-  {
-    x = 0;
-    for (j = 0; j < salph; j++)
-    {
-      if (j != i)
-        x += generator_(i, j);
-    }
-    generator_(i, i) = -x;
-  }
+  setDiagonal();
 
-  // at that point generator_ and freq_ are done for models without
-  // enableEigenDecomposition
+  // at that point generator_ (and possibly freq_) are done for models
+  // without enableEigenDecomposition
 
   // Eigen values:
   
   if (enableEigenDecomposition())
   {
-    for (i = 0; i < salph; i++)
-    {
-      bool flag = true;
-      for (j = 0; j < salph; j++)
-      {
-        if ((i != j) && abs(generator_(i, j)) > NumConstants::TINY())
-        {
-          flag = false;
-          break;
-        }
-      }
-      if (flag)
-        nbStop++;
-      vnull.push_back(flag);
-    }
-
-    if (nbStop != 0)
-    {
-      size_t gi = 0, gj = 0;
-
-      gk.resize(salph - nbStop, salph - nbStop);
-      for (i = 0; i < salph; i++)
-      {
-        if (!vnull[i])
-        {
-          gj = 0;
-          for (j = 0; j < salph; j++)
-          {
-            if (!vnull[j])
-            {
-              gk(i - gi, j - gj) = generator_(i, j);
-            }
-            else
-              gj++;
-          }
-        }
-        else
-          gi++;
-      }
-
-      EigenValue<double> ev(gk);
-      eigenValues_ = ev.getRealEigenValues();
-      iEigenValues_ = ev.getImagEigenValues();
-
-      for (i = 0; i < nbStop; i++)
-      {
-        eigenValues_.push_back(0);
-        iEigenValues_.push_back(0);
-      }
-
-      RowMatrix<double> rev = ev.getV();
-      rightEigenVectors_.resize(salph, salph);
-      gi = 0;
-      for (i = 0; i < salph; i++)
-      {
-        if (vnull[i])
-        {
-          gi++;
-          for (j = 0; j < salph; j++)
-          {
-            rightEigenVectors_(i, j) = 0;
-          }
-
-          rightEigenVectors_(i, salph - nbStop + gi - 1) = 1;
-        }
-        else
-        {
-          for (j = 0; j < salph - nbStop; j++)
-          {
-            rightEigenVectors_(i, j) = rev(i - gi, j);
-          }
-
-          for (j = salph - nbStop; j < salph; j++)
-          {
-            rightEigenVectors_(i, j) = 0;
-          }
-        }
-      }
-    }
-    else
-    {
-      EigenValue<double> ev(generator_);
-      eigenValues_ = ev.getRealEigenValues();
-      iEigenValues_ = ev.getImagEigenValues();
-      rightEigenVectors_ = ev.getV();
-      nbStop = 0;
-    }
-
-    try
-    {
-      MatrixTools::inv(rightEigenVectors_, leftEigenVectors_);
-
-      // is it diagonalizable ?
-
-      isDiagonalizable_ = true;
-      for (i = 0; i < size_ && isDiagonalizable_; i++)
-      {
-        if (abs(iEigenValues_[i]) > NumConstants::SMALL())
-          isDiagonalizable_ = false;
-      }
-
-      // is it singular?
-
-      // looking for the 0 eigenvector for which the non-stop right
-      // eigen vector elements are equal.
-      //
-
-      size_t nulleigen = 0;
-      double val;
-
-      isNonSingular_ = false;
-      while (nulleigen < salph - nbStop)
-      {
-        if ((abs(eigenValues_[nulleigen]) < NumConstants::SMALL()) && (abs(iEigenValues_[nulleigen]) < NumConstants::SMALL()))
-        {
-          i = 0;
-          while (vnull[i])
-            i++;
-          
-          val = rightEigenVectors_(i, nulleigen);
-          i++;
-          while (i < salph)
-          {
-            if (!vnull[i])
-            {
-              if (abs(rightEigenVectors_(i, nulleigen) - val) > NumConstants::SMALL())
-                break;
-            }
-            i++;
-          }
-          
-          if (i < salph)
-            nulleigen++;
-          else
-          {
-            isNonSingular_ = true;
-            break;
-          }
-        }
-        else
-          nulleigen++;
-      }
-      
-      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;
-      }
-      
-      else
-      {
-        ApplicationTools::displayMessage("Unable to find eigenvector for eigenvalue 1. Taylor series used instead.");
-        isDiagonalizable_ = false;
-      }
-    }
-    
-    
-    // if rightEigenVectors_ is singular
-    catch (ZeroDivisionException& e)
-    {
-      ApplicationTools::displayMessage("Singularity during  diagonalization. Taylor series used instead.");
-      isNonSingular_ = false;
-      isDiagonalizable_ = false;
-    }
-
-    if (!isNonSingular_)
-    {
-      double min = generator_(0, 0);
-      for (i = 1; i < salph; i++)
-      {
-        if (min > generator_(i, i))
-          min = generator_(i, i);
-      }
-
-      setScale(-1 / min);
-
-      if (vPowGen_.size() == 0)
-        vPowGen_.resize(30);
-
-      MatrixTools::getId(salph, tmpMat_);    // to compute the equilibrium frequency  (Q+Id)^256
-      MatrixTools::add(tmpMat_, generator_);
-      MatrixTools::pow(tmpMat_, 256, vPowGen_[0]);
-
-      for (i = 0; i < salph; i++)
-      {
-        freq_[i] = vPowGen_[0](0, i);
-      }
-
-      MatrixTools::getId(salph, vPowGen_[0]);
-    }
-
-    // normalization
-    normalize();
-
-    
-    if (!isNonSingular_)
-      MatrixTools::Taylor(generator_, 30, vPowGen_);
+    AbstractSubstitutionModel::updateMatrices();
   }
   else  // compute freq_ if no eigenDecomposition
   {
-    for (j = 0; j < size_; j++)
-      freq_[j] = 1;
-  
-    m = 1;
-    for (k = nbmod; k > 0; k--)
+    if (computeFrequencies())
     {
-      SubstitutionModel* pSM = VSubMod_[k - 1];
-      for (j = 0; j < vsize[k - 1]; j++)
+      size_t salph = getNumberOfStates();
+      for (auto& fr : freq_)
+        fr = 1;
+  
+      m = 1;
+      for (k = nbmod; k > 0; k--)
       {
-        n = 0;
-        while (n < salph)
-        { // loop on prefix
-          for (l = 0; l < m; l++)
-          { // loop on suffix
-            freq_[n + j * m + l] *=  pSM->freq(j);
+        SubstitutionModel* pSM = VSubMod_[k - 1];
+        for (j = 0; j < vsize[k - 1]; j++)
+        {
+          n = 0;
+          while (n < salph)
+          { // loop on prefix
+            for (l = 0; l < m; l++)
+            { // loop on suffix
+              freq_[n + j * m + l] *=  pSM->freq(j);
+            }
+            n += m * vsize[k - 1];
           }
-          n += m * vsize[k - 1];
         }
+        m *= vsize[k - 1];
       }
-      m *= vsize[k - 1];
+      // normalization
+      normalize();
     }
-
-    // normalization
-    normalize();
   }
-  
 
   // compute the exchangeability_
-
   for (i = 0; i < size_; i++)
     for (j = 0; j < size_; j++)
       exchangeability_(i, j) = generator_(i, j) / freq_[j];
-
 }
 
 
diff --git a/src/Bpp/Phyl/Model/AbstractWrappedModel.h b/src/Bpp/Phyl/Model/AbstractWrappedModel.h
new file mode 100644
index 0000000..792f8bf
--- /dev/null
+++ b/src/Bpp/Phyl/Model/AbstractWrappedModel.h
@@ -0,0 +1,289 @@
+//
+// File: AbtractWrappedModel.h
+// Created by: Laurent Guéguen
+// Created on: mardi 26 septembre 2017, à 16h 18
+//
+
+/*
+  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 _ABSTRACT_WRAPPED_MODEL_H_
+#define _ABSTRACT_WRAPPED_MODEL_H_
+
+#include "WrappedModel.h"
+
+namespace bpp
+{
+/**
+ * @brief Abstract class of Wrapping model class, where all methods
+ * are redirected from getModel().
+ * 
+ *
+ *
+ */
+
+  class AbstractWrappedModel :
+    public virtual WrappedModel
+  {
+  public:
+    AbstractWrappedModel() {}
+    virtual ~AbstractWrappedModel() {}
+    
+  public:
+    /*
+     *@ brief Methods to supersede TransitionModel methods.
+     *
+     * @{
+     */
+
+    const std::vector<int>& getAlphabetStates() const { return getModel().getAlphabetStates(); }
+
+    const StateMap& getStateMap() const { return getModel().getStateMap(); }
+
+    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); }
+
+
+    const Alphabet* getAlphabet() const { return getModel().getAlphabet(); }
+
+    size_t getNumberOfStates() const { return getModel().getNumberOfStates(); }
+
+    const FrequenciesSet* getFrequenciesSet() const { return getModel().getFrequenciesSet();}
+    
+    /*
+     * @}
+     */
+
+    virtual std::string getName() const
+    {
+      return getModel().getName();
+    }
+
+    /*
+     * @}
+     *
+     */
+  };
+  
+  class AbstractTotallyWrappedModel :
+    public virtual AbstractWrappedModel
+  {
+  public:
+    AbstractTotallyWrappedModel() {}
+    virtual ~AbstractTotallyWrappedModel() {}
+    
+  public:
+    /*
+     *@ brief Methods to supersede TransitionModel methods.
+     *
+     * @{
+     */
+
+    double freq(size_t i) const { return getModel().freq(i); }
+
+    double Pij_t    (size_t i, size_t j, double t) const { return getModel().Pij_t(i, j, t); }
+    double dPij_dt  (size_t i, size_t j, double t) const { return getModel().dPij_dt (i, j, t); }
+    double d2Pij_dt2(size_t i, size_t j, double t) const { return getModel().d2Pij_dt2(i, j, t); }
+
+    const Vdouble& getFrequencies() const { return getModel().getFrequencies(); }
+
+    const Matrix<double>& getPij_t(double t) const { return getModel().getPij_t(t); }
+
+    const Matrix<double>& getdPij_dt(double t) const { return getModel().getdPij_dt(t); }
+
+    const Matrix<double>& getd2Pij_dt2(double t) const { return getModel().getd2Pij_dt2(t); }
+
+    double getInitValue(size_t i, int state) const throw (IndexOutOfBoundsException, BadIntException)
+    {
+      return getModel().getInitValue(i,state);
+    }
+    
+    double getRate() const
+    {
+      return getModel().getRate();
+    }
+
+    void setRate(double rate)
+    {
+      return getModel().setRate(rate);
+    }
+
+    void setFreqFromData(const SequenceContainer& data, double pseudoCount = 0)
+    {
+      getModel().setFreqFromData(data, pseudoCount);
+    }
+    
+    void setFreq(std::map<int, double>& frequencies)
+    {
+      getModel().setFreq(frequencies);
+    }
+
+    bool computeFrequencies() const
+    {
+      return getModel().computeFrequencies();
+    }
+
+    /**
+     * @return Set if equilibrium frequencies should be computed from
+     * the generator
+     */
+    
+    void computeFrequencies(bool yn)
+    {
+      getModel().computeFrequencies(yn);
+    }
+
+    /*
+     * @}
+     *
+     */
+
+  protected:
+
+    Vdouble& getFrequencies_()
+    {
+      return getModel().getFrequencies_();
+    }
+
+  };
+  
+    
+  class AbstractWrappedSubstitutionModel :
+    public virtual AbstractWrappedModel,
+    public virtual WrappedSubstitutionModel
+  {
+  public:
+    AbstractWrappedSubstitutionModel() {}
+    
+    virtual ~AbstractWrappedSubstitutionModel() {}
+    
+    const TransitionModel& getModel() const
+    {
+      return getSubstitutionModel();
+    }
+    
+
+  protected:
+    TransitionModel& getModel()
+    {
+      return getSubstitutionModel();
+    }
+
+  };
+
+  class AbstractTotallyWrappedSubstitutionModel :
+    public virtual AbstractTotallyWrappedModel,
+    public virtual AbstractWrappedSubstitutionModel
+  {
+  public:
+    AbstractTotallyWrappedSubstitutionModel() {}
+    
+    virtual ~AbstractTotallyWrappedSubstitutionModel() {}
+    
+    /*
+     *@ brief Methods to supersede SubstitutionModel methods.
+     *
+     * @{
+     */
+
+    double Qij(size_t i, size_t j) const { return getSubstitutionModel().Qij(i, j); }
+
+    const Matrix<double>& getGenerator() const { return getSubstitutionModel().getGenerator(); }
+
+    const Matrix<double>& getExchangeabilityMatrix() const { return getSubstitutionModel().getExchangeabilityMatrix(); }
+
+    double Sij(size_t i, size_t j) const { return getSubstitutionModel().Sij(i, j); }
+
+    void enableEigenDecomposition(bool yn) { getSubstitutionModel().enableEigenDecomposition(yn); }
+
+    bool enableEigenDecomposition() { return getSubstitutionModel().enableEigenDecomposition(); }
+
+    bool isDiagonalizable() const { return getSubstitutionModel().isDiagonalizable(); }
+
+    bool isNonSingular() const { return getSubstitutionModel().isNonSingular(); }
+
+    const Vdouble& getEigenValues() const { return getSubstitutionModel().getEigenValues(); }
+
+    const Vdouble& getIEigenValues() const { return getSubstitutionModel().getIEigenValues(); }
+
+    const Matrix<double>& getRowLeftEigenVectors() const { return getSubstitutionModel().getRowLeftEigenVectors(); }
+
+    const Matrix<double>& getColumnRightEigenVectors() const { return getSubstitutionModel().getColumnRightEigenVectors(); }
+
+
+    /*
+     * @}
+     *
+     */
+
+    bool isScalable() const 
+    {
+      return getSubstitutionModel().isScalable();
+    }
+
+    void setScalable(bool scalable)
+    {
+      getSubstitutionModel().setScalable(scalable);
+    }
+
+    void normalize()
+    {
+      getSubstitutionModel().normalize();
+    }
+
+    void setDiagonal()
+    {
+      getSubstitutionModel().setDiagonal();
+    }
+
+    double getScale() const { return getSubstitutionModel().getScale(); }
+
+    void setScale(double scale) { getSubstitutionModel().setScale(scale); }
+
+    /*
+     * @}
+     */
+  };
+
+
+  
+} // end of namespace bpp.
+
+
+#endif  // _ABSTRACT_WRAPPED_MODEL_SUBSTITUTIONMODEL_H_
+
diff --git a/src/Bpp/Phyl/Model/Codon/CodonSubstitutionModel.h b/src/Bpp/Phyl/Model/AnonymousSubstitutionModel.h
similarity index 54%
copy from src/Bpp/Phyl/Model/Codon/CodonSubstitutionModel.h
copy to src/Bpp/Phyl/Model/AnonymousSubstitutionModel.h
index d7a6648..905669d 100644
--- a/src/Bpp/Phyl/Model/Codon/CodonSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/AnonymousSubstitutionModel.h
@@ -1,11 +1,11 @@
 //
-// File: CodonSubstitutionModel.h
+// File: AnonymousSubstitutionModel.h
 // Created by: Laurent Gueguen
-// Created on: Tue Dec 24 11:03:53 2003
+// Created on: samedi 17 juin 2017, � 07h 55
 //
 
 /*
-  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.
@@ -37,62 +37,54 @@
   knowledge of the CeCILL license and that you accept its terms.
 */
 
-#ifndef _CODONSUBSTITUTIONMODEL_H_
-#define _CODONSUBSTITUTIONMODEL_H_
+#ifndef _ANONYMOUS_SUBSTITUTIONMODEL_H_
+#define _ANONYMOUS_SUBSTITUTIONMODEL_H_
 
-//From bpp-seq:
-#include <Bpp/Seq/GeneticCode/GeneticCode.h>
-
-#include "../WordSubstitutionModel.h"
+#include "AbstractSubstitutionModel.h"
 
 namespace bpp
 {
-  /**
-   * @brief Abstract class for codon models
-   * @author Laurent Guéguen
+
+  /*
+   * @brief Substitution Model with no name nor predefined generator
+   * sets, and provides a non-const setGenerator() function to fill
+   * the generator directly.
+   *
+   * Directly inherits from AbstractSubstitutionModel, hence uses the
+   * computation methods developped in it.
    *
-   * This class aims at defining methods needed for inheriting codon.
    *
    */
-  class CodonSubstitutionModel:
-    public virtual SubstitutionModel
+
+  
+  class AnonymousSubstitutionModel :
+    public AbstractSubstitutionModel
   {
   public:
-    CodonSubstitutionModel() {}
-    virtual ~CodonSubstitutionModel() {}
-
-    virtual CodonSubstitutionModel* clone() const = 0;
+    AnonymousSubstitutionModel(const Alphabet* alpha, const StateMap* stateMap):
+      AbstractParameterAliasable("Anonymous"),
+      AbstractSubstitutionModel(alpha, stateMap, "Anonymous")
+    {}
 
-  public:
+    virtual ~AnonymousSubstitutionModel() {}
 
-    virtual const GeneticCode* getGeneticCode() const = 0;
+    AnonymousSubstitutionModel* clone() const { return new AnonymousSubstitutionModel(*this); }
 
-    /**
-     * @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;
-  };
-  
   
-  /**
-   * @brief Abstract class for reversible codon models
-   * @author Julien Dutheil
-   */
-  class CodonReversibleSubstitutionModel:
-    public virtual CodonSubstitutionModel,
-    public virtual ReversibleSubstitutionModel 
-  {
   public:
-    CodonReversibleSubstitutionModel() {}
-    virtual ~CodonReversibleSubstitutionModel() {}
+    std::string getName() const { return "Anonymous"; }
+    
+    size_t getNumberOfStates() const { return getAlphabet()->getSize(); }
 
-    virtual CodonReversibleSubstitutionModel* clone() const = 0;
-  };
+    Matrix<double>& setGenerator() { return generator_; }
 
+    void updateMatrices()
+    {
+      AbstractSubstitutionModel::updateMatrices();
+    }
+    
+  };
 } // end of namespace bpp.
 
-#endif
+#endif  // _ANONYMOUS_SUBSTITUTIONMODEL_H_
 
diff --git a/src/Bpp/Phyl/Model/Codon/AbstractCodonFitnessSubstitutionModel.cpp b/src/Bpp/Phyl/Model/Codon/AbstractCodonAAFitnessSubstitutionModel.cpp
similarity index 64%
copy from src/Bpp/Phyl/Model/Codon/AbstractCodonFitnessSubstitutionModel.cpp
copy to src/Bpp/Phyl/Model/Codon/AbstractCodonAAFitnessSubstitutionModel.cpp
index 4c49591..d5b91b5 100644
--- a/src/Bpp/Phyl/Model/Codon/AbstractCodonFitnessSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/Codon/AbstractCodonAAFitnessSubstitutionModel.cpp
@@ -1,7 +1,7 @@
 //
-// File: AbstractCodonFitnessSubstitutionModel.cpp
-// Created by:  Fanny Pouyet
-// Created on: mars 2012
+// File: AbstractCodonAAFitnessSubstitutionModel.cpp
+// Created by: Laurent Guéguen
+// Created on: mercredi 8 novembre 2017, à 21h 10
 //
 
 /*
@@ -36,41 +36,46 @@
   knowledge of the CeCILL license and that you accept its terms.
 */
 
-# include "AbstractCodonFitnessSubstitutionModel.h"
+# include "AbstractCodonAAFitnessSubstitutionModel.h"
 using namespace bpp;
 using namespace std;
 /****************************************************************************************/
-AbstractCodonFitnessSubstitutionModel::AbstractCodonFitnessSubstitutionModel(FrequenciesSet* pfitset, const string& prefix):
-  CodonSubstitutionModel(), AbstractParameterAliasable(prefix), pfitset_(pfitset), fitName_("")
+AbstractCodonAAFitnessSubstitutionModel::AbstractCodonAAFitnessSubstitutionModel(FrequenciesSet* pfitset, const GeneticCode* pgencode, const string& prefix):
+  AbstractParameterAliasable(prefix), pfitset_(pfitset), pgencode_(pgencode), fitName_("")
 {
-  if (dynamic_cast<CodonFrequenciesSet*>(pfitset) == NULL)
-    throw Exception ("Bad type for fitness parameters"+ pfitset ->getName() );
+  if (pfitset_->getAlphabet()->getAlphabetType()!="Proteic")
+    throw Exception("AbstractCodonAAFitnessSubstitutionModel::AbstractCodonAAFitnessSubstitutionModel need Proteic Fitness.");
+  
   fitName_="fit_"+ pfitset_->getNamespace();
   pfitset_->setNamespace(prefix + fitName_);
-  addParameters_(pfitset_->getParameters() );
+  addParameters_(pfitset_->getParameters());
 }
 
-AbstractCodonFitnessSubstitutionModel::~AbstractCodonFitnessSubstitutionModel()
+AbstractCodonAAFitnessSubstitutionModel::~AbstractCodonAAFitnessSubstitutionModel()
 {
-  if (pfitset_) delete pfitset_;
 }
 
-void AbstractCodonFitnessSubstitutionModel::fireParameterChanged (const ParameterList& parameters)
+void AbstractCodonAAFitnessSubstitutionModel::fireParameterChanged (const ParameterList& parameters)
 {
   pfitset_->matchParametersValues(parameters);
 }
 
-void AbstractCodonFitnessSubstitutionModel::setFreq(map<int, double>& frequencies)
+void AbstractCodonAAFitnessSubstitutionModel::setFreq(map<int, double>& frequencies)
 {
   pfitset_->setFrequenciesFromAlphabetStatesFrequencies(frequencies);
   matchParametersValues(pfitset_->getParameters() );
 }
 
-double AbstractCodonFitnessSubstitutionModel::getCodonsMulRate(size_t i, size_t j) const
+double AbstractCodonAAFitnessSubstitutionModel::getCodonsMulRate(size_t i, size_t j) const
 {
   double mu;
-  double phi_j= pfitset_->getFrequencies() [j];
-  double phi_i= pfitset_->getFrequencies() [i];
+
+  int aai = pgencode_->translate(static_cast<int>(i));
+  int aaj = pgencode_->translate(static_cast<int>(j));
+
+  double phi_j= pfitset_->getFrequencies() [aai];
+  double phi_i= pfitset_->getFrequencies() [aaj];
+
   if (phi_i == phi_j) mu=1;
   else if (phi_i==0)
     mu=100;
diff --git a/src/Bpp/Phyl/Model/Codon/AbstractCodonFitnessSubstitutionModel.h b/src/Bpp/Phyl/Model/Codon/AbstractCodonAAFitnessSubstitutionModel.h
similarity index 59%
copy from src/Bpp/Phyl/Model/Codon/AbstractCodonFitnessSubstitutionModel.h
copy to src/Bpp/Phyl/Model/Codon/AbstractCodonAAFitnessSubstitutionModel.h
index 49aa385..e41a42b 100644
--- a/src/Bpp/Phyl/Model/Codon/AbstractCodonFitnessSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/Codon/AbstractCodonAAFitnessSubstitutionModel.h
@@ -1,7 +1,7 @@
 //
-// File: AbstractCodonFitnessSubstitutionModel.h
-// Created by:  Fanny Pouyet
-// Created on: mars 2012
+// File: AbstractCodonAAFitnessSubstitutionModel.h
+// Created by: Laurent Guéguen
+// Created on: mercredi 8 novembre 2017, à 21h 11
 //
 
 /*
@@ -36,68 +36,93 @@
   knowledge of the CeCILL license and that you accept its terms.
 */
 
-# ifndef _ABSTRACTCODONFITNESSSUBSTITUTIONMODEL_H_
-# define _ABSTRACTCODONFITNESSSUBSTITUTIONMODEL_H_
+# ifndef _ABSTRACTCODON_AA_FITNESSSUBSTITUTIONMODEL_H_
+# define _ABSTRACTCODON_AA_FITNESSSUBSTITUTIONMODEL_H_
 
 # include "CodonSubstitutionModel.h"
-#include "../FrequenciesSet/CodonFrequenciesSet.h"
+
+#include "../FrequenciesSet/ProteinFrequenciesSet.h"
+
 namespace bpp
 {
   /**
    * @brief Abstract class for modelling of ratios of substitution
    * rates between codons, whatever they are synonymous or not.
    *
-   * @author Fanny Pouyet, Laurent Guéguen
+   * @author Laurent Guéguen
    *
-   * The fitness of a codon is a value between 0 and 1 defining the
-   * relative advantage of a codon, compared to others. If a codon
-   * @f$i at f$ has a fitness @f$\phi_i at f$ and another one (@f$j at f$) has
-   * a fitness @f$\phi_j at f$, the substitution rate from codon @f$i at f$
-   * to codon @f$j at f$ is multiplied by
+   * The fitness of an amino acid is a value between 0 and 1 defining
+   * the relative advantage of an amino acid, compared to others. If
+   * an amino acid @f$i at f$ has a fitness @f$\phi_i at f$ and another one
+   * (@f$j at f$) has a fitness @f$\phi_j at f$, the substitution rate from
+   * codon @f$i at f$ to codon @f$j at f$ is multiplied by
    * \f[-\frac{\log(\frac{\phi_i}{\phi_j})}{1-\frac{\phi_i}{\phi_j}}\f]
    *
-   * The set of fitnesses is implemented through a Codon
+   * The set of fitnesses is implemented through a Protein
    * FrequenciesSet object. The parameters are named \c
    * "fit_NameOfTheParameterInTheFrequenciesSet".
    */
 
 
-  class AbstractCodonFitnessSubstitutionModel :
-    public virtual CodonSubstitutionModel,
+  class AbstractCodonAAFitnessSubstitutionModel :
+    public virtual CoreCodonSubstitutionModel,
     public virtual AbstractParameterAliasable
   {
   private:
-    FrequenciesSet* pfitset_;
+    std::unique_ptr<FrequenciesSet> pfitset_;
+
+    const GeneticCode* pgencode_;
+  
     std::string fitName_;
-  public:
-    AbstractCodonFitnessSubstitutionModel(FrequenciesSet* pfitset, const std::string& prefix);
-    AbstractCodonFitnessSubstitutionModel(const AbstractCodonFitnessSubstitutionModel& model):
+
+public:
+    AbstractCodonAAFitnessSubstitutionModel(
+      FrequenciesSet* pfitset,
+      const GeneticCode* pgencode,
+      const std::string& prefix);
+    
+    AbstractCodonAAFitnessSubstitutionModel(const AbstractCodonAAFitnessSubstitutionModel& model):
       AbstractParameterAliasable(model),
       pfitset_(model.pfitset_->clone()),
+      pgencode_(model.pgencode_),
       fitName_(model.fitName_)
     {}
 
-    AbstractCodonFitnessSubstitutionModel& operator=(const AbstractCodonFitnessSubstitutionModel& model){
+    AbstractCodonAAFitnessSubstitutionModel& operator=(const AbstractCodonAAFitnessSubstitutionModel& model){
       AbstractParameterAliasable::operator=(model);
-      if (pfitset_) delete pfitset_;
-      pfitset_ = model.pfitset_->clone();
+      pfitset_.reset(model.pfitset_->clone());
+      pgencode_ = model.pgencode_;
       fitName_ = model.fitName_ ;
       return *this;
     }
 
-    virtual ~AbstractCodonFitnessSubstitutionModel();
+    AbstractCodonAAFitnessSubstitutionModel* clone() const
+    {
+      return new AbstractCodonAAFitnessSubstitutionModel(*this);
+    }
+
+    virtual ~AbstractCodonAAFitnessSubstitutionModel();
 
   public:
     void fireParameterChanged (const ParameterList& parameters);
+
     void setFreq(std::map<int, double>& frequencies);
-    const FrequenciesSet& getFreq() const { return *pfitset_; }
+
+    const FrequenciesSet& getFreq() const { return *pfitset_.get(); }
+
     void setNamespace (const std::string& prefix){
+      AbstractParameterAliasable::setNamespace(prefix);
       pfitset_->setNamespace(prefix + fitName_);
     }
 
     double getCodonsMulRate(size_t i, size_t j) const;
 
-    const FrequenciesSet* getFitness() const { return pfitset_;}
+    const FrequenciesSet& getAAFitness() const { return *pfitset_.get();}
+
+    const FrequenciesSet* getFrequenciesSet() const 
+    {
+      return 0;
+    }
 
   };
 } // end of namespace bpp
diff --git a/src/Bpp/Phyl/Model/Codon/AbstractCodonDistanceSubstitutionModel.cpp b/src/Bpp/Phyl/Model/Codon/AbstractCodonAARateSubstitutionModel.cpp
similarity index 70%
copy from src/Bpp/Phyl/Model/Codon/AbstractCodonDistanceSubstitutionModel.cpp
copy to src/Bpp/Phyl/Model/Codon/AbstractCodonAARateSubstitutionModel.cpp
index 4dbdb5e..911d78f 100644
--- a/src/Bpp/Phyl/Model/Codon/AbstractCodonDistanceSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/Codon/AbstractCodonAARateSubstitutionModel.cpp
@@ -1,7 +1,7 @@
 //
-// File: AbstractCodonDistanceSubstitutionModel.cpp
+// File: AbstractCodonAARateSubstitutionModel.cpp
 // Created by:  Laurent Gueguen
-// Created on: Feb 2009
+// Created on: lundi 30 octobre 2017, à 06h 07
 //
 
 /*
@@ -36,7 +36,7 @@
    knowledge of the CeCILL license and that you accept its terms.
  */
 
-#include "AbstractCodonDistanceSubstitutionModel.h"
+#include "AbstractCodonAARateSubstitutionModel.h"
 #include <Bpp/Numeric/NumConstants.h>
 
 using namespace bpp;
@@ -45,41 +45,42 @@ using namespace std;
 
 /******************************************************************************/
 
-AbstractCodonDistanceSubstitutionModel::AbstractCodonDistanceSubstitutionModel(
-  const AlphabetIndex2* pdist,
+AbstractCodonAARateSubstitutionModel::AbstractCodonAARateSubstitutionModel(
+  std::shared_ptr<ProteinSubstitutionModel> pmodel,
+  const GeneticCode* pgencode,
   const std::string& prefix,
   bool paramSynRate) :
-  CodonSubstitutionModel(),
   AbstractParameterAliasable(prefix),
-  pdistance_(pdist),
-  alpha_(10000),
-  beta_(1),
+  pAAmodel_(pmodel),
+  pgencode_(pgencode),
+  beta_(19),
   gamma_(1)
 {
-  if (pdistance_)
-    addParameter_(new Parameter(prefix + "alpha", 10000, &Parameter::R_PLUS_STAR));
-
   if (paramSynRate)
     addParameter_(new Parameter(prefix + "gamma", 1, new IntervalConstraint(NumConstants::SMALL(), 999, true, true), true));
 
   addParameter_(new Parameter(prefix + "beta", 1, new IntervalConstraint(NumConstants::SMALL(), 999, true, true), true));
+
+  pAAmodel_->enableEigenDecomposition(false);
+  
+  pAAmodel_->setNamespace(prefix + pAAmodel_->getNamespace());
+  addParameters_(pAAmodel_->getParameters());
 }
 
-void AbstractCodonDistanceSubstitutionModel::fireParameterChanged(const ParameterList& parameters)
+void AbstractCodonAARateSubstitutionModel::fireParameterChanged(const ParameterList& parameters)
 {
-  if (pdistance_)
-    alpha_ = getParameterValue("alpha");
+  pAAmodel_->matchParametersValues(parameters);
 
   if (hasParameter("gamma"))
     gamma_ = getParameterValue("gamma");
+
   beta_ = getParameterValue("beta");
 }
 
-double AbstractCodonDistanceSubstitutionModel::getCodonsMulRate(size_t i, size_t j) const
+double AbstractCodonAARateSubstitutionModel::getCodonsMulRate(size_t i, size_t j) const
 {
-  return getGeneticCode()->areSynonymous(static_cast<int>(i), static_cast<int>(j)) ? gamma_ :
-         beta_ * (pdistance_ ? exp(-pdistance_->getIndex(
-                 getGeneticCode()->translate(static_cast<int>(i)),
-                 getGeneticCode()->translate(static_cast<int>(j))) / alpha_) : 1);
+  return pgencode_->areSynonymous(static_cast<int>(i), static_cast<int>(j)) ? gamma_ :
+    beta_ * pAAmodel_->Qij(pgencode_->translate(static_cast<int>(i)),
+                           pgencode_->translate(static_cast<int>(j)));
 }
 
diff --git a/src/Bpp/Phyl/Model/Codon/AbstractCodonAARateSubstitutionModel.h b/src/Bpp/Phyl/Model/Codon/AbstractCodonAARateSubstitutionModel.h
new file mode 100644
index 0000000..b0a3742
--- /dev/null
+++ b/src/Bpp/Phyl/Model/Codon/AbstractCodonAARateSubstitutionModel.h
@@ -0,0 +1,162 @@
+//
+// File: AbstractCodonAARateSubstitutionModel.h
+// Created by: Laurent Gueguen
+// Created on: jeudi 15 septembre 2011, à 21h 11
+//
+
+/*
+  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 _ABSTRACTCODON_AARATE_SUBSTITUTIONMODEL_H_
+#define _ABSTRACTCODON_AARATE_SUBSTITUTIONMODEL_H_
+
+#include "CodonSubstitutionModel.h"
+#include "../Protein/ProteinSubstitutionModel.h"
+
+// From bpp-seq:
+#include <Bpp/Seq/GeneticCode/GeneticCode.h>
+#include <Bpp/Seq/AlphabetIndex/AlphabetIndex2.h>
+
+namespace bpp
+{
+/**
+ * @brief Abstract class for modelling of non-synonymous and
+ *  synonymous substitution rates in codon models, given an amino acid
+ *  rate matrix (from a shared_ptr model).
+ *
+ * @author Laurent Guéguen
+ *
+ * From the generator @f$g at f$ between amino-acids, the non-synonymous
+ *  rate is multiplied with, if the coded amino-acids are @f$x at f$ and
+ *  @f$y at f$, @f$\beta*g(x,y)@f$ with positive parameter \c "beta".
+ *
+ * If paramSynRate is true, the synonymous substitution rate is
+ *  multiplied with @f$\gamma at f$ (with optional positive parameter \c
+ *  "gamma"), else it is multiplied with 1.
+ *
+ *
+ */
+
+  class AbstractCodonAARateSubstitutionModel :
+    public virtual CoreCodonSubstitutionModel,
+    public virtual AbstractParameterAliasable
+  {
+  private:
+    std::shared_ptr<ProteinSubstitutionModel> pAAmodel_;
+
+    const GeneticCode* pgencode_;
+    
+    double beta_;
+
+    double gamma_;
+  public:
+    /**
+     * @brief Build a new AbstractCodonAARateSubstitutionModel object from
+     *  a pointer to NucleotideSubstitutionModel.
+     *
+     * @param pmodel shared_ptr to an amino_acid generator
+     * @param pgencode the genetic code
+     * @param prefix the Namespace
+     * @param paramSynRate is true iff synonymous rate is parameterised
+     *       (default=false).
+     */
+    
+    AbstractCodonAARateSubstitutionModel(
+      std::shared_ptr<ProteinSubstitutionModel> pmodel,
+      const GeneticCode* pgencode,
+      const std::string& prefix,
+      bool paramSynRate = false);
+
+    AbstractCodonAARateSubstitutionModel(const AbstractCodonAARateSubstitutionModel& model) :
+      AbstractParameterAliasable(model),
+      pAAmodel_(model.pAAmodel_),
+      pgencode_(model.pgencode_),
+      beta_(model.beta_),
+      gamma_(model.gamma_)
+    {}
+
+    AbstractCodonAARateSubstitutionModel& operator=(
+      const AbstractCodonAARateSubstitutionModel& model)
+    {
+      AbstractParameterAliasable::operator=(model);
+      pAAmodel_ = model.pAAmodel_;
+      pgencode_ = model.pgencode_;
+      beta_ = model.beta_;
+      gamma_ = model.gamma_;
+      return *this;
+    }
+
+    AbstractCodonAARateSubstitutionModel* clone() const
+    {
+      return new AbstractCodonAARateSubstitutionModel(*this);
+    }
+
+    virtual ~AbstractCodonAARateSubstitutionModel() {}
+
+  public:
+    void fireParameterChanged(const ParameterList& parameters);
+
+    double getCodonsMulRate(size_t i, size_t j) const;
+
+    void setNamespace(const std::string& prefix)
+    {
+      AbstractParameterAliasable::setNamespace(prefix);
+      pAAmodel_->setNamespace(prefix + pAAmodel_->getNamespace());
+    }
+
+    /*
+     * @brief links to a new AA model
+     *
+     */
+    
+    void setAAModel(std::shared_ptr<ProteinSubstitutionModel> model)
+    {
+      pAAmodel_=model;
+    }
+
+    const std::shared_ptr<ProteinSubstitutionModel>  getAAModel() const
+    {
+      return pAAmodel_;
+    }
+
+    const FrequenciesSet* getFrequenciesSet() const 
+    {
+      return 0;
+    }
+
+  };
+
+} // end of namespace bpp.
+
+#endif // _ABSTRACTCODON_AARATE_SUBSTITUTIONMODEL_H_
+
diff --git a/src/Bpp/Phyl/Model/Codon/CodonRateSubstitutionModel.cpp b/src/Bpp/Phyl/Model/Codon/AbstractCodonBGCSubstitutionModel.cpp
similarity index 57%
rename from src/Bpp/Phyl/Model/Codon/CodonRateSubstitutionModel.cpp
rename to src/Bpp/Phyl/Model/Codon/AbstractCodonBGCSubstitutionModel.cpp
index 894251b..e230021 100644
--- a/src/Bpp/Phyl/Model/Codon/CodonRateSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/Codon/AbstractCodonBGCSubstitutionModel.cpp
@@ -1,5 +1,5 @@
 //
-// File: CodonSubstitutionModel.cpp
+// File: AbstractCodonBGCSubstitutionModel.cpp
 // Created by:  Laurent Gueguen
 // Created on: Feb 2009
 //
@@ -36,8 +36,8 @@
    knowledge of the CeCILL license and that you accept its terms.
  */
 
-#include "CodonRateSubstitutionModel.h"
-
+#include "AbstractCodonBGCSubstitutionModel.h"
+#include <Bpp/Numeric/NumConstants.h>
 
 using namespace bpp;
 
@@ -45,29 +45,43 @@ using namespace std;
 
 /******************************************************************************/
 
-CodonRateSubstitutionModel::CodonRateSubstitutionModel(
-    const GeneticCode* gCode,
-    NucleotideSubstitutionModel* pmod) :
-  AbstractParameterAliasable("CodonRate."),
-  AbstractCodonSubstitutionModel(gCode, pmod, "CodonRate.", true)
+AbstractCodonBGCSubstitutionModel::AbstractCodonBGCSubstitutionModel(
+  const GeneticCode* pgencode,
+  const std::string& prefix) :
+  AbstractParameterAliasable(prefix),
+  pgencode_(pgencode),
+  B_(0),
+  S_(0)
 {
-  updateMatrices();
+  addParameter_(new Parameter(prefix + "S", 0));
+  addParameter_(new Parameter(prefix + "B", 0));
 }
 
-CodonRateSubstitutionModel::CodonRateSubstitutionModel(
-    const GeneticCode* gCode,
-    NucleotideSubstitutionModel* pmod1,
-    NucleotideSubstitutionModel* pmod2,
-    NucleotideSubstitutionModel* pmod3) :
-  AbstractParameterAliasable("CodonRate."),
-  AbstractCodonSubstitutionModel(gCode, pmod1, pmod2, pmod3, "CodonRate.", true)
+void AbstractCodonBGCSubstitutionModel::fireParameterChanged(const ParameterList& parameters)
 {
-  updateMatrices();
+  B_ = getParameterValue("B");
+  S_ = getParameterValue("S");
 }
 
-std::string CodonRateSubstitutionModel::getName() const
+double AbstractCodonBGCSubstitutionModel::getCodonsMulRate(size_t i, size_t j) const
 {
-  return "CodonRate";
-}
+  int epsilon = pgencode_->getSourceAlphabet()->getGCinCodon(static_cast<int>(j))
+    - pgencode_->getSourceAlphabet()->getGCinCodon(static_cast<int>(i));
 
+  switch (epsilon)
+  {
+  case 0:
+    return (pgencode_->areSynonymous(static_cast<int>(i), static_cast<int>(j))?1.
+            :(S_==0?1.:S_/(1-exp(-S_))));
+  case 1:
+    return (pgencode_->areSynonymous(static_cast<int>(i), static_cast<int>(j))
+            ?(B_==0?1:B_/(1-exp(-B_)))
+            :(B_+S_==0?1.:(B_+S_)/(1-exp(-(B_+S_)))));
+  case -1:
+    return (pgencode_->areSynonymous(static_cast<int>(i), static_cast<int>(j))
+            ?(B_==0?1:-B_/(1-exp(B_)))
+            :(-B_+S_==0?1.:(-B_+S_)/(1-exp(B_-S_))));
+  }
+  return 0;
+}
 
diff --git a/src/Bpp/Phyl/Model/Codon/AbstractCodonBGCSubstitutionModel.h b/src/Bpp/Phyl/Model/Codon/AbstractCodonBGCSubstitutionModel.h
new file mode 100644
index 0000000..84448e6
--- /dev/null
+++ b/src/Bpp/Phyl/Model/Codon/AbstractCodonBGCSubstitutionModel.h
@@ -0,0 +1,138 @@
+//
+// File: AbstractCodonDistanceSubstitutionModel.h
+// Created by: Laurent Gueguen
+// Created on: jeudi 15 septembre 2011, à 21h 11
+//
+
+/*
+  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 _ABSTRACTCODON_BGC_SUBSTITUTIONMODEL_H_
+#define _ABSTRACTCODON_BGC_SUBSTITUTIONMODEL_H_
+
+#include "CodonSubstitutionModel.h"
+#include <Bpp/Numeric/AbstractParameterAliasable.h>
+
+
+// From bpp-seq:
+#include <Bpp/Seq/GeneticCode/GeneticCode.h>
+#include <Bpp/Seq/AlphabetIndex/AlphabetIndex2.h>
+
+namespace bpp
+{
+/**
+ * @brief Abstract class for modelling of non-synonymous and
+ * synonymous substitution rates in codon models, with gBGC.
+ *
+ * @author Laurent Guéguen
+ *
+ * The non-synonymous substitution rate is multiplied with
+ * @f$\frac{\epsilon B+S}{1-e^{-(\epsilon B+S)}}@f$.
+ *
+ * The synonymous substitution rate is multiplied with @f$\frac{\epsilon
+ * B}{1-e^{-\epsilon B}}@f$.
+ *
+ * 
+ * with positive parameter @f$S at f$ that stands for selection, and real
+ * parameter @f$B at f$ for biased gene conversion. In the formula,
+ * @f$\epsilon = 1 at f$ for AT->GC substitutions, @f$\epsilon = -1 at f$
+ * for GC->AT substitution, and  @f$\epsilon = 0 at f$ otherwise.
+ *
+ *
+ * References:
+ * - Galtier N, Duret L, Glémin S, Ranwez V (2009) GC-biased gene
+ * conversion promotes the fixation of deleterious amino acid changes
+ * in primates, Trends in Genetics, vol. 25(1) pp.1-5.
+ *
+ */
+
+  class AbstractCodonBGCSubstitutionModel :
+    public virtual CoreCodonSubstitutionModel,
+    public virtual AbstractParameterAliasable
+  {
+  private:
+    const GeneticCode* pgencode_;
+  
+    double B_, S_;
+
+  public:
+    /**
+     * @brief Build a new AbstractCodonBGCSubstitutionModel object.
+     *
+     * @param pgencode the genetic code
+     * @param prefix the Namespace
+     */
+    AbstractCodonBGCSubstitutionModel(
+      const GeneticCode* pgencode,
+      const std::string& prefix);
+
+    AbstractCodonBGCSubstitutionModel(const AbstractCodonBGCSubstitutionModel& model) :
+      AbstractParameterAliasable(model),
+      pgencode_(model.pgencode_),
+      B_(model.B_),
+      S_(model.S_)
+    {}
+
+    AbstractCodonBGCSubstitutionModel& operator=(
+      const AbstractCodonBGCSubstitutionModel& model)
+    {
+      AbstractParameterAliasable::operator=(model);
+      pgencode_ = model.pgencode_;
+      B_ = model.B_;
+      S_ = model.S_;
+      return *this;
+    }
+
+    AbstractCodonBGCSubstitutionModel* clone() const
+    {
+      return new AbstractCodonBGCSubstitutionModel(*this);
+    }
+  
+    virtual ~AbstractCodonBGCSubstitutionModel() {}
+
+  public:
+    void fireParameterChanged(const ParameterList& parameters);
+
+    double getCodonsMulRate(size_t i, size_t j) const;
+
+    const FrequenciesSet* getFrequenciesSet() const 
+    {
+      return 0;
+    }
+
+  };
+
+} // end of namespace bpp.
+
+#endif
+
diff --git a/src/Bpp/Phyl/Model/Codon/AbstractCodonCpGSubstitutionModel.cpp b/src/Bpp/Phyl/Model/Codon/AbstractCodonCpGSubstitutionModel.cpp
index 2581093..6248ea9 100644
--- a/src/Bpp/Phyl/Model/Codon/AbstractCodonCpGSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/Codon/AbstractCodonCpGSubstitutionModel.cpp
@@ -1,5 +1,5 @@
 //
-// File: AbstractCodonDistanceSubstitutionModel.cpp
+// File: AbstractCodonCpGSubstitutionModel.cpp
 // Created by:  Laurent Gueguen
 // Created on: Feb 2009
 //
@@ -47,7 +47,6 @@ using namespace std;
 
 AbstractCodonCpGSubstitutionModel::AbstractCodonCpGSubstitutionModel(
   const std::string& prefix) :
-  CodonSubstitutionModel(),
   AbstractParameterAliasable(prefix),
   rho_(1)
 {
diff --git a/src/Bpp/Phyl/Model/Codon/AbstractCodonCpGSubstitutionModel.h b/src/Bpp/Phyl/Model/Codon/AbstractCodonCpGSubstitutionModel.h
index 6abdb70..0552d9c 100644
--- a/src/Bpp/Phyl/Model/Codon/AbstractCodonCpGSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/Codon/AbstractCodonCpGSubstitutionModel.h
@@ -1,41 +1,41 @@
 //
-// File: AbstractCodonDistanceSubstitutionModel.h
+// File: AbstractCodonCpGSubstitutionModel.h
 // Created by: Laurent Gueguen
 // Created on: jeudi 15 septembre 2011, à 21h 11
 //
 
 /*
-   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 _ABSTRACTCODONCPGSUBSTITUTIONMODEL_H_
 #define _ABSTRACTCODONCPGSUBSTITUTIONMODEL_H_
@@ -49,55 +49,66 @@ namespace bpp
 /**
  * @brief Abstract class for modelling of CpG -> CpA or TpG (symetric)
  *  hypermutability substitution rate inside codons. Note that the
- *  neihbouring effects between codons is note considered.
+ *  neihbouring effects between codons are not considered.
  *
  * @author Laurent Guéguen
  *
- * Substitution rate from C to T (resp. from G to A) is multiplied by a factor @f$\rho at f$
- *  if C is followed by a G (resp. if G is following a C).
+ * Substitution rate from C to T (resp. from G to A) is multiplied by
+ *  a factor @f$\rho at f$ if C is followed by a G (resp. if G is
+ *  following a C).
  *
  * Hypermutability parameter is named \c "rho".
  *
  */
 
-class AbstractCodonCpGSubstitutionModel :
-  public virtual CodonSubstitutionModel,
-  public virtual AbstractParameterAliasable
-{
-private:
-  double rho_;
-
-public:
-  /**
-   * @brief Build a new AbstractCodonCpGSubstitutionModel object from
-   *  a pointer to NucleotideSubstitutionModel.
-   *
-   * @param prefix the Namespace
-   */
-  AbstractCodonCpGSubstitutionModel(
-    const std::string& prefix);
-
-  AbstractCodonCpGSubstitutionModel(const AbstractCodonCpGSubstitutionModel& model) :
-    AbstractParameterAliasable(model),
-    rho_(model.rho_)
-  {}
-
-  AbstractCodonCpGSubstitutionModel& operator=(
-    const AbstractCodonCpGSubstitutionModel& model)
+  class AbstractCodonCpGSubstitutionModel :
+    public virtual CoreCodonSubstitutionModel,
+    public virtual AbstractParameterAliasable
   {
-    AbstractParameterAliasable::operator=(model);
-    rho_ = model.rho_;
-    return *this;
-  }
-
-  virtual ~AbstractCodonCpGSubstitutionModel() {}
-
-public:
-  void fireParameterChanged(const ParameterList& parameters);
-
-public:
-  double getCodonsMulRate(size_t i, size_t j) const;
-};
+  private:
+    double rho_;
+
+  public:
+    /**
+     * @brief Build a new AbstractCodonCpGSubstitutionModel object from
+     *  a pointer to NucleotideSubstitutionModel.
+     *
+     * @param prefix the Namespace
+     */
+    AbstractCodonCpGSubstitutionModel(
+      const std::string& prefix);
+
+    AbstractCodonCpGSubstitutionModel(const AbstractCodonCpGSubstitutionModel& model) :
+      AbstractParameterAliasable(model),
+      rho_(model.rho_)
+    {}
+
+    AbstractCodonCpGSubstitutionModel& operator=(
+      const AbstractCodonCpGSubstitutionModel& model)
+    {
+      AbstractParameterAliasable::operator=(model);
+      rho_ = model.rho_;
+      return *this;
+    }
+
+    AbstractCodonCpGSubstitutionModel* clone() const
+    {
+      return new AbstractCodonCpGSubstitutionModel(*this);
+    }
+
+    virtual ~AbstractCodonCpGSubstitutionModel() {}
+
+  public:
+    void fireParameterChanged(const ParameterList& parameters);
+
+    double getCodonsMulRate(size_t i, size_t j) const;
+
+    const FrequenciesSet* getFrequenciesSet() const 
+    {
+      return 0;
+    }
+
+  };
 
 } // end of namespace bpp.
 
diff --git a/src/Bpp/Phyl/Model/Codon/AbstractCodonDistanceSubstitutionModel.cpp b/src/Bpp/Phyl/Model/Codon/AbstractCodonDistanceSubstitutionModel.cpp
index 4dbdb5e..5ab8d5c 100644
--- a/src/Bpp/Phyl/Model/Codon/AbstractCodonDistanceSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/Codon/AbstractCodonDistanceSubstitutionModel.cpp
@@ -47,11 +47,12 @@ using namespace std;
 
 AbstractCodonDistanceSubstitutionModel::AbstractCodonDistanceSubstitutionModel(
   const AlphabetIndex2* pdist,
+  const GeneticCode* pgencode,
   const std::string& prefix,
   bool paramSynRate) :
-  CodonSubstitutionModel(),
   AbstractParameterAliasable(prefix),
   pdistance_(pdist),
+  pgencode_(pgencode),
   alpha_(10000),
   beta_(1),
   gamma_(1)
@@ -77,9 +78,9 @@ void AbstractCodonDistanceSubstitutionModel::fireParameterChanged(const Paramete
 
 double AbstractCodonDistanceSubstitutionModel::getCodonsMulRate(size_t i, size_t j) const
 {
-  return getGeneticCode()->areSynonymous(static_cast<int>(i), static_cast<int>(j)) ? gamma_ :
+  return pgencode_->areSynonymous(static_cast<int>(i), static_cast<int>(j)) ? gamma_ :
          beta_ * (pdistance_ ? exp(-pdistance_->getIndex(
-                 getGeneticCode()->translate(static_cast<int>(i)),
-                 getGeneticCode()->translate(static_cast<int>(j))) / alpha_) : 1);
+                                     pgencode_->translate(static_cast<int>(i)),
+                                     pgencode_->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 69a1420..ce319ad 100644
--- a/src/Bpp/Phyl/Model/Codon/AbstractCodonDistanceSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/Codon/AbstractCodonDistanceSubstitutionModel.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 _ABSTRACTCODONDISTANCESUBSTITUTIONMODEL_H_
 #define _ABSTRACTCODONDISTANCESUBSTITUTIONMODEL_H_
@@ -78,58 +78,74 @@ namespace bpp
  *   (2007), Bioinformatics, 23, i319--i327.
  */
 
-class AbstractCodonDistanceSubstitutionModel :
-  public virtual CodonSubstitutionModel,
-  public virtual AbstractParameterAliasable
-{
-private:
-  const AlphabetIndex2* pdistance_;
-
-  double alpha_, beta_;
-
-  double gamma_;
-public:
-  /**
-   * @brief Build a new AbstractCodonDistanceSubstitutionModel object from
-   *  a pointer to NucleotideSubstitutionModel.
-   *
-   * @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 AlphabetIndex2* pdist,
-    const std::string& prefix,
-    bool paramSynRate = false);
-
-  AbstractCodonDistanceSubstitutionModel(const AbstractCodonDistanceSubstitutionModel& model) :
-    AbstractParameterAliasable(model),
-    pdistance_(model.pdistance_),
-    alpha_(model.alpha_),
-    beta_(model.beta_),
-    gamma_(model.gamma_)
-  {}
-
-  AbstractCodonDistanceSubstitutionModel& operator=(
-    const AbstractCodonDistanceSubstitutionModel& model)
+  class AbstractCodonDistanceSubstitutionModel :
+    public virtual CoreCodonSubstitutionModel,
+    public virtual AbstractParameterAliasable
   {
-    AbstractParameterAliasable::operator=(model);
-    pdistance_ = model.pdistance_;
-    alpha_ = model.alpha_;
-    beta_ = model.beta_;
-    gamma_ = model.gamma_;
-    return *this;
-  }
-
-  virtual ~AbstractCodonDistanceSubstitutionModel() {}
-
-public:
-  void fireParameterChanged(const ParameterList& parameters);
-
-public:
-  double getCodonsMulRate(size_t i, size_t j) const;
-};
+  private:
+    const AlphabetIndex2* pdistance_;
+
+    const GeneticCode* pgencode_;
+  
+    double alpha_, beta_;
+
+    double gamma_;
+  public:
+    /**
+     * @brief Build a new AbstractCodonDistanceSubstitutionModel object.
+     *
+     * @param pdist optional pointer to a distance between amino-acids
+     * @param pgencode the genetic code
+     * @param prefix the Namespace
+     * @param paramSynRate is true iff synonymous rate is parametrised
+     *       (default=false).
+     */
+    
+    AbstractCodonDistanceSubstitutionModel(
+      const AlphabetIndex2* pdist,
+      const GeneticCode* pgencode,
+      const std::string& prefix,
+      bool paramSynRate = false);
+
+    AbstractCodonDistanceSubstitutionModel(const AbstractCodonDistanceSubstitutionModel& model) :
+      AbstractParameterAliasable(model),
+      pdistance_(model.pdistance_),
+      pgencode_(model.pgencode_),
+      alpha_(model.alpha_),
+      beta_(model.beta_),
+      gamma_(model.gamma_)
+    {}
+
+    AbstractCodonDistanceSubstitutionModel& operator=(
+      const AbstractCodonDistanceSubstitutionModel& model)
+    {
+      AbstractParameterAliasable::operator=(model);
+      pdistance_ = model.pdistance_;
+      pgencode_ = model.pgencode_;
+      alpha_ = model.alpha_;
+      beta_ = model.beta_;
+      gamma_ = model.gamma_;
+      return *this;
+    }
+
+    AbstractCodonDistanceSubstitutionModel* clone() const
+    {
+      return new AbstractCodonDistanceSubstitutionModel(*this);
+    }
+  
+    virtual ~AbstractCodonDistanceSubstitutionModel() {}
+
+  public:
+    void fireParameterChanged(const ParameterList& parameters);
+
+    double getCodonsMulRate(size_t i, size_t j) const;
+
+    const FrequenciesSet* getFrequenciesSet() const 
+    {
+      return 0;
+    }
+
+  };
 
 } // end of namespace bpp.
 
diff --git a/src/Bpp/Phyl/Model/Codon/AbstractCodonFitnessSubstitutionModel.cpp b/src/Bpp/Phyl/Model/Codon/AbstractCodonFitnessSubstitutionModel.cpp
index 4c49591..b90d666 100644
--- a/src/Bpp/Phyl/Model/Codon/AbstractCodonFitnessSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/Codon/AbstractCodonFitnessSubstitutionModel.cpp
@@ -40,14 +40,14 @@
 using namespace bpp;
 using namespace std;
 /****************************************************************************************/
-AbstractCodonFitnessSubstitutionModel::AbstractCodonFitnessSubstitutionModel(FrequenciesSet* pfitset, const string& prefix):
-  CodonSubstitutionModel(), AbstractParameterAliasable(prefix), pfitset_(pfitset), fitName_("")
+AbstractCodonFitnessSubstitutionModel::AbstractCodonFitnessSubstitutionModel(FrequenciesSet* pfitset, const GeneticCode* pgencode, const string& prefix):
+  AbstractParameterAliasable(prefix), pfitset_(pfitset), pgencode_(pgencode), fitName_("")
 {
   if (dynamic_cast<CodonFrequenciesSet*>(pfitset) == NULL)
-    throw Exception ("Bad type for fitness parameters"+ pfitset ->getName() );
+    throw Exception ("Bad type for fitness parameters"+ pfitset ->getName());
   fitName_="fit_"+ pfitset_->getNamespace();
   pfitset_->setNamespace(prefix + fitName_);
-  addParameters_(pfitset_->getParameters() );
+  addParameters_(pfitset_->getParameters());
 }
 
 AbstractCodonFitnessSubstitutionModel::~AbstractCodonFitnessSubstitutionModel()
@@ -69,8 +69,10 @@ void AbstractCodonFitnessSubstitutionModel::setFreq(map<int, double>& frequencie
 double AbstractCodonFitnessSubstitutionModel::getCodonsMulRate(size_t i, size_t j) const
 {
   double mu;
+
   double phi_j= pfitset_->getFrequencies() [j];
   double phi_i= pfitset_->getFrequencies() [i];
+  
   if (phi_i == phi_j) mu=1;
   else if (phi_i==0)
     mu=100;
diff --git a/src/Bpp/Phyl/Model/Codon/AbstractCodonFitnessSubstitutionModel.h b/src/Bpp/Phyl/Model/Codon/AbstractCodonFitnessSubstitutionModel.h
index 49aa385..37764b3 100644
--- a/src/Bpp/Phyl/Model/Codon/AbstractCodonFitnessSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/Codon/AbstractCodonFitnessSubstitutionModel.h
@@ -63,17 +63,26 @@ namespace bpp
 
 
   class AbstractCodonFitnessSubstitutionModel :
-    public virtual CodonSubstitutionModel,
+    public virtual CoreCodonSubstitutionModel,
     public virtual AbstractParameterAliasable
   {
   private:
     FrequenciesSet* pfitset_;
+
+    const GeneticCode* pgencode_;
+  
     std::string fitName_;
+
   public:
-    AbstractCodonFitnessSubstitutionModel(FrequenciesSet* pfitset, const std::string& prefix);
+    AbstractCodonFitnessSubstitutionModel(
+      FrequenciesSet* pfitset,
+      const GeneticCode* pgencode,
+      const std::string& prefix);
+    
     AbstractCodonFitnessSubstitutionModel(const AbstractCodonFitnessSubstitutionModel& model):
       AbstractParameterAliasable(model),
       pfitset_(model.pfitset_->clone()),
+      pgencode_(model.pgencode_),
       fitName_(model.fitName_)
     {}
 
@@ -81,17 +90,27 @@ namespace bpp
       AbstractParameterAliasable::operator=(model);
       if (pfitset_) delete pfitset_;
       pfitset_ = model.pfitset_->clone();
+      pgencode_ = model.pgencode_;
       fitName_ = model.fitName_ ;
       return *this;
     }
 
+    AbstractCodonFitnessSubstitutionModel* clone() const
+    {
+      return new AbstractCodonFitnessSubstitutionModel(*this);
+    }
+
     virtual ~AbstractCodonFitnessSubstitutionModel();
 
   public:
     void fireParameterChanged (const ParameterList& parameters);
+
     void setFreq(std::map<int, double>& frequencies);
+
     const FrequenciesSet& getFreq() const { return *pfitset_; }
+
     void setNamespace (const std::string& prefix){
+      AbstractParameterAliasable::setNamespace(prefix);
       pfitset_->setNamespace(prefix + fitName_);
     }
 
@@ -99,6 +118,11 @@ namespace bpp
 
     const FrequenciesSet* getFitness() const { return pfitset_;}
 
+    const FrequenciesSet* getFrequenciesSet() const 
+    {
+      return 0;
+    }
+
   };
 } // end of namespace bpp
 # endif
diff --git a/src/Bpp/Phyl/Model/Codon/AbstractCodonFrequenciesSubstitutionModel.cpp b/src/Bpp/Phyl/Model/Codon/AbstractCodonFrequenciesSubstitutionModel.cpp
index e93f50a..75db20b 100644
--- a/src/Bpp/Phyl/Model/Codon/AbstractCodonFrequenciesSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/Codon/AbstractCodonFrequenciesSubstitutionModel.cpp
@@ -49,7 +49,6 @@ using namespace std;
 AbstractCodonFrequenciesSubstitutionModel::AbstractCodonFrequenciesSubstitutionModel(
   FrequenciesSet* pfreq,
   const std::string& prefix) :
-  CodonSubstitutionModel(),
   AbstractParameterAliasable(prefix),
   pfreqset_(pfreq),
   freqName_("")
@@ -70,7 +69,7 @@ AbstractCodonFrequenciesSubstitutionModel::~AbstractCodonFrequenciesSubstitution
 
 void AbstractCodonFrequenciesSubstitutionModel::fireParameterChanged(const ParameterList& parameters)
 {
-  pfreqset_->matchParametersValues(parameters);
+  pfreqset_->matchParametersValues(parameters);  
 }
 
 
diff --git a/src/Bpp/Phyl/Model/Codon/AbstractCodonFrequenciesSubstitutionModel.h b/src/Bpp/Phyl/Model/Codon/AbstractCodonFrequenciesSubstitutionModel.h
index e61beca..3c4f60c 100644
--- a/src/Bpp/Phyl/Model/Codon/AbstractCodonFrequenciesSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/Codon/AbstractCodonFrequenciesSubstitutionModel.h
@@ -4,37 +4,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 _ABSTRACTCODONFREQUENCIESSUBSTITUTIONMODEL_H_
 #define _ABSTRACTCODONFREQUENCIESSUBSTITUTIONMODEL_H_
@@ -61,56 +61,67 @@ namespace bpp
  *
  */
 
-class AbstractCodonFrequenciesSubstitutionModel :
-  virtual public CodonSubstitutionModel,
-  virtual public AbstractParameterAliasable
-{
-private:
-  FrequenciesSet* pfreqset_;
-  std::string freqName_;
-
-public:
-  /**
-   *@brief Build a AbstractCodonFrequenciesSubstitutionModel instance
-   *
-   *@param pfreq pointer to the AbstractFrequenciesSet equilibrium frequencies.
-   *        It is owned by the instance.
-   *@param prefix the Namespace
-   */
-
-  AbstractCodonFrequenciesSubstitutionModel(FrequenciesSet* pfreq,
-                                            const std::string& prefix);
-
-  AbstractCodonFrequenciesSubstitutionModel(const AbstractCodonFrequenciesSubstitutionModel& model) :
-    AbstractParameterAliasable(model),
-    pfreqset_(model.pfreqset_->clone()),
-    freqName_(model.freqName_)
-  {}
-
-  AbstractCodonFrequenciesSubstitutionModel& operator=(const AbstractCodonFrequenciesSubstitutionModel& model)
+  class AbstractCodonFrequenciesSubstitutionModel :
+    virtual public CoreCodonSubstitutionModel,
+    virtual public AbstractParameterAliasable
   {
-    AbstractParameterAliasable::operator=(model);
-    if (pfreqset_) delete pfreqset_;
-    pfreqset_   = model.pfreqset_->clone();
-    freqName_   = model.freqName_;
-    return *this;
-  }
-
-  virtual ~AbstractCodonFrequenciesSubstitutionModel();
-
-  void fireParameterChanged(const ParameterList& parameters);
-
-  void setFreq(std::map<int, double>& frequencies);
-
-  const FrequenciesSet* getFrequenciesSet() const { return pfreqset_; }
-
-  void setNamespace(const std::string& prefix)
-  {
-    pfreqset_->setNamespace(prefix + freqName_);
-  }
-
-  double getCodonsMulRate(size_t, size_t) const;
-};
+  private:
+    FrequenciesSet* pfreqset_;
+    std::string freqName_;
+
+  public:
+    /**
+     *@brief Build a AbstractCodonFrequenciesSubstitutionModel instance
+     *
+     *@param pfreq pointer to the AbstractFrequenciesSet equilibrium frequencies.
+     *        It is owned by the instance.
+     *@param prefix the Namespace
+     */
+
+    AbstractCodonFrequenciesSubstitutionModel(FrequenciesSet* pfreq,
+                                              const std::string& prefix);
+
+    AbstractCodonFrequenciesSubstitutionModel(const AbstractCodonFrequenciesSubstitutionModel& model) :
+      AbstractParameterAliasable(model),
+      pfreqset_(model.pfreqset_->clone()),
+      freqName_(model.freqName_)
+    {}
+
+    AbstractCodonFrequenciesSubstitutionModel& operator=(const AbstractCodonFrequenciesSubstitutionModel& model)
+    {
+      AbstractParameterAliasable::operator=(model);
+      if (pfreqset_) delete pfreqset_;
+      pfreqset_   = model.pfreqset_->clone();
+      freqName_   = model.freqName_;
+      return *this;
+    }
+
+    AbstractCodonFrequenciesSubstitutionModel* clone() const
+    {
+      return new AbstractCodonFrequenciesSubstitutionModel(*this);
+    }
+
+    virtual ~AbstractCodonFrequenciesSubstitutionModel();
+
+    void fireParameterChanged(const ParameterList& parameters);
+
+    void setFreq(std::map<int, double>& frequencies);
+
+    void setNamespace(const std::string& prefix)
+    {
+      AbstractParameterAliasable::setNamespace(prefix);
+      pfreqset_->setNamespace(prefix + freqName_);
+    }
+
+    double getCodonsMulRate(size_t, size_t) const;
+
+    const FrequenciesSet* getFrequenciesSet() const 
+    {
+      return pfreqset_;
+    }
+
+  };
+  
 } // end of namespace bpp.
 
 #endif
diff --git a/src/Bpp/Phyl/Model/Codon/AbstractCodonPhaseFrequenciesSubstitutionModel.cpp b/src/Bpp/Phyl/Model/Codon/AbstractCodonPhaseFrequenciesSubstitutionModel.cpp
index 90fc857..21f6abc 100644
--- a/src/Bpp/Phyl/Model/Codon/AbstractCodonPhaseFrequenciesSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/Codon/AbstractCodonPhaseFrequenciesSubstitutionModel.cpp
@@ -48,7 +48,6 @@ using namespace std;
 AbstractCodonPhaseFrequenciesSubstitutionModel::AbstractCodonPhaseFrequenciesSubstitutionModel(
   FrequenciesSet* pfreq,
   const std::string& prefix) :
-  CodonSubstitutionModel(),
   AbstractParameterAliasable(prefix),
   posfreqset_(),
   freqName_("")
@@ -66,12 +65,12 @@ AbstractCodonPhaseFrequenciesSubstitutionModel::AbstractCodonPhaseFrequenciesSub
     if (dynamic_cast<FixedCodonFrequenciesSet*>(pCFS)) {
       for (unsigned int i = 0; i < 3; i++)
       {
-        vFS.push_back(new FixedNucleotideFrequenciesSet(pCFS->getAlphabet()->getNucleicAlphabet()));
+        vFS.push_back(new FixedNucleotideFrequenciesSet(pCFS->getCodonAlphabet()->getNucleicAlphabet()));
       }
     } else {
       for (unsigned int i = 0; i < 3; i++)
       {
-        vFS.push_back(new FullNucleotideFrequenciesSet(pCFS->getAlphabet()->getNucleicAlphabet()));
+        vFS.push_back(new FullNucleotideFrequenciesSet(pCFS->getCodonAlphabet()->getNucleicAlphabet()));
       }
     }
     posfreqset_ = new CodonFromIndependentFrequenciesSet(
@@ -83,8 +82,8 @@ AbstractCodonPhaseFrequenciesSubstitutionModel::AbstractCodonPhaseFrequenciesSub
 
   freqName_ = pfreq->getNamespace();
   posfreqset_->setNamespace(prefix + pfreq->getNamespace());
-  //  if (dynamic_cast<FixedCodonFrequenciesSet*>(pCFS)!=NULL)
   addParameters_(posfreqset_->getParameters());
+  fireParameterChanged(posfreqset_->getParameters());
 }
 
 AbstractCodonPhaseFrequenciesSubstitutionModel::~AbstractCodonPhaseFrequenciesSubstitutionModel()
diff --git a/src/Bpp/Phyl/Model/Codon/AbstractCodonPhaseFrequenciesSubstitutionModel.h b/src/Bpp/Phyl/Model/Codon/AbstractCodonPhaseFrequenciesSubstitutionModel.h
index ed7d008..4109ee1 100644
--- a/src/Bpp/Phyl/Model/Codon/AbstractCodonPhaseFrequenciesSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/Codon/AbstractCodonPhaseFrequenciesSubstitutionModel.h
@@ -4,37 +4,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 _ABSTRACTCODONPHASEFREQUENCIESSUBSTITUTIONMODEL_H_
 #define _ABSTRACTCODONPHASEFREQUENCIESSUBSTITUTIONMODEL_H_
@@ -66,61 +66,71 @@ namespace bpp
  *
  */
 
-class AbstractCodonPhaseFrequenciesSubstitutionModel :
-  public virtual CodonSubstitutionModel,
-  public virtual AbstractParameterAliasable
-{
-private:
-  /**
-   * @brief Position dependent version of Codon Frequencies Set
-   */
-  WordFrequenciesSet* posfreqset_;
-  std::string freqName_;
-
-public:
-  /**
-   * @brief Build a AbstractCodonPhaseFrequenciesSubstitutionModel instance
-   *
-   * @param pfreq pointer to the AbstractFrequenciesSet equilibrium frequencies.
-   *        It is owned by the instance.
-   * @param prefix the Namespace
-   */
-  AbstractCodonPhaseFrequenciesSubstitutionModel(
+  class AbstractCodonPhaseFrequenciesSubstitutionModel :
+    public virtual CoreCodonSubstitutionModel,
+    public virtual AbstractParameterAliasable
+  {
+  private:
+    /**
+     * @brief Position dependent version of Codon Frequencies Set
+     */
+    WordFrequenciesSet* posfreqset_;
+    std::string freqName_;
+
+  public:
+    /**
+     * @brief Build a AbstractCodonPhaseFrequenciesSubstitutionModel instance
+     *
+     * @param pfreq pointer to the AbstractFrequenciesSet equilibrium frequencies.
+     *        It is owned by the instance.
+     * @param prefix the Namespace
+     */
+    AbstractCodonPhaseFrequenciesSubstitutionModel(
       FrequenciesSet* pfreq,
       const std::string& prefix);
 
-  AbstractCodonPhaseFrequenciesSubstitutionModel(const AbstractCodonPhaseFrequenciesSubstitutionModel& model) :
-    AbstractParameterAliasable(model),
-    posfreqset_(model.posfreqset_->clone()),
-    freqName_(model.freqName_)
-  {}
+    AbstractCodonPhaseFrequenciesSubstitutionModel(const AbstractCodonPhaseFrequenciesSubstitutionModel& model) :
+      AbstractParameterAliasable(model),
+      posfreqset_(model.posfreqset_->clone()),
+      freqName_(model.freqName_)
+    {}
 
-  AbstractCodonPhaseFrequenciesSubstitutionModel& operator=(const AbstractCodonPhaseFrequenciesSubstitutionModel& model)
-  {
-    AbstractParameterAliasable::operator=(model);
-    if (posfreqset_)
-      delete posfreqset_;
-    posfreqset_   = model.posfreqset_->clone();
-    freqName_   = model.freqName_;
+    AbstractCodonPhaseFrequenciesSubstitutionModel& operator=(const AbstractCodonPhaseFrequenciesSubstitutionModel& model)
+    {
+      AbstractParameterAliasable::operator=(model);
+      if (posfreqset_)
+        delete posfreqset_;
+      posfreqset_   = model.posfreqset_->clone();
+      freqName_   = model.freqName_;
 
-    return *this;
-  }
+      return *this;
+    }
 
-  virtual ~AbstractCodonPhaseFrequenciesSubstitutionModel();
+    AbstractCodonPhaseFrequenciesSubstitutionModel* clone() const
+    {
+      return new AbstractCodonPhaseFrequenciesSubstitutionModel(*this);
+    }
 
-  void fireParameterChanged(const ParameterList& parameters);
+    virtual ~AbstractCodonPhaseFrequenciesSubstitutionModel();
+  
+    void fireParameterChanged(const ParameterList& parameters);
 
-  void setFreq(std::map<int, double>& frequencies);
+    void setFreq(std::map<int, double>& frequencies);
 
-  const FrequenciesSet* getFrequenciesSet() const { return posfreqset_; }
+     void setNamespace(const std::string& prefix)
+    {
+      AbstractParameterAliasable::setNamespace(prefix);
+      posfreqset_->setNamespace(prefix + freqName_);
+    }
 
-  void setNamespace(const std::string& prefix)
-  {
-    posfreqset_->setNamespace(prefix + freqName_);
-  }
+    double getCodonsMulRate(size_t, size_t) const;
+
+    const FrequenciesSet* getFrequenciesSet() const 
+    {
+      return posfreqset_;
+    }
 
-  double getCodonsMulRate(size_t, size_t) const;
-};
+  };
 } // end of namespace bpp.
 
 #endif
diff --git a/src/Bpp/Phyl/Model/Codon/AbstractCodonSubstitutionModel.cpp b/src/Bpp/Phyl/Model/Codon/AbstractCodonSubstitutionModel.cpp
index 1f03d30..25cb882 100644
--- a/src/Bpp/Phyl/Model/Codon/AbstractCodonSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/Codon/AbstractCodonSubstitutionModel.cpp
@@ -65,6 +65,7 @@ AbstractCodonSubstitutionModel::AbstractCodonSubstitutionModel(
 
   pmod->setNamespace(prefix + "123_" + VnestedPrefix_[0]);
   pmod->enableEigenDecomposition(0);
+
   addParameters_(pmod->getParameters());
 
   Vrate_.resize(3);
diff --git a/src/Bpp/Phyl/Model/Codon/AbstractCodonSubstitutionModel.h b/src/Bpp/Phyl/Model/Codon/AbstractCodonSubstitutionModel.h
index 382b677..1122dc5 100644
--- a/src/Bpp/Phyl/Model/Codon/AbstractCodonSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/Codon/AbstractCodonSubstitutionModel.h
@@ -69,6 +69,7 @@ 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 AbstractWordSubstitutionModel
diff --git a/src/Bpp/Phyl/Model/Codon/CodonAdHocSubstitutionModel.cpp b/src/Bpp/Phyl/Model/Codon/CodonAdHocSubstitutionModel.cpp
new file mode 100644
index 0000000..62ba3ee
--- /dev/null
+++ b/src/Bpp/Phyl/Model/Codon/CodonAdHocSubstitutionModel.cpp
@@ -0,0 +1,172 @@
+//
+// File: CodonAdHocSubstitutionModel.cpp
+// Created by:  Laurent Gueguen
+// Created on: lundi 30 octobre 2017, à 06h 39
+//
+
+/*
+  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 "CodonAdHocSubstitutionModel.h"
+
+using namespace bpp;
+
+using namespace std;
+
+/******************************************************************************/
+
+CodonAdHocSubstitutionModel::CodonAdHocSubstitutionModel(
+    const GeneticCode* gCode,
+    NucleotideSubstitutionModel* pmod,
+    std::vector<CoreCodonSubstitutionModel*>& vpmodel,
+    const std::string& name) :
+  AbstractParameterAliasable(name+"."),
+  AbstractCodonSubstitutionModel(gCode, pmod, name+"."),
+  vModel_(),
+  name_(name),
+  freqSet_()
+{
+  for (auto model : vpmodel)
+    if (model!=NULL)
+    {
+      model->setNamespace(name+".");
+      if (model->getFrequenciesSet())
+      {
+        if (freqSet_)
+          throw Exception("CodonAdHocSubstitutionModel::CodonAdHocSubstitutionModel : two sub models with FrequenciesSet");
+        
+        freqSet_=model->getFrequenciesSet();
+      }
+      vModel_.push_back(unique_ptr<CoreCodonSubstitutionModel>(model));
+      addParameters_(model->getParameters());
+    }
+  computeFrequencies(true);
+  updateMatrices();
+}
+
+CodonAdHocSubstitutionModel::CodonAdHocSubstitutionModel(
+    const GeneticCode* gCode,
+    NucleotideSubstitutionModel* pmod1,
+    NucleotideSubstitutionModel* pmod2,
+    NucleotideSubstitutionModel* pmod3,
+    std::vector<CoreCodonSubstitutionModel*>& vpmodel,
+    const std::string& name) :
+  AbstractParameterAliasable(name+"."),
+  AbstractCodonSubstitutionModel(gCode, pmod1, pmod2, pmod3, name+"."),
+  vModel_(),
+  name_(name),
+  freqSet_()
+{
+  for (auto& model : vpmodel)
+    if (model!=NULL)
+    {
+      model->setNamespace(name+".");
+      if (model->getFrequenciesSet())
+      {
+        if (freqSet_)
+          throw Exception("CodonAdHocSubstitutionModel::CodonAdHocSubstitutionModel : two sub models with FrequenciesSet");
+        
+        freqSet_=model->getFrequenciesSet();
+      }
+      
+      vModel_.push_back(unique_ptr<CoreCodonSubstitutionModel>(model));
+      addParameters_(model->getParameters());
+    }
+
+  computeFrequencies(true);
+  updateMatrices();
+}
+
+CodonAdHocSubstitutionModel::CodonAdHocSubstitutionModel(const CodonAdHocSubstitutionModel& model) :
+  AbstractParameterAliasable(model),
+  AbstractCodonSubstitutionModel(model),
+  vModel_(),
+  name_(model.name_),
+  freqSet_()
+{
+  for (auto& mod : model.vModel_)
+    vModel_.emplace_back(mod->clone());
+
+  for (auto& mod : vModel_)
+    if (mod->getFrequenciesSet())
+    {
+      if (freqSet_)
+        throw Exception("CodonAdHocSubstitutionModel::CodonAdHocSubstitutionModel : two sub models with FrequenciesSet");
+        
+      freqSet_=mod->getFrequenciesSet();
+    }
+}
+
+CodonAdHocSubstitutionModel& CodonAdHocSubstitutionModel::operator=(const CodonAdHocSubstitutionModel& model)
+{
+  AbstractParameterAliasable::operator=(model);
+  AbstractCodonSubstitutionModel::operator=(model);
+  name_ = model.name_;
+  
+  vModel_.clear();
+  freqSet_=0;  
+  
+  for (auto& mod : model.vModel_)
+    vModel_.emplace_back(mod->clone());
+
+  for (auto& mod : vModel_)
+    if (mod->getFrequenciesSet())
+    {
+      if (freqSet_)
+        throw Exception("CodonAdHocSubstitutionModel::CodonAdHocSubstitutionModel : two sub models with FrequenciesSet");
+      
+      freqSet_=mod->getFrequenciesSet();
+    }
+
+  return *this;
+}
+
+
+void CodonAdHocSubstitutionModel::fireParameterChanged(const ParameterList& parameters)
+{
+  for (auto& model : vModel_)
+    model->matchParametersValues(parameters);
+
+  // Beware: must be called at the end
+  AbstractCodonSubstitutionModel::fireParameterChanged(parameters);
+}
+
+double CodonAdHocSubstitutionModel::getCodonsMulRate(size_t i, size_t j) const
+{
+  double x(1);
+
+  for (auto& model : vModel_)
+    x*= model->getCodonsMulRate(i,j);
+  
+  return x * AbstractCodonSubstitutionModel::getCodonsMulRate(i,j);
+}
+
diff --git a/src/Bpp/Phyl/Model/Codon/CodonDistanceCpGSubstitutionModel.h b/src/Bpp/Phyl/Model/Codon/CodonAdHocSubstitutionModel.h
similarity index 60%
rename from src/Bpp/Phyl/Model/Codon/CodonDistanceCpGSubstitutionModel.h
rename to src/Bpp/Phyl/Model/Codon/CodonAdHocSubstitutionModel.h
index d3ac593..aa83bd2 100644
--- a/src/Bpp/Phyl/Model/Codon/CodonDistanceCpGSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/Codon/CodonAdHocSubstitutionModel.h
@@ -1,7 +1,7 @@
 //
-// File: CodonDistanceCpGSubstitutionModel.h
+// File: CodonAdHocSubstitutionModel.h
 // Created by: Laurent Gueguen
-// Created on: Tue Dec 24 11:03:53 2003
+// Created on: lundi 30 octobre 2017, à 06h 31
 //
 
 /*
@@ -37,21 +37,16 @@
   knowledge of the CeCILL license and that you accept its terms.
 */
 
-#ifndef _CODONDISTANCECPGSUBSTITUTIONMODEL_H_
-#define _CODONDISTANCECPGSUBSTITUTIONMODEL_H_
+#ifndef _CODON_ADHOC_SUBSTITUTIONMODEL_H_
+#define _CODON_ADHOC_SUBSTITUTIONMODEL_H_
 
-#include "AbstractCodonDistanceSubstitutionModel.h"
-#include "AbstractCodonCpGSubstitutionModel.h"
 #include "AbstractCodonSubstitutionModel.h"
 
 namespace bpp
 {
   /**
    * @brief Class for substitution models of codons with
-   * non-synonymous/synonymous ratios of substitution rates defined
-   * through a distance between amino-acids, with additional INSIDE
-   * codons CpG hypermutability rate multiplier (parameter \c "rho").
-   *
+   * several layers of codon models
    *
    * @author Laurent Guéguen
    *
@@ -60,40 +55,47 @@ namespace bpp
    *
    * Only substitutions with one letter changed are accepted. </p>
    *
-   * If a distance @f$d at f$ between amino-acids is defined, the ratio between
-   * non-synonymous and synonymous substitutions rates is, if the codied
-   * amino-acids are @f$x at f$ and @f$y at f$, @f$\beta*\exp(-\alpha.d(x,y))@f$ with
-   * non-negative parameter \c "alpha" and positive parameter \c "beta".
-   *
-   * If such a distance is not defined, the ratio between non-synonymous
-   * and synonymous substitutions rates is @f$\beta at f$ with positive
-   * parameter \c "beta".
    *
    */
 
-  class CodonDistanceCpGSubstitutionModel :
-    public AbstractCodonSubstitutionModel,
-    public AbstractCodonDistanceSubstitutionModel,
-    public AbstractCodonCpGSubstitutionModel
+  class CodonAdHocSubstitutionModel :
+    public AbstractCodonSubstitutionModel
   {
+  private:
+
+    std::vector<std::unique_ptr<CoreCodonSubstitutionModel> > vModel_;
+
+    std::string name_;
+
+    /*
+     * @brief optional FrequenciesSet if model is defined through a
+     * FrequenciesSet.
+     *
+     */
+     
+    const FrequenciesSet* freqSet_;
+    
   public:
     /**
-     * @brief Build a new CodonDistanceCpGSubstitutionModel object from
+     * @brief Build a new CodonAdHocSubstitutionModel object from
      * a pointer to NucleotideSubstitutionModel.
      *
      * @param gCode pointer to a GeneticCode
-     * @param pmod  pointer to the NucleotideSubstitutionModel to use in the three positions.
+     * @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
+     * @param vpmodel vector of codon models. They will be owned by the model.
+     * @param name the name of the model
      */
 
-    CodonDistanceCpGSubstitutionModel(
-        const GeneticCode* gCode,
-        NucleotideSubstitutionModel* pmod,
-        const AlphabetIndex2* pdist);
+    CodonAdHocSubstitutionModel(
+      const GeneticCode* gCode,
+      NucleotideSubstitutionModel* pmod,
+      std::vector<CoreCodonSubstitutionModel*>& vpmodel,
+      const std::string& name);
 
     /**
-     * @brief Build a new CodonDistanceCpGSubstitutionModel object
+     * @brief Build a new CodonAdHocSubstitutionModel object
      * from three pointers to NucleotideSubstitutionModels.
      *
      * @param gCode pointer to a GeneticCode
@@ -102,32 +104,58 @@ namespace bpp
      *   Either all the models are different objects to avoid parameters
      *   redondancy, or only the first model is used in every position.
      *   The used models are owned by the instance.
-     * @param pdist optional pointer to the AlphabetIndex2 amino-acids distance object.
+     * @param vpmodel vector of codon models. They will be owned by the
+     * model.
+     * @param name the name of the model
      */
 
-    CodonDistanceCpGSubstitutionModel(
+    CodonAdHocSubstitutionModel(
         const GeneticCode* gCode,
         NucleotideSubstitutionModel* pmod1,
         NucleotideSubstitutionModel* pmod2,
         NucleotideSubstitutionModel* pmod3,
-        const AlphabetIndex2* pdist);
+        std::vector<CoreCodonSubstitutionModel*>& vpmodel,
+        const std::string& name);
+
+    CodonAdHocSubstitutionModel(const CodonAdHocSubstitutionModel& model);
+
+    CodonAdHocSubstitutionModel& operator=(const CodonAdHocSubstitutionModel& model);
 
-    virtual ~CodonDistanceCpGSubstitutionModel() {}
+    virtual ~CodonAdHocSubstitutionModel() {}
 
-    CodonDistanceCpGSubstitutionModel* clone() const
+    CodonAdHocSubstitutionModel* clone() const
     {
-      return new CodonDistanceCpGSubstitutionModel(*this);
+      return new CodonAdHocSubstitutionModel(*this);
     }
 
   public:
     void fireParameterChanged(const ParameterList& parameterlist);
   
-    std::string getName() const;
+    std::string getName() const
+    {
+      return name_;
+    }
+
+    size_t  getNumberOfModels() const
+    {
+      return vModel_.size();
+    }
 
+    const std::unique_ptr<CoreCodonSubstitutionModel>& getNModel(size_t i) const
+    {
+      return vModel_[i];
+    }
+    
     double getCodonsMulRate(size_t i, size_t j) const;
+
+    const FrequenciesSet* getFrequenciesSet() const
+    {
+      return freqSet_;
+    }
+    
   };
   
 } // end of namespace bpp.
 
-#endif //_CODONDISTANCECPGSUBSTITUTIONMODEL_H_
+#endif //_CODON_ADHOC_SUBSTITUTIONMODEL_H_
 
diff --git a/src/Bpp/Phyl/Model/Codon/CodonDistanceCpGSubstitutionModel.cpp b/src/Bpp/Phyl/Model/Codon/CodonDistanceCpGSubstitutionModel.cpp
deleted file mode 100644
index c0121dc..0000000
--- a/src/Bpp/Phyl/Model/Codon/CodonDistanceCpGSubstitutionModel.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-//
-// File: CodonDistanceSubstitutionModel.cpp
-// Created by:  Laurent Gueguen
-// Created on: Feb 2009
-//
-
-/*
-  Copyright or © or Copr. Bio++ Development Team, (November 16, 2004)
-  This software is a computer program whose purpose is to provide classes
-  for phylogenetic data analysis.
-
-  This software is governed by the CeCILL  license under French law and
-  abiding by the rules of distribution of free software.  You can  use,
-  modify and/ or redistribute the software under the terms of the CeCILL
-  license as circulated by CEA, CNRS and INRIA at the following URL
-  "http://www.cecill.info".
-
-  As a counterpart to the access to the source code and  rights to copy,
-  modify and redistribute granted by the license, users are provided only
-  with a limited warranty  and the software's author,  the holder of the
-  economic rights,  and the successive licensors  have only  limited
-  liability.
-
-  In this respect, the user's attention is drawn to the risks associated
-  with loading,  using,  modifying and/or developing or reproducing the
-  software by the user in light of its specific status of free software,
-  that may mean  that it is complicated to manipulate,  and  that  also
-  therefore means  that it is reserved for developers  and  experienced
-  professionals having in-depth computer knowledge. Users are therefore
-  encouraged to load and test the software's suitability as regards their
-  requirements in conditions enabling the security of their systems and/or
-  data to be ensured and,  more generally, to use and operate it in the
-  same conditions as regards security.
-
-  The fact that you are presently reading this means that you have had
-  knowledge of the CeCILL license and that you accept its terms.
-*/
-
-#include "CodonDistanceCpGSubstitutionModel.h"
-
-using namespace bpp;
-
-using namespace std;
-
-/******************************************************************************/
-
-CodonDistanceCpGSubstitutionModel::CodonDistanceCpGSubstitutionModel(
-    const GeneticCode* gCode,
-    NucleotideSubstitutionModel* pmod,
-    const AlphabetIndex2* pdist) :
-  AbstractParameterAliasable("CodonDistCpG."),
-  AbstractCodonSubstitutionModel(gCode, pmod, "CodonDistCpG."),
-  AbstractCodonDistanceSubstitutionModel(pdist, "CodonDistCpG."),
-  AbstractCodonCpGSubstitutionModel("CodonDistCpG.")
-{
-  updateMatrices();
-}
-
-CodonDistanceCpGSubstitutionModel::CodonDistanceCpGSubstitutionModel(
-    const GeneticCode* gCode,
-    NucleotideSubstitutionModel* pmod1,
-    NucleotideSubstitutionModel* pmod2,
-    NucleotideSubstitutionModel* pmod3,
-    const AlphabetIndex2* pdist) :
-  AbstractParameterAliasable("CodonDistCpG."),
-  AbstractCodonSubstitutionModel(gCode, pmod1, pmod2, pmod3, "CodonDistCpG."),
-  AbstractCodonDistanceSubstitutionModel(pdist, "CodonDistCpG."),
-  AbstractCodonCpGSubstitutionModel("CodonDistCpG.")
-{
-  updateMatrices();
-}
-
-std::string CodonDistanceCpGSubstitutionModel::getName() const
-{
-  return "CodonDistCpG";
-}
-
-void CodonDistanceCpGSubstitutionModel::fireParameterChanged(const ParameterList& parameters)
-{
-  AbstractCodonDistanceSubstitutionModel::fireParameterChanged(parameters);
-  AbstractCodonCpGSubstitutionModel::fireParameterChanged(parameters);
-
-  // Beware: must be call at the end
-  AbstractCodonSubstitutionModel::fireParameterChanged(parameters);
-}
-
-double CodonDistanceCpGSubstitutionModel::getCodonsMulRate(size_t i, size_t j) const
-{
-  return AbstractCodonDistanceSubstitutionModel::getCodonsMulRate(i,j)
-    * AbstractCodonCpGSubstitutionModel::getCodonsMulRate(i,j)
-    * AbstractCodonSubstitutionModel::getCodonsMulRate(i,j);
-}
-
diff --git a/src/Bpp/Phyl/Model/Codon/CodonDistanceFrequenciesSubstitutionModel.cpp b/src/Bpp/Phyl/Model/Codon/CodonDistanceFrequenciesSubstitutionModel.cpp
index fc86530..e464aad 100644
--- a/src/Bpp/Phyl/Model/Codon/CodonDistanceFrequenciesSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/Codon/CodonDistanceFrequenciesSubstitutionModel.cpp
@@ -52,10 +52,12 @@ CodonDistanceFrequenciesSubstitutionModel::CodonDistanceFrequenciesSubstitutionM
     bool paramSynRate) :
   AbstractParameterAliasable("CodonDistFreq."),
   AbstractCodonSubstitutionModel(gCode, pmod, "CodonDistFreq."),
-  AbstractCodonDistanceSubstitutionModel(pdist, "CodonDistFreq.", paramSynRate),
+  AbstractCodonDistanceSubstitutionModel(pdist, gCode, "CodonDistFreq.", paramSynRate),
   AbstractCodonFrequenciesSubstitutionModel(pfreq, "CodonDistFreq.")
 {
+  computeFrequencies(true); // for initialization
   updateMatrices();
+  computeFrequencies(false);
 }
 
 CodonDistanceFrequenciesSubstitutionModel::CodonDistanceFrequenciesSubstitutionModel(
@@ -68,10 +70,12 @@ CodonDistanceFrequenciesSubstitutionModel::CodonDistanceFrequenciesSubstitutionM
     bool paramSynRate) :
   AbstractParameterAliasable("CodonDistFreq."),
   AbstractCodonSubstitutionModel(gCode, pmod1, pmod2, pmod3, "CodonDistFreq."),
-  AbstractCodonDistanceSubstitutionModel(pdist, "CodonDistFreq.", paramSynRate),
+  AbstractCodonDistanceSubstitutionModel(pdist, gCode, "CodonDistFreq.", paramSynRate),
   AbstractCodonFrequenciesSubstitutionModel(pfreq, "CodonDistFreq.")
 {
+  computeFrequencies(true); // for initialization
   updateMatrices();
+  computeFrequencies(false);
 }
 
 std::string CodonDistanceFrequenciesSubstitutionModel::getName() const
@@ -83,6 +87,7 @@ void CodonDistanceFrequenciesSubstitutionModel::fireParameterChanged(const Param
 {
   AbstractCodonDistanceSubstitutionModel::fireParameterChanged(parameters);
   AbstractCodonFrequenciesSubstitutionModel::fireParameterChanged(parameters);
+  getFrequencies_()=AbstractCodonFrequenciesSubstitutionModel::getFrequenciesSet()->getFrequencies();
 
   // Beware: must be call at the end
   AbstractCodonSubstitutionModel::fireParameterChanged(parameters);
@@ -106,4 +111,5 @@ void CodonDistanceFrequenciesSubstitutionModel::setNamespace(const std::string&
 void CodonDistanceFrequenciesSubstitutionModel::setFreq(map<int,double>& frequencies)
 {
   AbstractCodonFrequenciesSubstitutionModel::setFreq(frequencies);
+  getFrequencies_()=AbstractCodonFrequenciesSubstitutionModel::getFrequenciesSet()->getFrequencies();
 }
diff --git a/src/Bpp/Phyl/Model/Codon/CodonDistanceFrequenciesSubstitutionModel.h b/src/Bpp/Phyl/Model/Codon/CodonDistanceFrequenciesSubstitutionModel.h
index 534e08b..3b20edd 100644
--- a/src/Bpp/Phyl/Model/Codon/CodonDistanceFrequenciesSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/Codon/CodonDistanceFrequenciesSubstitutionModel.h
@@ -154,6 +154,10 @@ public:
 
   void setFreq(std::map<int,double>& frequencies);
 
+  const FrequenciesSet* getFrequenciesSet() const { 
+    return AbstractCodonFrequenciesSubstitutionModel::getFrequenciesSet();
+  }
+  
 };
 
 } // end of namespace bpp.
diff --git a/src/Bpp/Phyl/Model/Codon/CodonDistancePhaseFrequenciesSubstitutionModel.cpp b/src/Bpp/Phyl/Model/Codon/CodonDistancePhaseFrequenciesSubstitutionModel.cpp
index b40273d..7c76bd2 100644
--- a/src/Bpp/Phyl/Model/Codon/CodonDistancePhaseFrequenciesSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/Codon/CodonDistancePhaseFrequenciesSubstitutionModel.cpp
@@ -51,10 +51,12 @@ CodonDistancePhaseFrequenciesSubstitutionModel::CodonDistancePhaseFrequenciesSub
     const AlphabetIndex2* pdist) :
   AbstractParameterAliasable("CodonDistPhasFreq."),
   AbstractCodonSubstitutionModel(gCode, pmod, "CodonDistPhasFreq."),
-  AbstractCodonDistanceSubstitutionModel(pdist, "CodonDistPhasFreq."),
+  AbstractCodonDistanceSubstitutionModel(pdist, gCode, "CodonDistPhasFreq."),
   AbstractCodonPhaseFrequenciesSubstitutionModel(pfreq, "CodonDistPhasFreq.")
 {
+  computeFrequencies(true); //for init
   updateMatrices();
+  computeFrequencies(false);
 }
 
 CodonDistancePhaseFrequenciesSubstitutionModel::CodonDistancePhaseFrequenciesSubstitutionModel(
@@ -66,10 +68,12 @@ CodonDistancePhaseFrequenciesSubstitutionModel::CodonDistancePhaseFrequenciesSub
     const AlphabetIndex2* pdist) :
   AbstractParameterAliasable("CodonDistPhasFreq."),
   AbstractCodonSubstitutionModel(gCode, pmod1, pmod2, pmod3, "CodonDistPhasFreq."),
-  AbstractCodonDistanceSubstitutionModel(pdist, "CodonDistPhasFreq."),
+  AbstractCodonDistanceSubstitutionModel(pdist, gCode, "CodonDistPhasFreq."),
   AbstractCodonPhaseFrequenciesSubstitutionModel(pfreq, "CodonDistPhasFreq.")
 {
+  computeFrequencies(true);
   updateMatrices();
+  computeFrequencies(false);
 }
 
 std::string CodonDistancePhaseFrequenciesSubstitutionModel::getName() const
@@ -81,7 +85,8 @@ void CodonDistancePhaseFrequenciesSubstitutionModel::fireParameterChanged(const
 {
   AbstractCodonDistanceSubstitutionModel::fireParameterChanged(parameters);
   AbstractCodonPhaseFrequenciesSubstitutionModel::fireParameterChanged(parameters);
-  
+  getFrequencies_()=AbstractCodonPhaseFrequenciesSubstitutionModel::getFrequenciesSet()->getFrequencies();
+
   // Beware: must be call at the end
   AbstractCodonSubstitutionModel::fireParameterChanged(parameters);
 }
@@ -104,4 +109,5 @@ void CodonDistancePhaseFrequenciesSubstitutionModel::setNamespace(const std::str
 void CodonDistancePhaseFrequenciesSubstitutionModel::setFreq(map<int,double>& frequencies)
 {
   AbstractCodonPhaseFrequenciesSubstitutionModel::setFreq(frequencies);
+  getFrequencies_()=AbstractCodonPhaseFrequenciesSubstitutionModel::getFrequenciesSet()->getFrequencies();
 }
diff --git a/src/Bpp/Phyl/Model/Codon/CodonDistancePhaseFrequenciesSubstitutionModel.h b/src/Bpp/Phyl/Model/Codon/CodonDistancePhaseFrequenciesSubstitutionModel.h
index d154f2e..76dfbf3 100644
--- a/src/Bpp/Phyl/Model/Codon/CodonDistancePhaseFrequenciesSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/Codon/CodonDistancePhaseFrequenciesSubstitutionModel.h
@@ -135,6 +135,13 @@ public:
   void setNamespace(const std::string&);
 
   void setFreq(std::map<int,double>& frequencies);
+
+  const FrequenciesSet* getFrequenciesSet() const
+  {
+    return AbstractCodonPhaseFrequenciesSubstitutionModel::getFrequenciesSet();
+  }
+  
+  
 };
 
 } // end of namespace bpp.
diff --git a/src/Bpp/Phyl/Model/Codon/CodonDistanceSubstitutionModel.cpp b/src/Bpp/Phyl/Model/Codon/CodonDistanceSubstitutionModel.cpp
index daf14a1..60c889f 100644
--- a/src/Bpp/Phyl/Model/Codon/CodonDistanceSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/Codon/CodonDistanceSubstitutionModel.cpp
@@ -50,8 +50,9 @@ CodonDistanceSubstitutionModel::CodonDistanceSubstitutionModel(
     const AlphabetIndex2* pdist) :
   AbstractParameterAliasable("CodonDist."),
   AbstractCodonSubstitutionModel(gCode, pmod, "CodonDist."),
-  AbstractCodonDistanceSubstitutionModel(pdist, "CodonDist.")
+  AbstractCodonDistanceSubstitutionModel(pdist, gCode, "CodonDist.")
 {
+  computeFrequencies(true);
   updateMatrices();
 }
 
@@ -63,8 +64,9 @@ CodonDistanceSubstitutionModel::CodonDistanceSubstitutionModel(
     const AlphabetIndex2* pdist) :
   AbstractParameterAliasable("CodonDist."),
   AbstractCodonSubstitutionModel(gCode, pmod1, pmod2, pmod3, "CodonDist."),
-  AbstractCodonDistanceSubstitutionModel(pdist, "CodonDist.")
+  AbstractCodonDistanceSubstitutionModel(pdist, gCode, "CodonDist.")
 {
+  computeFrequencies(true);
   updateMatrices();
 }
 
diff --git a/src/Bpp/Phyl/Model/Codon/CodonDistanceSubstitutionModel.h b/src/Bpp/Phyl/Model/Codon/CodonDistanceSubstitutionModel.h
index 014d20b..fcc5e6a 100644
--- a/src/Bpp/Phyl/Model/Codon/CodonDistanceSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/Codon/CodonDistanceSubstitutionModel.h
@@ -58,7 +58,7 @@ namespace bpp
    * Only substitutions with one letter changed are accepted. </p>
    *
    * If a distance @f$d at f$ between amino-acids is defined, the ratio between
-   * non-synonymous and synonymous substitutions rates is, if the codied
+   * non-synonymous and synonymous substitutions rates is, if the coded
    * amino-acids are @f$x at f$ and @f$y at f$, @f$\beta*\exp(-\alpha.d(x,y))@f$ with
    * non-negative parameter \c "alpha" and positive parameter \c "beta".
    *
diff --git a/src/Bpp/Phyl/Model/Codon/CodonRateFrequenciesSubstitutionModel.cpp b/src/Bpp/Phyl/Model/Codon/CodonRateFrequenciesSubstitutionModel.cpp
deleted file mode 100644
index b26bf4b..0000000
--- a/src/Bpp/Phyl/Model/Codon/CodonRateFrequenciesSubstitutionModel.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-//
-// File: CodonRateFrequenciesSubstitutionModel.cpp
-// Created by:  Laurent Gueguen
-// Created on: lundi 19 septembre 2011, à 12h 20
-//
-
-/*
-  Copyright or © or Copr. CNRS, (November 16, 2004)
-  This software is a computer program whose purpose is to provide classes
-  for phylogenetic data analysis.
-
-  This software is governed by the CeCILL  license under French law and
-  abiding by the rules of distribution of free software.  You can  use,
-  modify and/ or redistribute the software under the terms of the CeCILL
-  license as circulated by CEA, CNRS and INRIA at the following URL
-  "http://www.cecill.info".
-
-  As a counterpart to the access to the source code and  rights to copy,
-  modify and redistribute granted by the license, users are provided only
-  with a limited warranty  and the software's author,  the holder of the
-  economic rights,  and the successive licensors  have only  limited
-  liability.
-
-  In this respect, the user's attention is drawn to the risks associated
-  with loading,  using,  modifying and/or developing or reproducing the
-  software by the user in light of its specific status of free software,
-  that may mean  that it is complicated to manipulate,  and  that  also
-  therefore means  that it is reserved for developers  and  experienced
-  professionals having in-depth computer knowledge. Users are therefore
-  encouraged to load and test the software's suitability as regards their
-  requirements in conditions enabling the security of their systems and/or
-  data to be ensured and,  more generally, to use and operate it in the
-  same conditions as regards security.
-
-  The fact that you are presently reading this means that you have had
-  knowledge of the CeCILL license and that you accept its terms.
-*/
-
-#include "CodonRateFrequenciesSubstitutionModel.h"
-
-using namespace bpp;
-
-using namespace std;
-
-/******************************************************************************/
-
-CodonRateFrequenciesSubstitutionModel::CodonRateFrequenciesSubstitutionModel(
-    const GeneticCode* gCode,
-    NucleotideSubstitutionModel* pmod,
-    FrequenciesSet* pfreq) :
-  AbstractParameterAliasable("CodonRateFreq."),
-  AbstractCodonSubstitutionModel(gCode, pmod, "CodonRateFreq.", true),
-  AbstractCodonFrequenciesSubstitutionModel(pfreq, "CodonRateFreq.")
-{
-  updateMatrices();
-}
-
-CodonRateFrequenciesSubstitutionModel::CodonRateFrequenciesSubstitutionModel(
-    const GeneticCode* gCode,
-    NucleotideSubstitutionModel* pmod1,
-    NucleotideSubstitutionModel* pmod2,
-    NucleotideSubstitutionModel* pmod3,
-    FrequenciesSet* pfreq) :
-  AbstractParameterAliasable("CodonRateFreq."),
-  AbstractCodonSubstitutionModel(gCode, pmod1, pmod2, pmod3, "CodonRateFreq.", true),
-  AbstractCodonFrequenciesSubstitutionModel(pfreq, "CodonRateFreq.")
-{
-  updateMatrices();
-}
-
-std::string CodonRateFrequenciesSubstitutionModel::getName() const
-{
-  return "CodonRateFreq";
-}
-
-void CodonRateFrequenciesSubstitutionModel::fireParameterChanged(const ParameterList& parameters)
-{
-  AbstractCodonFrequenciesSubstitutionModel::fireParameterChanged(parameters);
-
-  // Beware: must be call at the end
-  AbstractCodonSubstitutionModel::fireParameterChanged(parameters);
-}
-
-double CodonRateFrequenciesSubstitutionModel::getCodonsMulRate(size_t i, size_t j) const
-{
-  return AbstractCodonSubstitutionModel::getCodonsMulRate(i,j)
-    * AbstractCodonFrequenciesSubstitutionModel::getCodonsMulRate(i,j);
-}
-
-void CodonRateFrequenciesSubstitutionModel::setNamespace(const std::string& st)
-{
-  AbstractParameterAliasable::setNamespace(st);
-  AbstractCodonSubstitutionModel::setNamespace(st);
-  AbstractCodonFrequenciesSubstitutionModel::setNamespace(st);
-}
-
-void CodonRateFrequenciesSubstitutionModel::setFreq(map<int,double>& frequencies)
-{
-  AbstractCodonFrequenciesSubstitutionModel::setFreq(frequencies);
-}
diff --git a/src/Bpp/Phyl/Model/Codon/CodonRateFrequenciesSubstitutionModel.h b/src/Bpp/Phyl/Model/Codon/CodonRateFrequenciesSubstitutionModel.h
deleted file mode 100644
index 0207314..0000000
--- a/src/Bpp/Phyl/Model/Codon/CodonRateFrequenciesSubstitutionModel.h
+++ /dev/null
@@ -1,124 +0,0 @@
-//
-// File: CodonRateSubstitutionModel.h
-// Created by: Laurent Gueguen
-// Created on: Tue Dec 24 11:03:53 2003
-//
-
-/*
-   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 _CODONRATEFREQUENCIESSUBSTITUTIONMODEL_H_
-#define _CODONRATEFREQUENCIESSUBSTITUTIONMODEL_H_
-
-#include "AbstractCodonSubstitutionModel.h"
-#include "AbstractCodonFrequenciesSubstitutionModel.h"
-
-namespace bpp
-{
-/**
- * @brief Class for substitution models on non stop codons, with
- * different parametrized rates on the models, depending on their
- * phase and defined through a specific equilibrium distribution.
- *
- * @author Laurent Guéguen
- *
- * This class should be used with models which equilibrium
- * distribution is fixed, ans does not depend on the parameters.
- * Otherwise there may be problems of identifiability of the
- * parameters.
- *
- * See description in AbstractCodonRateSubstitutionModel and
- * AbstractCodonFrequenciesSubstitutionModel class.
- *
- */
-class CodonRateFrequenciesSubstitutionModel :
-    public AbstractCodonSubstitutionModel,
-    public AbstractCodonFrequenciesSubstitutionModel
-{
-public:
-  
-  /**
-   * @brief Build a new CodonRateSubstitutionModel object from
-   *  a pointer to NucleotideSubstitutionModels.
-   * @author Laurent Guéguen
-   *
-   * @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
-   */
-  CodonRateFrequenciesSubstitutionModel(
-      const GeneticCode* gCode,
-      NucleotideSubstitutionModel* pmod,
-      FrequenciesSet* pfreq);
-
-  /**
-   * @brief Build a new CodonRateSubstitutionModel object
-   *  from three pointers to NucleotideSubstitutionModels.
-   *
-   * @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
-   */
-
-  CodonRateFrequenciesSubstitutionModel(
-      const GeneticCode* gCode,
-      NucleotideSubstitutionModel* pmod1,
-      NucleotideSubstitutionModel* pmod2,
-      NucleotideSubstitutionModel* pmod3,
-      FrequenciesSet* pfreq);
-
-  virtual ~CodonRateFrequenciesSubstitutionModel(){}
-
-  CodonRateFrequenciesSubstitutionModel* clone() const { return new CodonRateFrequenciesSubstitutionModel(*this); }
-
-public:
-  void fireParameterChanged(const ParameterList& parameterlist);
-  
-  std::string getName() const;
-
-  double getCodonsMulRate(size_t i, size_t j) const;
-
-  void setNamespace(const std::string& st);
-
-  void setFreq(std::map<int,double>& frequencies);
-};
-
-} // end of namespace bpp.
-
-#endif
-
diff --git a/src/Bpp/Phyl/Model/Codon/CodonRateSubstitutionModel.h b/src/Bpp/Phyl/Model/Codon/CodonRateSubstitutionModel.h
deleted file mode 100644
index 341d53e..0000000
--- a/src/Bpp/Phyl/Model/Codon/CodonRateSubstitutionModel.h
+++ /dev/null
@@ -1,107 +0,0 @@
-//
-// File: CodonRateSubstitutionModel.h
-// Created by: Laurent Gueguen
-// Created on: Tue Dec 24 11:03:53 2003
-//
-
-/*
-   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 _CODONRATESUBSTITUTIONMODEL_H_
-#define _CODONRATESUBSTITUTIONMODEL_H_
-
-#include "AbstractCodonSubstitutionModel.h"
-#include "../Nucleotide/NucleotideSubstitutionModel.h"
-
-namespace bpp
-{
-/**
- * @brief Class for substitution models on non stop codons, with
- * different rates on the models, depending on their phase.
- *
- * @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.
-   * @author Laurent Guéguen
-   *
-   * @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 GeneticCode* gCode,
-      NucleotideSubstitutionModel* pmod);
-
-  /**
-   * @brief Build a new CodonRateSubstitutionModel object
-   * from three pointers to NucleotideSubstitutionModels.
-   *
-   * @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);
-
-  virtual ~CodonRateSubstitutionModel() {}
-
-#ifndef NO_VIRTUAL_COV
-  CodonRateSubstitutionModel*
-#else
-  Clonable*
-#endif
-  clone() const { return new CodonRateSubstitutionModel(*this); }
-
-public:
-  std::string getName() 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 d7a6648..e4489c3 100644
--- a/src/Bpp/Phyl/Model/Codon/CodonSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/Codon/CodonSubstitutionModel.h
@@ -42,31 +42,29 @@
 
 //From bpp-seq:
 #include <Bpp/Seq/GeneticCode/GeneticCode.h>
-
-#include "../WordSubstitutionModel.h"
+#include "../SubstitutionModel.h"
 
 namespace bpp
 {
   /**
-   * @brief Abstract class for codon models
+   * @brief Abstract classes for codon models
    * @author Laurent Guéguen
    *
    * This class aims at defining methods needed for inheriting codon.
    *
    */
-  class CodonSubstitutionModel:
-    public virtual SubstitutionModel
+
+  class CoreCodonSubstitutionModel:
+    public virtual ParameterAliasable
   {
   public:
-    CodonSubstitutionModel() {}
-    virtual ~CodonSubstitutionModel() {}
+    CoreCodonSubstitutionModel() {}
+    virtual ~CoreCodonSubstitutionModel() {}
 
-    virtual CodonSubstitutionModel* clone() const = 0;
+    virtual CoreCodonSubstitutionModel* clone() const = 0;
 
   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
@@ -74,6 +72,22 @@ namespace bpp
      * nucleotides.
      */
     virtual double getCodonsMulRate(size_t, size_t) const = 0;
+
+    virtual const FrequenciesSet* getFrequenciesSet() const = 0;
+  };
+
+
+  class CodonSubstitutionModel:
+    public virtual CoreCodonSubstitutionModel,
+    public virtual SubstitutionModel
+  {
+  public:
+    CodonSubstitutionModel() {}
+    virtual ~CodonSubstitutionModel() {}
+
+    virtual CodonSubstitutionModel* clone() const = 0;
+    
+    virtual const GeneticCode* getGeneticCode() const = 0;
   };
   
   
diff --git a/src/Bpp/Phyl/Model/Codon/GY94.h b/src/Bpp/Phyl/Model/Codon/GY94.h
index fabea3a..cb4eb14 100644
--- a/src/Bpp/Phyl/Model/Codon/GY94.h
+++ b/src/Bpp/Phyl/Model/Codon/GY94.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 _GY94_H_
@@ -79,39 +79,38 @@ namespace bpp
  * Reference:
  * - Goldman N. and Yang Z. (1994), _Molecular Biology And Evolution_ 11(5) 725--736. 
  */
-class GY94:
+  class GY94:
     public AbstractBiblioSubstitutionModel,
     virtual public ReversibleSubstitutionModel
-{
-private:
+  {
+  private:
 
-  GranthamAAChemicalDistance gacd_;
-  std::unique_ptr<CodonDistanceFrequenciesSubstitutionModel> pmodel_;
+    GranthamAAChemicalDistance gacd_;
+    std::unique_ptr<CodonDistanceFrequenciesSubstitutionModel> pmodel_;
 
-public:
-  GY94(const GeneticCode* gc, FrequenciesSet* codonFreqs);
+  public:
+    GY94(const GeneticCode* gc, FrequenciesSet* codonFreqs);
        
-  ~GY94();
+    ~GY94();
 
-  GY94(const GY94& gy94);
+    GY94(const GY94& gy94);
   
-  GY94& operator=(const GY94& gy94);
+    GY94& operator=(const GY94& gy94);
 
-#ifndef NOVIRTUAL_COV_
-  GY94* 
-#else
-  Clonable*
-#endif
-  clone() const { return new GY94(*this); }
+    GY94* clone() const { return new GY94(*this); }
 
-public:
+  public:
 
-  std::string getName() const { return "GY94"; }
+    std::string getName() const { return "GY94"; }
 	
-  const SubstitutionModel& getModel() const { return *pmodel_.get(); }
+    const SubstitutionModel& getSubstitutionModel() 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(); }
+  protected:
+  SubstitutionModel& getSubstitutionModel() { return *pmodel_.get(); }
 
 };
 
diff --git a/src/Bpp/Phyl/Model/Codon/KCM.h b/src/Bpp/Phyl/Model/Codon/KCM.h
index 0d2ac79..f002f5e 100644
--- a/src/Bpp/Phyl/Model/Codon/KCM.h
+++ b/src/Bpp/Phyl/Model/Codon/KCM.h
@@ -103,14 +103,19 @@ namespace bpp
   public:
     std::string getName() const { return "KCM"+std::string(oneModel_?"7":"19")+".";}
 
-    const SubstitutionModel& getModel() const { return *pmodel_.get(); }
+    const SubstitutionModel& getSubstitutionModel() 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(); }
+  protected:
+    SubstitutionModel& getSubstitutionModel() { return *pmodel_.get(); }
+
+    const FrequenciesSet* getFrequenciesSet() const {
+      return 0;
+    }
+
   };
 
 } // end of namespace bpp.
diff --git a/src/Bpp/Phyl/Model/Codon/KroneckerCodonDistanceFrequenciesSubstitutionModel.cpp b/src/Bpp/Phyl/Model/Codon/KroneckerCodonDistanceFrequenciesSubstitutionModel.cpp
index 8ed8e3e..78d2bc2 100644
--- a/src/Bpp/Phyl/Model/Codon/KroneckerCodonDistanceFrequenciesSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/Codon/KroneckerCodonDistanceFrequenciesSubstitutionModel.cpp
@@ -51,9 +51,10 @@ KroneckerCodonDistanceFrequenciesSubstitutionModel::KroneckerCodonDistanceFreque
     const AlphabetIndex2* pdist) :
   AbstractParameterAliasable("KronCodonDistFreq."),
   AbstractKroneckerCodonSubstitutionModel(gCode, pmod, "KronCodonDistFreq."),
-  AbstractCodonDistanceSubstitutionModel(pdist, "KronCodonDistFreq."),
+  AbstractCodonDistanceSubstitutionModel(pdist, gCode, "KronCodonDistFreq."),
   AbstractCodonFrequenciesSubstitutionModel(pfreq, "KronCodonDistFreq.")
 {
+  computeFrequencies(false);
   updateMatrices();
 }
 
@@ -65,9 +66,10 @@ KroneckerCodonDistanceFrequenciesSubstitutionModel::KroneckerCodonDistanceFreque
   const AlphabetIndex2* pdist) :
   AbstractParameterAliasable("KronCodonDistFreq."),
   AbstractKroneckerCodonSubstitutionModel(gCode, pmod, vPos, "KronCodonDistFreq."),
-  AbstractCodonDistanceSubstitutionModel(pdist, "KronCodonDistFreq."),
+  AbstractCodonDistanceSubstitutionModel(pdist, gCode, "KronCodonDistFreq."),
   AbstractCodonFrequenciesSubstitutionModel(pfreq, "KronCodonDistFreq.")
 {
+  computeFrequencies(false);
   updateMatrices();
 }
 
@@ -80,9 +82,10 @@ KroneckerCodonDistanceFrequenciesSubstitutionModel::KroneckerCodonDistanceFreque
     const AlphabetIndex2* pdist) :
   AbstractParameterAliasable("KronCodonDistFreq."),
   AbstractKroneckerCodonSubstitutionModel(gCode, pmod1, pmod2, pmod3, "KronCodonDistFreq."),
-  AbstractCodonDistanceSubstitutionModel(pdist, "KronCodonDistFreq."),
+  AbstractCodonDistanceSubstitutionModel(pdist, gCode, "KronCodonDistFreq."),
   AbstractCodonFrequenciesSubstitutionModel(pfreq, "KronCodonDistFreq.")
 {
+  computeFrequencies(false);
   updateMatrices();
 }
 
@@ -96,9 +99,10 @@ KroneckerCodonDistanceFrequenciesSubstitutionModel::KroneckerCodonDistanceFreque
   const AlphabetIndex2* pdist) :
   AbstractParameterAliasable("KronCodonDistFreq."),
   AbstractKroneckerCodonSubstitutionModel(gCode, pmod1, pmod2, pmod3, vPos, "KronCodonDistFreq."),
-  AbstractCodonDistanceSubstitutionModel(pdist, "KronCodonDistFreq."),
+  AbstractCodonDistanceSubstitutionModel(pdist, gCode, "KronCodonDistFreq."),
   AbstractCodonFrequenciesSubstitutionModel(pfreq, "KronCodonDistFreq.")
 {
+  computeFrequencies(false);
   updateMatrices();
 }
 
diff --git a/src/Bpp/Phyl/Model/Codon/KroneckerCodonDistanceFrequenciesSubstitutionModel.h b/src/Bpp/Phyl/Model/Codon/KroneckerCodonDistanceFrequenciesSubstitutionModel.h
index 9cd3667..4e2f0fd 100644
--- a/src/Bpp/Phyl/Model/Codon/KroneckerCodonDistanceFrequenciesSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/Codon/KroneckerCodonDistanceFrequenciesSubstitutionModel.h
@@ -202,6 +202,11 @@ public:
 
   void setFreq(std::map<int,double>& frequencies);
 
+  const FrequenciesSet* getFrequenciesSet() const {
+    return AbstractCodonFrequenciesSubstitutionModel::getFrequenciesSet();
+  }
+
+
 };
 
 } // end of namespace bpp.
diff --git a/src/Bpp/Phyl/Model/Codon/KroneckerCodonDistanceSubstitutionModel.cpp b/src/Bpp/Phyl/Model/Codon/KroneckerCodonDistanceSubstitutionModel.cpp
index 2840948..bf007e0 100644
--- a/src/Bpp/Phyl/Model/Codon/KroneckerCodonDistanceSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/Codon/KroneckerCodonDistanceSubstitutionModel.cpp
@@ -50,8 +50,9 @@ KroneckerCodonDistanceSubstitutionModel::KroneckerCodonDistanceSubstitutionModel
     const AlphabetIndex2* pdist) :
   AbstractParameterAliasable("KronCodonDist."),
   AbstractKroneckerCodonSubstitutionModel(gCode, pmod, "KronCodonDist."),
-  AbstractCodonDistanceSubstitutionModel(pdist, "KronCodonDist.")
+  AbstractCodonDistanceSubstitutionModel(pdist, gCode, "KronCodonDist.")
 {
+  computeFrequencies(true);
   updateMatrices();
 }
 
@@ -63,8 +64,9 @@ KroneckerCodonDistanceSubstitutionModel::KroneckerCodonDistanceSubstitutionModel
     const AlphabetIndex2* pdist) :
   AbstractParameterAliasable("KronCodonDist."),
   AbstractKroneckerCodonSubstitutionModel(gCode, pmod1, pmod2, pmod3, "KronCodonDist."),
-  AbstractCodonDistanceSubstitutionModel(pdist, "KronCodonDist.")
+  AbstractCodonDistanceSubstitutionModel(pdist, gCode, "KronCodonDist.")
 {
+  computeFrequencies(true);
   updateMatrices();
 }
 
@@ -75,8 +77,9 @@ KroneckerCodonDistanceSubstitutionModel::KroneckerCodonDistanceSubstitutionModel
   const AlphabetIndex2* pdist) :
   AbstractParameterAliasable("KronCodonDist."),
   AbstractKroneckerCodonSubstitutionModel(gCode, pmod, vPos, "KronCodonDist."),
-  AbstractCodonDistanceSubstitutionModel(pdist, "KronCodonDist.")
+  AbstractCodonDistanceSubstitutionModel(pdist, gCode, "KronCodonDist.")
 {
+  computeFrequencies(true);
   updateMatrices();
 }
 
@@ -89,8 +92,9 @@ KroneckerCodonDistanceSubstitutionModel::KroneckerCodonDistanceSubstitutionModel
   const AlphabetIndex2* pdist) :
   AbstractParameterAliasable("KronCodonDist."),
   AbstractKroneckerCodonSubstitutionModel(gCode, pmod1, pmod2, pmod3, vPos, "KronCodonDist."),
-  AbstractCodonDistanceSubstitutionModel(pdist, "KronCodonDist.")
+  AbstractCodonDistanceSubstitutionModel(pdist, gCode, "KronCodonDist.")
 {
+  computeFrequencies(true);
   updateMatrices();
 }
 std::string KroneckerCodonDistanceSubstitutionModel::getName() const
diff --git a/src/Bpp/Phyl/Model/Codon/MG94.h b/src/Bpp/Phyl/Model/Codon/MG94.h
index ff0ed43..7152523 100644
--- a/src/Bpp/Phyl/Model/Codon/MG94.h
+++ b/src/Bpp/Phyl/Model/Codon/MG94.h
@@ -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. 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 _MG94_H_
 #define _MG94_H_
@@ -74,37 +74,39 @@ namespace bpp
  * Reference:
  * - Muse S.V. and Gaut B.S. (1994), Molecular_ Biology And Evolution_ 11(5) 715--724.
  */
-class MG94 :
+  class MG94 :
     public AbstractBiblioSubstitutionModel,
     virtual public CodonReversibleSubstitutionModel
-{
-private:
-  std::unique_ptr<CodonDistancePhaseFrequenciesSubstitutionModel> pmodel_;
+  {
+  private:
+    std::unique_ptr<CodonDistancePhaseFrequenciesSubstitutionModel> pmodel_;
 
-public:
-  MG94(const GeneticCode* gc, FrequenciesSet* codonFreqs);
+  public:
+    MG94(const GeneticCode* gc, FrequenciesSet* codonFreqs);
 
-  MG94(const MG94& mg94);
+    MG94(const MG94& mg94);
 
-  MG94& operator=(const MG94& mg94);
+    MG94& operator=(const MG94& mg94);
 
-  ~MG94();
+    ~MG94();
 
-  MG94* clone() const { return new MG94(*this); }
+    MG94* clone() const { return new MG94(*this); }
 
-public:
-  std::string getName() const { return "MG94"; }
+  public:
+    std::string getName() const { return "MG94"; }
 
-  const SubstitutionModel& getModel() const { return *pmodel_.get(); }
+    const SubstitutionModel& getSubstitutionModel() const { return *pmodel_.get(); }
 
-  const GeneticCode* getGeneticCode() const { return pmodel_->getGeneticCode(); }
+    const GeneticCode* getGeneticCode() const { return pmodel_->getGeneticCode(); }
   
-  double getCodonsMulRate(size_t i, size_t j) const { return pmodel_->getCodonsMulRate(i, j); }
+    double getCodonsMulRate(size_t i, size_t j) const { return pmodel_->getCodonsMulRate(i, j); }
+
+    const FrequenciesSet* getFrequenciesSet() const { return pmodel_->getFrequenciesSet();}
 
-private:
-  SubstitutionModel& getModel() { return *pmodel_.get(); }
+  protected:
+    SubstitutionModel& getSubstitutionModel() { return *pmodel_.get(); }
 
-};
+  };
 
 } // end of namespace bpp.
 
diff --git a/src/Bpp/Phyl/Model/Codon/SENCA.cpp b/src/Bpp/Phyl/Model/Codon/SENCA.cpp
index 40dd52f..8e79b6f 100644
--- a/src/Bpp/Phyl/Model/Codon/SENCA.cpp
+++ b/src/Bpp/Phyl/Model/Codon/SENCA.cpp
@@ -43,30 +43,32 @@ using namespace bpp;
 using namespace std;
 
 SENCA::SENCA(
-    const GeneticCode* gCode,
-    NucleotideSubstitutionModel* pmod,
-    FrequenciesSet* pfit,
-    const AlphabetIndex2* pdist) :
+  const GeneticCode* gCode,
+  NucleotideSubstitutionModel* pmod,
+  FrequenciesSet* pfit,
+  const AlphabetIndex2* pdist) :
   AbstractParameterAliasable("SENCA."),
   AbstractCodonSubstitutionModel(gCode, pmod, "SENCA."),
-  AbstractCodonDistanceSubstitutionModel(pdist, "SENCA."),
-  AbstractCodonFitnessSubstitutionModel(pfit, "SENCA.")
+  AbstractCodonDistanceSubstitutionModel(pdist, gCode, "SENCA."),
+  AbstractCodonFitnessSubstitutionModel(pfit, gCode, "SENCA.")
 {
+  computeFrequencies(true);  
   updateMatrices();
 }
 
 SENCA::SENCA(
-    const GeneticCode* gCode,
-    NucleotideSubstitutionModel* pmod1,
-    NucleotideSubstitutionModel* pmod2,
-    NucleotideSubstitutionModel* pmod3,
-    FrequenciesSet* pfit,
-    const AlphabetIndex2* pdist) :
+  const GeneticCode* gCode,
+  NucleotideSubstitutionModel* pmod1,
+  NucleotideSubstitutionModel* pmod2,
+  NucleotideSubstitutionModel* pmod3,
+  FrequenciesSet* pfit,
+  const AlphabetIndex2* pdist) :
   AbstractParameterAliasable("SENCA."),
   AbstractCodonSubstitutionModel(gCode, pmod1, pmod2, pmod3, "SENCA."),
-  AbstractCodonDistanceSubstitutionModel(pdist, "SENCA."),
-  AbstractCodonFitnessSubstitutionModel(pfit,"SENCA.")
+  AbstractCodonDistanceSubstitutionModel(pdist, gCode, "SENCA."),
+  AbstractCodonFitnessSubstitutionModel(pfit, gCode, "SENCA.")
 {
+  computeFrequencies(true);
   updateMatrices();
 }
 
diff --git a/src/Bpp/Phyl/Model/Codon/SENCA.h b/src/Bpp/Phyl/Model/Codon/SENCA.h
index a4b0b07..709d04d 100644
--- a/src/Bpp/Phyl/Model/Codon/SENCA.h
+++ b/src/Bpp/Phyl/Model/Codon/SENCA.h
@@ -72,8 +72,11 @@ namespace bpp
    * FrequenciesSet object. The parameters are named \c
    * "fit_NameOfTheParameterInTheFrequenciesSet".
    *
+   * Note: equilibrium frequencies are computed from the generator. To
+   * be done : implement analytic computation.
+   *
    * Reference:
-   * -  Yang Z. and Nielsen R. (2008), _Molecular Biology and Evolution_ 25(3):568--579.
+   * - Pouyet & al, Genome Biology and Evolution, 2016
    */
   
   class SENCA :
@@ -84,17 +87,17 @@ namespace bpp
   {
   public:
     SENCA(
-        const GeneticCode* gCode,
-        NucleotideSubstitutionModel* pmod,
-        FrequenciesSet* pfit,
-        const AlphabetIndex2* pdist = 0);
+      const GeneticCode* gCode,
+      NucleotideSubstitutionModel* pmod,
+      FrequenciesSet* pfit,
+      const AlphabetIndex2* pdist = 0);
     SENCA(
-        const GeneticCode* gCode,
-        NucleotideSubstitutionModel* pmod1,
-        NucleotideSubstitutionModel* pmod2,
-        NucleotideSubstitutionModel* pmod3,
-        FrequenciesSet* pfit,
-        const AlphabetIndex2* pdist = 0);
+      const GeneticCode* gCode,
+      NucleotideSubstitutionModel* pmod1,
+      NucleotideSubstitutionModel* pmod2,
+      NucleotideSubstitutionModel* pmod3,
+      FrequenciesSet* pfit,
+      const AlphabetIndex2* pdist = 0);
 
     virtual ~SENCA() {}
 
@@ -126,6 +129,10 @@ namespace bpp
      */
     void setFreq(std::map<int,double>& frequencies);
 
+    const FrequenciesSet* getFrequenciesSet() const {
+      return AbstractCodonFitnessSubstitutionModel::getFrequenciesSet();
+    }
+
   };
 
 } // end of namespace bpp.
diff --git a/src/Bpp/Phyl/Model/Codon/TripletSubstitutionModel.h b/src/Bpp/Phyl/Model/Codon/TripletSubstitutionModel.h
index 60f50b9..edf6bfe 100644
--- a/src/Bpp/Phyl/Model/Codon/TripletSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/Codon/TripletSubstitutionModel.h
@@ -75,7 +75,7 @@ public:
    */
   
   TripletSubstitutionModel(const CodonAlphabet* palph,
-                                     NucleotideSubstitutionModel* pmod);
+                           NucleotideSubstitutionModel* pmod);
   
   /**
    *@brief Build a new TripletSubstitutionModel object
@@ -90,10 +90,10 @@ public:
    */
 
   TripletSubstitutionModel(const CodonAlphabet* palph,
-                                     NucleotideSubstitutionModel* pmod1,
-                                     NucleotideSubstitutionModel* pmod2, 
-                                     NucleotideSubstitutionModel* pmod3);
-
+                           NucleotideSubstitutionModel* pmod1,
+                           NucleotideSubstitutionModel* pmod2, 
+                           NucleotideSubstitutionModel* pmod3);
+  
   ~TripletSubstitutionModel() {};
   
   TripletSubstitutionModel* clone() const { return new TripletSubstitutionModel(*this);}
diff --git a/src/Bpp/Phyl/Model/Codon/YN98.cpp b/src/Bpp/Phyl/Model/Codon/YN98.cpp
index dce5ea5..df42865 100644
--- a/src/Bpp/Phyl/Model/Codon/YN98.cpp
+++ b/src/Bpp/Phyl/Model/Codon/YN98.cpp
@@ -52,6 +52,8 @@ YN98::YN98(const GeneticCode* gc, FrequenciesSet* codonFreqs) :
   AbstractBiblioSubstitutionModel("YN98."),
   pmodel_(new CodonDistanceFrequenciesSubstitutionModel(gc, new K80(dynamic_cast<const CodonAlphabet*>(gc->getSourceAlphabet())->getNucleicAlphabet()), codonFreqs))
 {
+  computeFrequencies(false);
+  
   addParameter_(new Parameter("YN98.kappa", 1, &Parameter::R_PLUS_STAR));
   addParameter_(new Parameter("YN98.omega", 1, new IntervalConstraint(NumConstants::MILLI(), 999, true, true), true));
 
diff --git a/src/Bpp/Phyl/Model/Codon/YN98.h b/src/Bpp/Phyl/Model/Codon/YN98.h
index d712cb8..5233f99 100644
--- a/src/Bpp/Phyl/Model/Codon/YN98.h
+++ b/src/Bpp/Phyl/Model/Codon/YN98.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 _YN98_H_
 #define _YN98_H_
@@ -85,37 +85,39 @@ namespace bpp
  * Reference:
  * -  Yang Z. and Nielsen R. (1998), _Journal of Molecular Evolution_ 46:409--418.
  */
-class YN98 :
+  class YN98 :
     public AbstractBiblioSubstitutionModel,
     public virtual CodonReversibleSubstitutionModel
-{
-private:
-  std::unique_ptr<CodonDistanceFrequenciesSubstitutionModel> pmodel_;
+  {
+  private:
+    std::unique_ptr<CodonDistanceFrequenciesSubstitutionModel> pmodel_;
 
-public:
-  YN98(const GeneticCode* gc, FrequenciesSet* codonFreqs);
+  public:
+    YN98(const GeneticCode* gc, FrequenciesSet* codonFreqs);
 
-  YN98(const YN98& yn98);
+    YN98(const YN98& yn98);
 
-  YN98& operator=(const YN98&);
+    YN98& operator=(const YN98&);
 
-  virtual ~YN98() {}
+    virtual ~YN98() {}
 
-  YN98* clone() const { return new YN98(*this); }
+    YN98* clone() const { return new YN98(*this); }
 
-public:
-  std::string getName() const { return "YN98"; }
+  public:
+    std::string getName() const { return "YN98"; }
 
-  const SubstitutionModel& getModel() const { return *pmodel_.get(); }
+    const SubstitutionModel& getSubstitutionModel() const { return *pmodel_.get(); }
 
-  const GeneticCode* getGeneticCode() const { return pmodel_->getGeneticCode(); }
+    const GeneticCode* getGeneticCode() const { return pmodel_->getGeneticCode(); }
   
-  double getCodonsMulRate(size_t i, size_t j) const { return pmodel_->getCodonsMulRate(i, j); }
+    double getCodonsMulRate(size_t i, size_t j) const { return pmodel_->getCodonsMulRate(i, j); }
+
+    const FrequenciesSet* getFrequenciesSet() const { return pmodel_->getFrequenciesSet();}
 
-private:
-  SubstitutionModel& getModel() { return *pmodel_.get(); }
+  protected:
+    SubstitutionModel& getSubstitutionModel() { return *pmodel_.get(); }
 
-};
+  };
 
 } // end of namespace bpp.
 
diff --git a/src/Bpp/Phyl/Model/Codon/CodonSubstitutionModel.h b/src/Bpp/Phyl/Model/Codon/YNGP_M.h
similarity index 50%
copy from src/Bpp/Phyl/Model/Codon/CodonSubstitutionModel.h
copy to src/Bpp/Phyl/Model/Codon/YNGP_M.h
index d7a6648..b00a1a9 100644
--- a/src/Bpp/Phyl/Model/Codon/CodonSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/Codon/YNGP_M.h
@@ -1,7 +1,7 @@
 //
-// File: CodonSubstitutionModel.h
+// File: YNGP_M.h
 // Created by: Laurent Gueguen
-// Created on: Tue Dec 24 11:03:53 2003
+// Created on: mardi 26 septembre 2017, à 23h 06
 //
 
 /*
@@ -11,16 +11,16 @@
   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,
+  abiding by the rules of distribution of free software.  You can  use, 
   modify and/ or redistribute the software under the terms of the CeCILL
   license as circulated by CEA, CNRS and INRIA at the following URL
-  "http://www.cecill.info".
+  "http://www.cecill.info". 
 
   As a counterpart to the access to the source code and  rights to copy,
   modify and redistribute granted by the license, users are provided only
   with a limited warranty  and the software's author,  the holder of the
   economic rights,  and the successive licensors  have only  limited
-  liability.
+  liability. 
 
   In this respect, the user's attention is drawn to the risks associated
   with loading,  using,  modifying and/or developing or reproducing the
@@ -29,70 +29,82 @@
   therefore means  that it is reserved for developers  and  experienced
   professionals having in-depth computer knowledge. Users are therefore
   encouraged to load and test the software's suitability as regards their
-  requirements in conditions enabling the security of their systems and/or
-  data to be ensured and,  more generally, to use and operate it in the
-  same conditions as regards security.
+  requirements in conditions enabling the security of their systems and/or 
+  data to be ensured and,  more generally, to use and operate it in the 
+  same conditions as regards security. 
 
   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 _CODONSUBSTITUTIONMODEL_H_
-#define _CODONSUBSTITUTIONMODEL_H_
+#ifndef _YNGP_M_H_
+#define _YNGP_M_H_
 
-//From bpp-seq:
-#include <Bpp/Seq/GeneticCode/GeneticCode.h>
+#include "../AbstractBiblioMixedSubstitutionModel.h"
+#include "../FrequenciesSet/CodonFrequenciesSet.h"
 
-#include "../WordSubstitutionModel.h"
+#include <Bpp/Seq/GeneticCode/GeneticCode.h>
 
 namespace bpp
 {
-  /**
-   * @brief Abstract class for codon models
-   * @author Laurent Guéguen
-   *
-   * This class aims at defining methods needed for inheriting codon.
-   *
-   */
-  class CodonSubstitutionModel:
-    public virtual SubstitutionModel
-  {
-  public:
-    CodonSubstitutionModel() {}
-    virtual ~CodonSubstitutionModel() {}
-
-    virtual CodonSubstitutionModel* clone() const = 0;
-
-  public:
-
-    virtual const GeneticCode* getGeneticCode() const = 0;
 
+/**
+ * @brief Abstract generic class for The Yang et al (2000) M
+ * substitution models for codons. al (2004). @author Laurent Guéguen
+ *
+ * References:
+ *
+ * Yang, Z., R. Nielsen, N. Goldman, and A.-M. K. Pedersen (2000)
+ * Genetics 155:431-449.
+ * 
+ * Wong, W. S. W., Z. Yang, N. Goldman, and R. Nielsen. (2004)
+ * Genetics 168:1041--1051.
+ */
+
+  class YNGP_M:
+    public AbstractBiblioMixedSubstitutionModel,
+    virtual public ReversibleSubstitutionModel
+  {
+  protected:
     /**
-     * @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.
+     * @brief indexes of 2 codons states between which the substitution is
+     * synonymous, to set a basis to the homogeneization of the rates.
+     *
      */
-    virtual double getCodonsMulRate(size_t, size_t) const = 0;
-  };
+    size_t synfrom_, synto_;
   
-  
-  /**
-   * @brief Abstract class for reversible codon models
-   * @author Julien Dutheil
-   */
-  class CodonReversibleSubstitutionModel:
-    public virtual CodonSubstitutionModel,
-    public virtual ReversibleSubstitutionModel 
-  {
   public:
-    CodonReversibleSubstitutionModel() {}
-    virtual ~CodonReversibleSubstitutionModel() {}
-
-    virtual CodonReversibleSubstitutionModel* clone() const = 0;
+    YNGP_M(const std::string& name) :
+      AbstractBiblioMixedSubstitutionModel(name),
+      synfrom_(),
+      synto_()
+    {
+      computeFrequencies(false);
+    }
+    
+    YNGP_M(const YNGP_M& mod2) :
+      AbstractBiblioMixedSubstitutionModel(mod2),
+      synfrom_(mod2.synfrom_),
+      synto_(mod2.synto_)
+    {
+      computeFrequencies(false);
+    }
+
+    virtual YNGP_M* clone() const = 0;
+    
+    YNGP_M& operator=(const YNGP_M& mod2)
+    {
+      AbstractBiblioMixedSubstitutionModel::operator=(mod2);
+
+      synfrom_ = mod2.synfrom_;
+      synto_ = mod2.synto_;
+
+      return *this;
+    }
+    
   };
 
-} // end of namespace bpp.
+} //end of namespace bpp.
 
-#endif
+#endif	//_YNGP_M_H_
 
diff --git a/src/Bpp/Phyl/Model/Codon/YNGP_M1.cpp b/src/Bpp/Phyl/Model/Codon/YNGP_M1.cpp
index 7d3d7a0..734c5f2 100644
--- a/src/Bpp/Phyl/Model/Codon/YNGP_M1.cpp
+++ b/src/Bpp/Phyl/Model/Codon/YNGP_M1.cpp
@@ -42,6 +42,8 @@
 #include <Bpp/Numeric/NumConstants.h>
 #include <Bpp/Numeric/Prob/SimpleDiscreteDistribution.h>
 
+#include "../MixtureOfASubstitutionModel.h"
+
 using namespace bpp;
 
 using namespace std;
@@ -49,10 +51,7 @@ using namespace std;
 /******************************************************************************/
 
 YNGP_M1::YNGP_M1(const GeneticCode* gc, FrequenciesSet* codonFreqs) :
-  AbstractBiblioMixedSubstitutionModel("YNGP_M1."),
-  pmixmodel_(),
-  synfrom_(),
-  synto_()
+  YNGP_M("YNGP_M1.")
 {
   // build the submodel
 
@@ -124,25 +123,6 @@ YNGP_M1::YNGP_M1(const GeneticCode* gc, FrequenciesSet* codonFreqs) :
   updateMatrices();
 }
 
-YNGP_M1::YNGP_M1(const YNGP_M1& mod2) : AbstractBiblioMixedSubstitutionModel(mod2),
-  pmixmodel_(new MixtureOfASubstitutionModel(*mod2.pmixmodel_)),
-  synfrom_(mod2.synfrom_),
-  synto_(mod2.synto_)
-{}
-
-YNGP_M1& YNGP_M1::operator=(const YNGP_M1& mod2)
-{
-  AbstractBiblioSubstitutionModel::operator=(mod2);
-
-  pmixmodel_.reset(new MixtureOfASubstitutionModel(*mod2.pmixmodel_));
-  synfrom_ = mod2.synfrom_;
-  synto_ = mod2.synto_;
-
-  return *this;
-}
-
-YNGP_M1::~YNGP_M1() {}
-
 void YNGP_M1::updateMatrices()
 {
   AbstractBiblioSubstitutionModel::updateMatrices();
diff --git a/src/Bpp/Phyl/Model/Codon/YNGP_M1.h b/src/Bpp/Phyl/Model/Codon/YNGP_M1.h
index a5bac47..e750a03 100644
--- a/src/Bpp/Phyl/Model/Codon/YNGP_M1.h
+++ b/src/Bpp/Phyl/Model/Codon/YNGP_M1.h
@@ -5,47 +5,42 @@
 //
 
 /*
-Copyright or © or Copr. Bio++ Development Team, (November 16, 2004)
-
-This software is a computer program whose purpose is to provide classes
-for phylogenetic data analysis.
-
-This software is governed by the CeCILL  license under French law and
-abiding by the rules of distribution of free software.  You can  use, 
-modify and/ or redistribute the software under the terms of the CeCILL
-license as circulated by CEA, CNRS and INRIA at the following URL
-"http://www.cecill.info". 
-
-As a counterpart to the access to the source code and  rights to copy,
-modify and redistribute granted by the license, users are provided only
-with a limited warranty  and the software's author,  the holder of the
-economic rights,  and the successive licensors  have only  limited
-liability. 
-
-In this respect, the user's attention is drawn to the risks associated
-with loading,  using,  modifying and/or developing or reproducing the
-software by the user in light of its specific status of free software,
-that may mean  that it is complicated to manipulate,  and  that  also
-therefore means  that it is reserved for developers  and  experienced
-professionals having in-depth computer knowledge. Users are therefore
-encouraged to load and test the software's suitability as regards their
-requirements in conditions enabling the security of their systems and/or 
-data to be ensured and,  more generally, to use and operate it in the 
-same conditions as regards security. 
-
-The fact that you are presently reading this means that you have had
-knowledge of the CeCILL license and that you accept its terms.
+  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 _YNGP_M1_H_
 #define _YNGP_M1_H_
 
-#include "../AbstractBiblioMixedSubstitutionModel.h"
-#include "../MixtureOfASubstitutionModel.h"
-#include "../FrequenciesSet/CodonFrequenciesSet.h"
-
-#include <Bpp/Seq/GeneticCode/GeneticCode.h>
-
+#include "YNGP_M.h"
 namespace bpp
 {
 
@@ -76,49 +71,32 @@ namespace bpp
  * Wong, W. S. W., Z. Yang, N. Goldman, and R. Nielsen. (2004)
  * Genetics 168:1041--1051.
  */
-class YNGP_M1:
-    public AbstractBiblioMixedSubstitutionModel,
-    virtual public ReversibleSubstitutionModel
-{
-private:
-  std::unique_ptr<MixtureOfASubstitutionModel> pmixmodel_;
-
-
-  /**
-   * @brief indexes of 2 codons states between which the substitution is
-   * synonymous, to set a basis to the homogeneization of the rates.
-   *
-   */
-  size_t synfrom_, synto_;
-  
-public:
-  YNGP_M1(const GeneticCode* gc, FrequenciesSet* codonFreqs);
-
-  virtual ~YNGP_M1();
-  
-  YNGP_M1* clone() const { return new YNGP_M1(*this); }
-
-  YNGP_M1(const YNGP_M1&);
-
-  YNGP_M1& operator=(const YNGP_M1&);
-
-protected:
-  void updateMatrices();
-
-public:
-  const SubstitutionModel& getModel() const { return *pmixmodel_.get(); }
-
-  const MixedSubstitutionModel& getMixedModel() const { return *pmixmodel_.get(); }
-
-  std::string getName() const { return "YNGP_M1"; }
-
-private:
-  SubstitutionModel& getModel() { return *pmixmodel_.get(); }
-  
-  MixedSubstitutionModel& getMixedModel() { return *pmixmodel_.get(); }
-
-  const FrequenciesSet* getFrequenciesSet() const {return pmixmodel_->getNModel(1)->getFrequenciesSet();}
-};
+  class YNGP_M1:
+    public YNGP_M
+  {
+  public:
+    YNGP_M1(const GeneticCode* gc, FrequenciesSet* codonFreqs);
+
+    YNGP_M1* clone() const { return new YNGP_M1(*this); }
+
+    YNGP_M1(const YNGP_M1& mod2) :
+      YNGP_M(mod2)
+    {
+    }
+
+    YNGP_M1& operator=(const YNGP_M1& mod2)
+    {
+      YNGP_M::operator=(mod2);
+      return *this;
+    }
+    
+  protected:
+    void updateMatrices();
+
+  public:
+    std::string getName() const { return "YNGP_M1"; }
+
+  };
 
 } //end of namespace bpp.
 
diff --git a/src/Bpp/Phyl/Model/Codon/YNGP_M10.cpp b/src/Bpp/Phyl/Model/Codon/YNGP_M10.cpp
index e655bc7..cd7e4ef 100644
--- a/src/Bpp/Phyl/Model/Codon/YNGP_M10.cpp
+++ b/src/Bpp/Phyl/Model/Codon/YNGP_M10.cpp
@@ -38,6 +38,7 @@
 
 #include "YNGP_M10.h"
 #include "YN98.h"
+#include "../MixtureOfASubstitutionModel.h"
 
 #include <Bpp/Numeric/Prob/MixtureOfDiscreteDistributions.h>
 #include <Bpp/Numeric/Prob/BetaDiscreteDistribution.h>
@@ -51,10 +52,7 @@ using namespace std;
 /******************************************************************************/
 
 YNGP_M10::YNGP_M10(const GeneticCode* gc, FrequenciesSet* codonFreqs, unsigned int nbBeta, unsigned int nbGamma) :
-  AbstractBiblioMixedSubstitutionModel("YNGP_M10."),
-  pmixmodel_(),
-  synfrom_(),
-  synto_(),
+  YNGP_M("YNGP_M10."),
   nBeta_(nbBeta),
   nGamma_(nbGamma)
 {
@@ -139,31 +137,6 @@ YNGP_M10::YNGP_M10(const GeneticCode* gc, FrequenciesSet* codonFreqs, unsigned i
   updateMatrices();
 }
 
-YNGP_M10::YNGP_M10(const YNGP_M10& mod2) : AbstractBiblioMixedSubstitutionModel(mod2),
-                                           pmixmodel_(new MixtureOfASubstitutionModel(*mod2.pmixmodel_)),
-                                           synfrom_(mod2.synfrom_),
-                                           synto_(mod2.synto_),
-                                           nBeta_(mod2.nBeta_),
-                                           nGamma_(mod2.nGamma_)
-
-{}
-
-
-YNGP_M10& YNGP_M10::operator=(const YNGP_M10& mod2)
-{
-  AbstractBiblioMixedSubstitutionModel::operator=(mod2);
-
-  pmixmodel_.reset(new MixtureOfASubstitutionModel(*mod2.pmixmodel_));
-  synfrom_ = mod2.synfrom_;
-  synto_ = mod2.synto_;
-  nBeta_ = mod2.nBeta_;
-  nGamma_ = mod2.nGamma_;
-  
-  return *this;
-}
-
-YNGP_M10::~YNGP_M10() {}
-
 void YNGP_M10::updateMatrices()
 {
   AbstractBiblioSubstitutionModel::updateMatrices();
diff --git a/src/Bpp/Phyl/Model/Codon/YNGP_M10.h b/src/Bpp/Phyl/Model/Codon/YNGP_M10.h
index a8a605d..e6ef6d1 100644
--- a/src/Bpp/Phyl/Model/Codon/YNGP_M10.h
+++ b/src/Bpp/Phyl/Model/Codon/YNGP_M10.h
@@ -5,44 +5,42 @@
 //
 
 /*
-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. 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 _YNGP_M10_H_
 #define _YNGP_M10_H_
 
-#include "../AbstractBiblioMixedSubstitutionModel.h"
-#include "../MixtureOfASubstitutionModel.h"
-#include "../FrequenciesSet/CodonFrequenciesSet.h"
+#include "YNGP_M.h"
 
 #include <Bpp/Seq/GeneticCode/GeneticCode.h>
 
@@ -70,65 +68,55 @@ namespace bpp
  * Genetics 155:431-449.
  * 
  */
-class YNGP_M10:
-    public AbstractBiblioMixedSubstitutionModel,
-    virtual public ReversibleSubstitutionModel
-{
-private:
-  std::unique_ptr<MixtureOfASubstitutionModel> pmixmodel_;
-
-  /**
-   * @brief indexes of 2 codons between which the substitution is
-   * synonymous, to set a basis to the homogeneization of the rates.
-   */
-  size_t synfrom_, synto_;
-
-  unsigned int nBeta_, nGamma_;
-  
-public:
-  /*
-   *@brief Constructor that requires the number of classes of the
-   * BetaDiscreteDistribution and the GammaDiscreteDistribution.
-   *
-   */
+  class YNGP_M10:
+    public YNGP_M
+  {
+  private:
+    unsigned int nBeta_, nGamma_;
   
-  YNGP_M10(const GeneticCode* gc, FrequenciesSet* codonFreqs, unsigned int nbBeta, unsigned int nbGamma);
-
-  ~YNGP_M10();
+  public:
+    /*
+     *@brief Constructor that requires the number of classes of the
+     * BetaDiscreteDistribution and the GammaDiscreteDistribution.
+     *
+     */
   
-  YNGP_M10* clone() const { return new YNGP_M10(*this); }
-
-  YNGP_M10(const YNGP_M10&);
-
-  YNGP_M10& operator=(const YNGP_M10&);
+    YNGP_M10(const GeneticCode* gc, FrequenciesSet* codonFreqs, unsigned int nbBeta, unsigned int nbGamma);
 
-protected:
-  void updateMatrices();
+    YNGP_M10* clone() const { return new YNGP_M10(*this); }
 
-public:
-  const SubstitutionModel& getModel() const { return *pmixmodel_.get(); }
-
-  const MixedSubstitutionModel& getMixedModel() const { return *pmixmodel_.get(); }
-
-  std::string getName() const { return "YNGP_M10"; }
-
-  unsigned int getNBeta() const 
-  {
-    return nBeta_;
-  }
+    YNGP_M10(const YNGP_M10& mod2) :
+      YNGP_M(mod2),
+      nBeta_(mod2.nBeta_),
+      nGamma_(mod2.nGamma_)
+    {
+    }
   
-  unsigned int getNGamma() const 
-  {
-    return nGamma_;
-  }
+    YNGP_M10& operator=(const YNGP_M10& mod2)
+    {
+      YNGP_M::operator=(mod2);
+      nBeta_=mod2.nBeta_;
+      nGamma_=mod2.nGamma_;
+      return *this;
+    }
+
+  protected:
+    void updateMatrices();
+
+  public:
+    std::string getName() const { return "YNGP_M10"; }
+
+    unsigned int getNBeta() const 
+    {
+      return nBeta_;
+    }
   
-private:
-  SubstitutionModel& getModel() { return *pmixmodel_.get(); }
-
-  MixedSubstitutionModel& getMixedModel() { return *pmixmodel_.get(); }
-
-  const FrequenciesSet* getFrequenciesSet() const {return pmixmodel_->getNModel(1)->getFrequenciesSet();}
-};
+    unsigned int getNGamma() const 
+    {
+      return nGamma_;
+    }
+  
+  };
 
 } //end of namespace bpp.
 
diff --git a/src/Bpp/Phyl/Model/Codon/YNGP_M2.cpp b/src/Bpp/Phyl/Model/Codon/YNGP_M2.cpp
index 3bb1a21..32b9fc6 100644
--- a/src/Bpp/Phyl/Model/Codon/YNGP_M2.cpp
+++ b/src/Bpp/Phyl/Model/Codon/YNGP_M2.cpp
@@ -38,6 +38,7 @@
 
 #include "YNGP_M2.h"
 #include "YN98.h"
+#include "../MixtureOfASubstitutionModel.h"
 
 #include <Bpp/Numeric/NumConstants.h>
 #include <Bpp/Numeric/Prob/SimpleDiscreteDistribution.h>
@@ -49,10 +50,7 @@ using namespace std;
 /******************************************************************************/
 
 YNGP_M2::YNGP_M2(const GeneticCode* gc, FrequenciesSet* codonFreqs) :
-  AbstractBiblioMixedSubstitutionModel("YNGP_M2."),
-  pmixmodel_(),
-  synfrom_(),
-  synto_()
+  YNGP_M("YNGP_M2.")
 {
   // build the submodel
 
@@ -130,25 +128,6 @@ YNGP_M2::YNGP_M2(const GeneticCode* gc, FrequenciesSet* codonFreqs) :
   updateMatrices();
 }
 
-YNGP_M2::YNGP_M2(const YNGP_M2& mod2) : AbstractBiblioMixedSubstitutionModel(mod2),
-  pmixmodel_(new MixtureOfASubstitutionModel(*mod2.pmixmodel_)),
-  synfrom_(mod2.synfrom_),
-  synto_(mod2.synto_)
-{}
-
-YNGP_M2& YNGP_M2::operator=(const YNGP_M2& mod2)
-{
-  AbstractBiblioMixedSubstitutionModel::operator=(mod2);
-
-  pmixmodel_.reset(new MixtureOfASubstitutionModel(*mod2.pmixmodel_));
-  synfrom_ = mod2.synfrom_;
-  synto_ = mod2.synto_;
-
-  return *this;
-}
-
-YNGP_M2::~YNGP_M2() {}
-
 void YNGP_M2::updateMatrices()
 {
   AbstractBiblioSubstitutionModel::updateMatrices();
diff --git a/src/Bpp/Phyl/Model/Codon/YNGP_M2.h b/src/Bpp/Phyl/Model/Codon/YNGP_M2.h
index 0eb253c..e658a7c 100644
--- a/src/Bpp/Phyl/Model/Codon/YNGP_M2.h
+++ b/src/Bpp/Phyl/Model/Codon/YNGP_M2.h
@@ -5,44 +5,42 @@
 //
 
 /*
-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. 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 _YNGP_M2_H_
 #define _YNGP_M2_H_
 
-#include "../AbstractBiblioMixedSubstitutionModel.h"
-#include "../MixtureOfASubstitutionModel.h"
-#include "../FrequenciesSet/CodonFrequenciesSet.h"
+#include "YNGP_M.h"
 
 #include <Bpp/Seq/GeneticCode/GeneticCode.h>
 
@@ -72,47 +70,32 @@ namespace bpp
  * Wong, W. S. W., Z. Yang, N. Goldman, and R. Nielsen. (2004)
  * Genetics 168:1041--1051.
  */
-class YNGP_M2:
-    public AbstractBiblioMixedSubstitutionModel,
-    virtual public ReversibleSubstitutionModel
-{
-private:
-  std::unique_ptr<MixtureOfASubstitutionModel> pmixmodel_;
-
-  /**
-   * @brief indexes of 2 codons between which the substitution is
-   * synonymous, to set a basis to the homogeneization of the rates.
-   */
-  size_t synfrom_, synto_;
-  
-public:
-  YNGP_M2(const GeneticCode* gc, FrequenciesSet* codonFreqs);
-
-  virtual ~YNGP_M2();
-  
-  YNGP_M2* clone() const { return new YNGP_M2(*this); }
-
-  YNGP_M2(const YNGP_M2&);
-
-  YNGP_M2& operator=(const YNGP_M2&);
-
-protected:
-  void updateMatrices();
+  class YNGP_M2:
+    public YNGP_M
+  {
+  public:
+    YNGP_M2(const GeneticCode* gc, FrequenciesSet* codonFreqs);
 
-public:
-  const SubstitutionModel& getModel() const { return *pmixmodel_.get(); }
+    YNGP_M2* clone() const { return new YNGP_M2(*this); }
 
-  const MixedSubstitutionModel& getMixedModel() const { return *pmixmodel_.get(); }
+    YNGP_M2(const YNGP_M2& mod2) :
+      YNGP_M(mod2)
+    {
+    }
 
-  std::string getName() const { return "YNGP_M2"; }
+    YNGP_M2& operator=(const YNGP_M2& mod2)
+    {
+      YNGP_M::operator=(mod2);
+      return *this;
+    }
 
-private:
-  SubstitutionModel& getModel() { return *pmixmodel_.get(); }
+  protected:
+    void updateMatrices();
 
-  MixedSubstitutionModel& getMixedModel() { return *pmixmodel_.get(); }
+  public:
+    std::string getName() const { return "YNGP_M2"; }
 
-  const FrequenciesSet* getFrequenciesSet() const {return pmixmodel_->getNModel(1)->getFrequenciesSet();}
-};
+  };
 
 } //end of namespace bpp.
 
diff --git a/src/Bpp/Phyl/Model/Codon/YNGP_M3.cpp b/src/Bpp/Phyl/Model/Codon/YNGP_M3.cpp
index 1a23a95..64b26a8 100644
--- a/src/Bpp/Phyl/Model/Codon/YNGP_M3.cpp
+++ b/src/Bpp/Phyl/Model/Codon/YNGP_M3.cpp
@@ -38,6 +38,7 @@
 
 #include "YNGP_M3.h"
 #include "YN98.h"
+#include "../MixtureOfASubstitutionModel.h"
 
 #include <Bpp/Numeric/NumConstants.h>
 #include <Bpp/Numeric/Prob/SimpleDiscreteDistribution.h>
@@ -49,10 +50,7 @@ using namespace std;
 /******************************************************************************/
 
 YNGP_M3::YNGP_M3(const GeneticCode* gc, FrequenciesSet* codonFreqs, unsigned int nbOmega) :
-  AbstractBiblioMixedSubstitutionModel("YNGP_M3."),
-  pmixmodel_(),
-  synfrom_(),
-  synto_()
+  YNGP_M("YNGP_M3.")
 {
   if (nbOmega < 1)
     throw Exception("At least one omega is necessary in the YNGP_M3 model");
@@ -148,25 +146,6 @@ YNGP_M3::YNGP_M3(const GeneticCode* gc, FrequenciesSet* codonFreqs, unsigned int
   updateMatrices();
 }
 
-YNGP_M3::YNGP_M3(const YNGP_M3& mod2) : AbstractBiblioMixedSubstitutionModel(mod2),
-  pmixmodel_(new MixtureOfASubstitutionModel(*mod2.pmixmodel_)),
-  synfrom_(mod2.synfrom_),
-  synto_(mod2.synto_)
-{}
-
-YNGP_M3& YNGP_M3::operator=(const YNGP_M3& mod2)
-{
-  AbstractBiblioMixedSubstitutionModel::operator=(mod2);
-
-  pmixmodel_.reset(new MixtureOfASubstitutionModel(*mod2.pmixmodel_));
-  synfrom_ = mod2.synfrom_;
-  synto_ = mod2.synto_;
-
-  return *this;
-}
-
-YNGP_M3::~YNGP_M3() {}
-
 void YNGP_M3::updateMatrices()
 {
   for (unsigned int i = 0; i < lParPmodel_.size(); i++)
diff --git a/src/Bpp/Phyl/Model/Codon/YNGP_M3.h b/src/Bpp/Phyl/Model/Codon/YNGP_M3.h
index 9a5a658..59547d4 100644
--- a/src/Bpp/Phyl/Model/Codon/YNGP_M3.h
+++ b/src/Bpp/Phyl/Model/Codon/YNGP_M3.h
@@ -5,45 +5,42 @@
 //
 
 /*
-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. 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 _YNGP_M3_H_
 #define _YNGP_M3_H_
 
-#include "../AbstractBiblioMixedSubstitutionModel.h"
-#include "../MixtureOfASubstitutionModel.h"
-#include "../FrequenciesSet/CodonFrequenciesSet.h"
-
+#include "YNGP_M.h"
 #include <Bpp/Seq/GeneticCode/GeneticCode.h>
 
 namespace bpp
@@ -72,49 +69,32 @@ namespace bpp
  * Genetics 155:431-449.
  * 
  */
-class YNGP_M3:
-    public AbstractBiblioMixedSubstitutionModel,
-    virtual public ReversibleSubstitutionModel
-{
-private:
-  std::unique_ptr<MixtureOfASubstitutionModel> pmixmodel_;
-
-  /**
-   * @brief indexes of 2 codons between which the substitution is
-   * synonymous, to set a basis to the homogeneization of the rates.
-   *
-   */
-  size_t synfrom_, synto_;
-  
-public:
-  YNGP_M3(const GeneticCode* gc, FrequenciesSet* codonFreqs, unsigned int nclass = 3);
-
-  ~YNGP_M3();
-  
-  YNGP_M3* clone() const { return new YNGP_M3(*this); }
-
-  YNGP_M3(const YNGP_M3&);
-
-  YNGP_M3& operator=(const YNGP_M3&);
+  class YNGP_M3:
+    public YNGP_M
+  {
+  public:
+    YNGP_M3(const GeneticCode* gc, FrequenciesSet* codonFreqs, unsigned int nclass = 3);
 
-protected:
-  void updateMatrices();
+    YNGP_M3* clone() const { return new YNGP_M3(*this); }
 
-public:
-  const SubstitutionModel& getModel() const { return *pmixmodel_.get(); }
+    YNGP_M3(const YNGP_M3& mod2) :
+      YNGP_M(mod2)
+    {
+    }
 
-  const MixedSubstitutionModel& getMixedModel() const { return *pmixmodel_.get(); }
+    YNGP_M3& operator=(const YNGP_M3& mod2)
+    {
+      YNGP_M::operator=(mod2);
+      return *this;
+    }
 
-  std::string getName() const { return "YNGP_M3"; }
+  protected:
+    void updateMatrices();
 
-private:
-  SubstitutionModel& getModel() { return *pmixmodel_.get(); }
-  
-  MixedSubstitutionModel& getMixedModel() { return *pmixmodel_.get(); }
-  
-  const FrequenciesSet* getFrequenciesSet() const {return pmixmodel_->getNModel(1)->getFrequenciesSet();}
+  public:
+    std::string getName() const { return "YNGP_M3"; }
 
-};
+  };
 
 } //end of namespace bpp.
 
diff --git a/src/Bpp/Phyl/Model/Codon/YNGP_M7.cpp b/src/Bpp/Phyl/Model/Codon/YNGP_M7.cpp
index 2300410..c4feb17 100644
--- a/src/Bpp/Phyl/Model/Codon/YNGP_M7.cpp
+++ b/src/Bpp/Phyl/Model/Codon/YNGP_M7.cpp
@@ -38,6 +38,7 @@
 
 #include "YNGP_M7.h"
 #include "YN98.h"
+#include "../MixtureOfASubstitutionModel.h"
 
 #include <Bpp/Numeric/NumConstants.h>
 #include <Bpp/Numeric/Prob/BetaDiscreteDistribution.h>
@@ -51,10 +52,7 @@ using namespace std;
 /******************************************************************************/
 
 YNGP_M7::YNGP_M7(const GeneticCode* gc, FrequenciesSet* codonFreqs, unsigned int nclass) :
-  AbstractBiblioMixedSubstitutionModel("YNGP_M7."),
-  pmixmodel_(),
-  synfrom_(),
-  synto_()
+  YNGP_M("YNGP_M7.")
 {
   if (nclass <= 0)
     throw Exception("Bad number of classes for model YNGP_M7: " + TextTools::toString(nclass));
@@ -125,25 +123,6 @@ YNGP_M7::YNGP_M7(const GeneticCode* gc, FrequenciesSet* codonFreqs, unsigned int
   updateMatrices();
 }
 
-YNGP_M7::YNGP_M7(const YNGP_M7& mod2) : AbstractBiblioMixedSubstitutionModel(mod2),
-  pmixmodel_(new MixtureOfASubstitutionModel(*mod2.pmixmodel_)),
-  synfrom_(mod2.synfrom_),
-  synto_(mod2.synto_)
-{}
-
-YNGP_M7& YNGP_M7::operator=(const YNGP_M7& mod2)
-{
-  AbstractBiblioMixedSubstitutionModel::operator=(mod2);
-
-  pmixmodel_.reset(new MixtureOfASubstitutionModel(*mod2.pmixmodel_));
-  synfrom_ = mod2.synfrom_;
-  synto_ = mod2.synto_;
-
-  return *this;
-}
-
-YNGP_M7::~YNGP_M7() {}
-
 void YNGP_M7::updateMatrices()
 {
   AbstractBiblioSubstitutionModel::updateMatrices();
diff --git a/src/Bpp/Phyl/Model/Codon/YNGP_M7.h b/src/Bpp/Phyl/Model/Codon/YNGP_M7.h
index 8bb6bde..4a80719 100644
--- a/src/Bpp/Phyl/Model/Codon/YNGP_M7.h
+++ b/src/Bpp/Phyl/Model/Codon/YNGP_M7.h
@@ -5,44 +5,42 @@
 //
 
 /*
-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. 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 _YNGP_M7_H_
 #define _YNGP_M7_H_
 
-#include "../AbstractBiblioMixedSubstitutionModel.h"
-#include "../MixtureOfASubstitutionModel.h"
-#include "../FrequenciesSet/CodonFrequenciesSet.h"
+#include "YNGP_M.h"
 
 #include <Bpp/Seq/GeneticCode/GeneticCode.h>
 
@@ -67,55 +65,39 @@ namespace bpp
  * Genetics 155:431-449.
  * 
  */
-class YNGP_M7:
-    public AbstractBiblioMixedSubstitutionModel,
-    virtual public ReversibleSubstitutionModel
-{
-private:
-  std::unique_ptr<MixtureOfASubstitutionModel> pmixmodel_;
-
-  /**
-   * @brief indexes of 2 codons between which the substitution is
-   * synonymous, to set a basis to the homogeneization of the rates.
-   *
-   */
-  size_t synfrom_, synto_;
-  
-public:
-  /*
-   *@brief Constructor that requires the number of classes of the
-   * BetaDiscreteDistribution.
-   *
-   */
+  class YNGP_M7:
+    public YNGP_M
+  {
+  public:
+    /*
+     *@brief Constructor that requires the number of classes of the
+     * BetaDiscreteDistribution.
+     *
+     */
   
-  YNGP_M7(const GeneticCode* gc, FrequenciesSet* codonFreqs, unsigned int nclass);
-
-  ~YNGP_M7();
-  
-  YNGP_M7* clone() const { return new YNGP_M7(*this); }
-
-  YNGP_M7(const YNGP_M7&);
+    YNGP_M7(const GeneticCode* gc, FrequenciesSet* codonFreqs, unsigned int nclass);
 
-  YNGP_M7& operator=(const YNGP_M7&);
+    YNGP_M7* clone() const { return new YNGP_M7(*this); }
 
-protected:
-  void updateMatrices();
+    YNGP_M7(const YNGP_M7& mod2) :
+      YNGP_M(mod2)
+    {
+    }
 
-public:
-  const SubstitutionModel& getModel() const { return *pmixmodel_.get(); }
-
-  const MixedSubstitutionModel& getMixedModel() const { return *pmixmodel_.get(); }
-
-  std::string getName() const { return "YNGP_M7"; }
-
-private:
-  SubstitutionModel& getModel() { return *pmixmodel_.get(); }
+    YNGP_M7& operator=(const YNGP_M7& mod2)
+    {
+      YNGP_M::operator=(mod2);
+      return *this;
+    }
+  
 
-  MixedSubstitutionModel& getMixedModel() { return *pmixmodel_.get(); }
+  protected:
+    void updateMatrices();
 
-  const FrequenciesSet* getFrequenciesSet() const {return pmixmodel_->getNModel(1)->getFrequenciesSet();}
+  public:
+    std::string getName() const { return "YNGP_M7"; }
 
-};
+  };
 
 } //end of namespace bpp.
 
diff --git a/src/Bpp/Phyl/Model/Codon/YNGP_M8.cpp b/src/Bpp/Phyl/Model/Codon/YNGP_M8.cpp
index d29589d..292001c 100644
--- a/src/Bpp/Phyl/Model/Codon/YNGP_M8.cpp
+++ b/src/Bpp/Phyl/Model/Codon/YNGP_M8.cpp
@@ -38,6 +38,7 @@
 
 #include "YNGP_M8.h"
 #include "YN98.h"
+#include "../MixtureOfASubstitutionModel.h"
 
 #include <Bpp/Numeric/Prob/MixtureOfDiscreteDistributions.h>
 #include <Bpp/Numeric/Prob/SimpleDiscreteDistribution.h>
@@ -51,10 +52,7 @@ using namespace std;
 /******************************************************************************/
 
 YNGP_M8::YNGP_M8(const GeneticCode* gc, FrequenciesSet* codonFreqs, unsigned int nclass) :
-  AbstractBiblioMixedSubstitutionModel("YNGP_M8."),
-  pmixmodel_(),
-  synfrom_(),
-  synto_()
+  YNGP_M("YNGP_M8.")
 {
   if (nclass <= 0)
     throw Exception("Bad number of classes for model YNGP_M8: " + TextTools::toString(nclass));
@@ -138,25 +136,6 @@ YNGP_M8::YNGP_M8(const GeneticCode* gc, FrequenciesSet* codonFreqs, unsigned int
   updateMatrices();
 }
 
-YNGP_M8::YNGP_M8(const YNGP_M8& mod2) : AbstractBiblioMixedSubstitutionModel(mod2),
-  pmixmodel_(new MixtureOfASubstitutionModel(*mod2.pmixmodel_)),
-  synfrom_(mod2.synfrom_),
-  synto_(mod2.synto_)
-{}
-
-YNGP_M8& YNGP_M8::operator=(const YNGP_M8& mod2)
-{
-  AbstractBiblioMixedSubstitutionModel::operator=(mod2);
-
-  pmixmodel_.reset(new MixtureOfASubstitutionModel(*mod2.pmixmodel_));
-  synfrom_ = mod2.synfrom_;
-  synto_ = mod2.synto_;
-
-  return *this;
-}
-
-YNGP_M8::~YNGP_M8() {}
-
 void YNGP_M8::updateMatrices()
 {
   AbstractBiblioSubstitutionModel::updateMatrices();
diff --git a/src/Bpp/Phyl/Model/Codon/YNGP_M8.h b/src/Bpp/Phyl/Model/Codon/YNGP_M8.h
index 7383114..3d71cd1 100644
--- a/src/Bpp/Phyl/Model/Codon/YNGP_M8.h
+++ b/src/Bpp/Phyl/Model/Codon/YNGP_M8.h
@@ -5,44 +5,42 @@
 //
 
 /*
-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. 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 _YNGP_M8_H_
 #define _YNGP_M8_H_
 
-#include "../AbstractBiblioMixedSubstitutionModel.h"
-#include "../MixtureOfASubstitutionModel.h"
-#include "../FrequenciesSet/CodonFrequenciesSet.h"
+#include "YNGP_M.h"
 
 #include <Bpp/Seq/GeneticCode/GeneticCode.h>
 
@@ -70,53 +68,38 @@ namespace bpp
  * Genetics 155:431-449.
  * 
  */
-class YNGP_M8:
-    public AbstractBiblioMixedSubstitutionModel,
-    virtual public ReversibleSubstitutionModel
-{
-private:
-  std::unique_ptr<MixtureOfASubstitutionModel> pmixmodel_;
-
-  /**
-   * @brief indexes of 2 codons between which the substitution is
-   * synonymous, to set a basis to the homogeneization of the rates.
-   */
-  size_t synfrom_, synto_;
-  
-public:
-  /*
-   *@brief Constructor that requires the number of classes of the
-   * BetaDiscreteDistribution.
-   *
-   */
-  
-  YNGP_M8(const GeneticCode* gc, FrequenciesSet* codonFreqs, unsigned int nbclass);
-
-  ~YNGP_M8();
+  class YNGP_M8:
+    public YNGP_M
+  {
+  public:
+    /*
+     *@brief Constructor that requires the number of classes of the
+     * BetaDiscreteDistribution.
+     *
+     */
   
-  YNGP_M8* clone() const { return new YNGP_M8(*this); }
-
-  YNGP_M8(const YNGP_M8&);
-
-  YNGP_M8& operator=(const YNGP_M8&);
+    YNGP_M8(const GeneticCode* gc, FrequenciesSet* codonFreqs, unsigned int nbclass);
 
-protected:
-  void updateMatrices();
+    YNGP_M8* clone() const { return new YNGP_M8(*this); }
 
-public:
-  const SubstitutionModel& getModel() const { return *pmixmodel_.get(); }
-
-  const MixedSubstitutionModel& getMixedModel() const { return *pmixmodel_.get(); }
-
-  std::string getName() const { return "YNGP_M8"; }
-
-private:
-  SubstitutionModel& getModel() { return *pmixmodel_.get(); }
+    YNGP_M8(const YNGP_M8& mod2) :
+      YNGP_M(mod2)
+    {
+    }
+  
+    YNGP_M8& operator=(const YNGP_M8& mod2)
+    {
+      YNGP_M::operator=(mod2);
+      return *this;
+    }
+  
+  protected:
+    void updateMatrices();
 
-  MixedSubstitutionModel& getMixedModel() { return *pmixmodel_.get(); }
+  public:
+    std::string getName() const { return "YNGP_M8"; }
 
-  const FrequenciesSet* getFrequenciesSet() const {return pmixmodel_->getNModel(1)->getFrequenciesSet();}
-};
+  };
 
 } //end of namespace bpp.
 
diff --git a/src/Bpp/Phyl/Model/Codon/YNGP_M9.cpp b/src/Bpp/Phyl/Model/Codon/YNGP_M9.cpp
index d52dee0..205c38d 100644
--- a/src/Bpp/Phyl/Model/Codon/YNGP_M9.cpp
+++ b/src/Bpp/Phyl/Model/Codon/YNGP_M9.cpp
@@ -38,6 +38,7 @@
 
 #include "YNGP_M9.h"
 #include "YN98.h"
+#include "../MixtureOfASubstitutionModel.h"
 
 #include <Bpp/Numeric/Prob/MixtureOfDiscreteDistributions.h>
 #include <Bpp/Numeric/Prob/BetaDiscreteDistribution.h>
@@ -51,10 +52,7 @@ using namespace std;
 /******************************************************************************/
 
 YNGP_M9::YNGP_M9(const GeneticCode* gc, FrequenciesSet* codonFreqs, unsigned int nbBeta, unsigned int nbGamma) :
-  AbstractBiblioMixedSubstitutionModel("YNGP_M9."),
-  pmixmodel_(),
-  synfrom_(),
-  synto_(),
+  YNGP_M("YNGP_M9."),
   nBeta_(nbBeta),
   nGamma_(nbGamma)
 {
@@ -138,31 +136,6 @@ YNGP_M9::YNGP_M9(const GeneticCode* gc, FrequenciesSet* codonFreqs, unsigned int
   updateMatrices();
 }
 
-YNGP_M9::YNGP_M9(const YNGP_M9& mod2) : AbstractBiblioMixedSubstitutionModel(mod2),
-                                           pmixmodel_(new MixtureOfASubstitutionModel(*mod2.pmixmodel_)),
-                                           synfrom_(mod2.synfrom_),
-                                           synto_(mod2.synto_),
-                                           nBeta_(mod2.nBeta_),
-                                           nGamma_(mod2.nGamma_)
-
-{}
-
-
-YNGP_M9& YNGP_M9::operator=(const YNGP_M9& mod2)
-{
-  AbstractBiblioMixedSubstitutionModel::operator=(mod2);
-
-  pmixmodel_.reset(new MixtureOfASubstitutionModel(*mod2.pmixmodel_));
-  synfrom_ = mod2.synfrom_;
-  synto_ = mod2.synto_;
-  nBeta_ = mod2.nBeta_;
-  nGamma_ = mod2.nGamma_;
-  
-  return *this;
-}
-
-YNGP_M9::~YNGP_M9() {}
-
 void YNGP_M9::updateMatrices()
 {
   AbstractBiblioSubstitutionModel::updateMatrices();
diff --git a/src/Bpp/Phyl/Model/Codon/YNGP_M9.h b/src/Bpp/Phyl/Model/Codon/YNGP_M9.h
index 851a50c..7553409 100644
--- a/src/Bpp/Phyl/Model/Codon/YNGP_M9.h
+++ b/src/Bpp/Phyl/Model/Codon/YNGP_M9.h
@@ -5,44 +5,42 @@
 //
 
 /*
-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. 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 _YNGP_M9_H_
 #define _YNGP_M9_H_
 
-#include "../AbstractBiblioMixedSubstitutionModel.h"
-#include "../MixtureOfASubstitutionModel.h"
-#include "../FrequenciesSet/CodonFrequenciesSet.h"
+#include "YNGP_M.h"
 
 #include <Bpp/Seq/GeneticCode/GeneticCode.h>
 
@@ -70,65 +68,57 @@ namespace bpp
  * Genetics 155:431-449.
  * 
  */
-class YNGP_M9:
-    public AbstractBiblioMixedSubstitutionModel,
-    virtual public ReversibleSubstitutionModel
-{
-private:
-  std::unique_ptr<MixtureOfASubstitutionModel> pmixmodel_;
-
-  /**
-   * @brief indexes of 2 codons between which the substitution is
-   * synonymous, to set a basis to the homogeneization of the rates.
-   */
-  size_t synfrom_, synto_;
-
-  unsigned int nBeta_, nGamma_;
+  class YNGP_M9:
+    public YNGP_M
+  {
+  private:
+    unsigned int nBeta_, nGamma_;
   
-public:
-  /*
-   *@brief Constructor that requires the number of classes of the
-   * BetaDiscreteDistribution and the GammaDiscreteDistribution.
-   *
-   */
+  public:
+    /*
+     *@brief Constructor that requires the number of classes of the
+     * BetaDiscreteDistribution and the GammaDiscreteDistribution.
+     *
+     */
   
-  YNGP_M9(const GeneticCode* gc, FrequenciesSet* codonFreqs, unsigned int nbBeta, unsigned int nbGamma);
-
-  ~YNGP_M9();
+    YNGP_M9(const GeneticCode* gc, FrequenciesSet* codonFreqs, unsigned int nbBeta, unsigned int nbGamma);
+
+    YNGP_M9* clone() const { return new YNGP_M9(*this); }
+
+    YNGP_M9(const YNGP_M9& mod2) :
+      YNGP_M(mod2),
+      nBeta_(mod2.nBeta_),
+      nGamma_(mod2.nGamma_)
+    {
+    }
+    
+    YNGP_M9& operator=(const YNGP_M9& mod2)
+    {
+      YNGP_M::operator=(mod2);
+      
+      nBeta_ = mod2.nBeta_;
+      nGamma_ = mod2.nGamma_;
+      return *this;
+    }
+    
+
+  protected:
+    void updateMatrices();
+
+  public:
+    std::string getName() const { return "YNGP_M9"; }
+
+    unsigned int getNBeta() const 
+    {
+      return nBeta_;
+    }
   
-  YNGP_M9* clone() const { return new YNGP_M9(*this); }
-
-  YNGP_M9(const YNGP_M9&);
-
-  YNGP_M9& operator=(const YNGP_M9&);
-
-protected:
-  void updateMatrices();
-
-public:
-  const SubstitutionModel& getModel() const { return *pmixmodel_.get(); }
-
-  const MixedSubstitutionModel& getMixedModel() const { return *pmixmodel_.get(); }
-
-  std::string getName() const { return "YNGP_M9"; }
-
-  unsigned int getNBeta() const 
-  {
-    return nBeta_;
-  }
+    unsigned int getNGamma() const 
+    {
+      return nGamma_;
+    }
   
-  unsigned int getNGamma() const 
-  {
-    return nGamma_;
-  }
-  
-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/FrequenciesSet/CodonFrequenciesSet.cpp b/src/Bpp/Phyl/Model/FrequenciesSet/CodonFrequenciesSet.cpp
index 01e4df3..083676c 100644
--- a/src/Bpp/Phyl/Model/FrequenciesSet/CodonFrequenciesSet.cpp
+++ b/src/Bpp/Phyl/Model/FrequenciesSet/CodonFrequenciesSet.cpp
@@ -81,18 +81,18 @@ FullCodonFrequenciesSet::FullCodonFrequenciesSet(
   pgc_(gCode),
   sFreq_(gCode->getSourceAlphabet()->getSize() - gCode->getNumberOfStopCodons(), method, allowNullFreqs, "Full.")
 {
-  if (initFreqs.size() != getAlphabet()->getSize())
+  if (initFreqs.size() != getCodonAlphabet()->getSize())
     throw Exception("FullCodonFrequenciesSet(constructor). There must be " + TextTools::toString(gCode->getSourceAlphabet()->getSize()) + " frequencies.");
 
   double sum = 0;
-  for (size_t i = 0; i < getAlphabet()->getSize(); i++)
+  for (size_t i = 0; i < getCodonAlphabet()->getSize(); i++)
   {
     if (!pgc_->isStop(static_cast<int>(i)))
       sum += initFreqs[i];
   }
 
   vector<double> vd;
-  for (size_t i = 0; i < getAlphabet()->getSize(); i++)
+  for (size_t i = 0; i < getCodonAlphabet()->getSize(); i++)
   {
     if (!gCode->isStop(static_cast<int>(i)))
       vd.push_back(initFreqs[i] / sum);
@@ -126,18 +126,18 @@ void FullCodonFrequenciesSet::setNamespace(const std::string& nameSpace)
 
 void FullCodonFrequenciesSet::setFrequencies(const vector<double>& frequencies)
 {
-  if (frequencies.size() != getAlphabet()->getSize())
+  if (frequencies.size() != getCodonAlphabet()->getSize())
     throw DimensionException("FullFrequenciesSet::setFrequencies", frequencies.size(), getAlphabet()->getSize());
 
   double sum = 0;
-  for (size_t i = 0; i < getAlphabet()->getSize(); i++)
+  for (size_t i = 0; i < getCodonAlphabet()->getSize(); i++)
   {
     if (!pgc_->isStop(static_cast<int>(i)))
       sum += frequencies[i];
   }
 
   vector<double> vd;
-  for (size_t i = 0; i < getAlphabet()->getSize(); i++)
+  for (size_t i = 0; i < getCodonAlphabet()->getSize(); i++)
   {
     if (!pgc_->isStop(static_cast<int>(i)))
       vd.push_back(frequencies[i] / sum);
@@ -160,7 +160,7 @@ void FullCodonFrequenciesSet::updateFreq_()
 {
   size_t nbstop = 0;
 
-  for (size_t j = 0; j < getAlphabet()->getSize(); j++)
+  for (size_t j = 0; j < getCodonAlphabet()->getSize(); j++)
   {
     if (pgc_->isStop(static_cast<int>(j)))
     {
@@ -280,8 +280,8 @@ void FullPerAACodonFrequenciesSet::updateFrequencies()
 
 void FullPerAACodonFrequenciesSet::setFrequencies(const vector<double>& frequencies)
 {
-  if (frequencies.size() != getAlphabet()->getSize())
-    throw DimensionException("FullPerAAFrequenciesSet::setFrequencies", frequencies.size(), getAlphabet()->getSize());
+  if (frequencies.size() != getCodonAlphabet()->getSize())
+    throw DimensionException("FullPerAAFrequenciesSet::setFrequencies", frequencies.size(), getCodonAlphabet()->getSize());
 
   double bigS = 0;
   Vdouble vaa;
@@ -356,7 +356,7 @@ FixedCodonFrequenciesSet::FixedCodonFrequenciesSet(const GeneticCode* gCode, con
 
 void FixedCodonFrequenciesSet::setFrequencies(const vector<double>& frequencies)
 {
-  const CodonAlphabet* ca = dynamic_cast<const CodonAlphabet*>(getAlphabet());
+  const CodonAlphabet* ca = getCodonAlphabet();
   if (frequencies.size() != ca->getSize())
     throw DimensionException("FixedFrequenciesSet::setFrequencies", frequencies.size(), ca->getSize());
   double sum = 0.0;
@@ -402,7 +402,7 @@ CodonFromIndependentFrequenciesSet::CodonFromIndependentFrequenciesSet(
     int nspcod = vspcod[ispcod];
     for (size_t ph = 0; ph < 3; ph++)
     {
-      size_t nspcod0 = static_cast<size_t>(nspcod) - pow * static_cast<size_t>(getAlphabet()->getNPosition(nspcod, 2 - ph));
+      size_t nspcod0 = static_cast<size_t>(nspcod) - pow * static_cast<size_t>(getCodonAlphabet()->getNPosition(nspcod, 2 - ph));
       for (size_t dec = 0; dec < 4; dec++)
       {
         size_t vois = nspcod0 + pow * dec;
@@ -415,7 +415,7 @@ CodonFromIndependentFrequenciesSet::CodonFromIndependentFrequenciesSet(
   updateFrequencies();
 }
 
-const CodonAlphabet* CodonFromIndependentFrequenciesSet::getAlphabet() const
+const CodonAlphabet* CodonFromIndependentFrequenciesSet::getCodonAlphabet() const
 {
   return dynamic_cast<const CodonAlphabet*>(WordFromIndependentFrequenciesSet::getAlphabet());
 }
@@ -442,7 +442,7 @@ void CodonFromIndependentFrequenciesSet::updateFrequencies()
 {
   WordFromIndependentFrequenciesSet::updateFrequencies();
 
-  size_t s = getAlphabet()->getSize();
+  size_t s = getCodonAlphabet()->getSize();
 
   if (mgmtStopCodon_ != 0)
   {
@@ -525,7 +525,7 @@ CodonFromUniqueFrequenciesSet::CodonFromUniqueFrequenciesSet(
     int nspcod = vspcod[ispcod];
     for (int ph = 0; ph < 3; ph++)
     {
-      size_t nspcod0 = static_cast<size_t>(nspcod) - pow * static_cast<size_t>(getAlphabet()->getNPosition(nspcod, static_cast<unsigned int>(2 - ph)));
+      size_t nspcod0 = static_cast<size_t>(nspcod) - pow * static_cast<size_t>(getCodonAlphabet()->getNPosition(nspcod, static_cast<unsigned int>(2 - ph)));
       for (size_t dec = 0; dec < 4; dec++)
       {
         size_t vois = nspcod0 + pow * dec;
@@ -539,9 +539,9 @@ CodonFromUniqueFrequenciesSet::CodonFromUniqueFrequenciesSet(
   updateFrequencies();
 }
 
-const CodonAlphabet* CodonFromUniqueFrequenciesSet::getAlphabet() const
+const CodonAlphabet* CodonFromUniqueFrequenciesSet::getCodonAlphabet() const
 {
-  return dynamic_cast<const CodonAlphabet*>(WordFromUniqueFrequenciesSet::getAlphabet());
+  return dynamic_cast<const CodonAlphabet*>(WordFromUniqueFrequenciesSet::getWordAlphabet());
 }
 
 
@@ -567,7 +567,7 @@ void CodonFromUniqueFrequenciesSet::updateFrequencies()
 {
   WordFromUniqueFrequenciesSet::updateFrequencies();
 
-  size_t s = getAlphabet()->getSize();
+  size_t s = getCodonAlphabet()->getSize();
 
   if (mgmtStopCodon_ != 0)
   {
@@ -575,7 +575,7 @@ void CodonFromUniqueFrequenciesSet::updateFrequencies()
     // neighbour non-stop codons
     double f[64] = {0};
     
-    for (auto mStopNeigh_it : mStopNeigh_)
+    for (const auto& mStopNeigh_it : mStopNeigh_)
     {
       int stNb = mStopNeigh_it.first;
       Vint vneigh = mStopNeigh_it.second;
diff --git a/src/Bpp/Phyl/Model/FrequenciesSet/CodonFrequenciesSet.h b/src/Bpp/Phyl/Model/FrequenciesSet/CodonFrequenciesSet.h
index 9e8430b..7b9b1b5 100644
--- a/src/Bpp/Phyl/Model/FrequenciesSet/CodonFrequenciesSet.h
+++ b/src/Bpp/Phyl/Model/FrequenciesSet/CodonFrequenciesSet.h
@@ -60,7 +60,7 @@ public:
   
   CodonFrequenciesSet* clone() const = 0;
 
-  const CodonAlphabet* getAlphabet() const = 0;
+  virtual const CodonAlphabet* getCodonAlphabet() const = 0;
 
 public:
   /**
@@ -142,7 +142,7 @@ public:
    */
   void setFrequencies(const std::vector<double>& frequencies);
 
-  const CodonAlphabet* getAlphabet() const
+  const CodonAlphabet* getCodonAlphabet() const
   {
     return dynamic_cast<const CodonAlphabet*>(AbstractFrequenciesSet::getAlphabet());
   }
@@ -199,7 +199,7 @@ public:
 public:
   const GeneticCode* getGeneticCode() const { return pgc_; }
 
-  const CodonAlphabet* getAlphabet() const
+  const CodonAlphabet* getCodonAlphabet() const
   {
     return dynamic_cast<const CodonAlphabet*>(AbstractFrequenciesSet::getAlphabet());
   }
@@ -274,7 +274,7 @@ public:
 
 public:
   
-  const CodonAlphabet* getAlphabet() const
+  const CodonAlphabet* getCodonAlphabet() const
   {
     return dynamic_cast<const CodonAlphabet*>(AbstractFrequenciesSet::getAlphabet());
   }
@@ -354,7 +354,7 @@ public:
 
   CodonFromIndependentFrequenciesSet* clone() const { return new CodonFromIndependentFrequenciesSet(*this); }
 
-  const CodonAlphabet* getAlphabet() const;
+  const CodonAlphabet* getCodonAlphabet() const;
 
   const GeneticCode* getGeneticCode() const { return pgc_; }
 
@@ -435,7 +435,7 @@ public:
 
   CodonFromUniqueFrequenciesSet* clone() const { return new CodonFromUniqueFrequenciesSet(*this); }
 
-  const CodonAlphabet* getAlphabet() const;
+  const CodonAlphabet* getCodonAlphabet() const;
 
   const GeneticCode* getGeneticCode() const { return pgc_; }
 
diff --git a/src/Bpp/Phyl/Model/FrequenciesSet/FrequenciesSet.h b/src/Bpp/Phyl/Model/FrequenciesSet/FrequenciesSet.h
index b3a663b..989bff1 100644
--- a/src/Bpp/Phyl/Model/FrequenciesSet/FrequenciesSet.h
+++ b/src/Bpp/Phyl/Model/FrequenciesSet/FrequenciesSet.h
@@ -83,7 +83,7 @@ namespace bpp
     /**
      * @return The frequencies values of the set.
      */
-    virtual const std::vector<double> getFrequencies() const = 0;
+    virtual const Vdouble& getFrequencies() const = 0;
 
     /**
      * @return The frequencies of each alphabet states according to this model.
@@ -168,7 +168,7 @@ namespace bpp
 
     const StateMap& getStateMap() const { return *stateMap_; }
 
-    const std::vector<double> getFrequencies() const { return freq_; }
+    const Vdouble& getFrequencies() const { return freq_; }
   
     const std::map<int, double> getAlphabetStatesFrequencies() const;
 
diff --git a/src/Bpp/Phyl/Model/FrequenciesSet/WordFrequenciesSet.cpp b/src/Bpp/Phyl/Model/FrequenciesSet/WordFrequenciesSet.cpp
index f227f76..db613cf 100644
--- a/src/Bpp/Phyl/Model/FrequenciesSet/WordFrequenciesSet.cpp
+++ b/src/Bpp/Phyl/Model/FrequenciesSet/WordFrequenciesSet.cpp
@@ -64,7 +64,7 @@ AbstractWordFrequenciesSet::AbstractWordFrequenciesSet(StateMap* stateMap, const
 
 size_t AbstractWordFrequenciesSet::getLength() const
 {
-  return dynamic_cast<const WordAlphabet*>(getAlphabet())->getLength();
+  return getWordAlphabet()->getLength();
 }
 
 AbstractWordFrequenciesSet::~AbstractWordFrequenciesSet()
@@ -99,6 +99,31 @@ WordFromIndependentFrequenciesSet::WordFromIndependentFrequenciesSet(
   updateFrequencies();
 }
 
+WordFromIndependentFrequenciesSet::WordFromIndependentFrequenciesSet(
+  const CodonAlphabet* pWA,
+  const std::vector<FrequenciesSet*>& freqVector,
+  const string& prefix, const string& name) :
+  AbstractWordFrequenciesSet(new CanonicalStateMap(pWA, false), prefix, name),
+  vFreq_(),
+  vNestedPrefix_()
+{
+  size_t sf = getSizeFromVector(freqVector);
+  if (pWA->getSize() !=  sf)
+    throw Exception("WordFromIndependentFrequenciesSet: Size of the frequencies does not match size of the alphabet : " + TextTools::toString(sf) + " vs " + TextTools::toString(pWA->getSize()));
+
+  size_t l = freqVector.size();
+
+  for (size_t i = 0; i < l; i++)
+  {
+    vFreq_.push_back(freqVector[i]);
+    vNestedPrefix_.push_back(freqVector[i]->getNamespace());
+    vFreq_[i]->setNamespace(prefix + TextTools::toString(i + 1) + "_" + vNestedPrefix_[i]);
+    addParameters_(vFreq_[i]->getParameters());
+  }
+
+  updateFrequencies();
+}
+
 WordFromIndependentFrequenciesSet::WordFromIndependentFrequenciesSet(const WordFromIndependentFrequenciesSet& iwfs) :
   AbstractWordFrequenciesSet(iwfs),
   vFreq_(iwfs.vFreq_.size()),
@@ -158,7 +183,7 @@ void WordFromIndependentFrequenciesSet::fireParameterChanged(const ParameterList
 void WordFromIndependentFrequenciesSet::updateFrequencies()
 {
   size_t l = vFreq_.size();
-  size_t s = getAlphabet()->getSize();
+  size_t s = getWordAlphabet()->getSize();
   vector< vector<double> >f(l);
 
   size_t i, p, t, i2;
@@ -183,8 +208,8 @@ void WordFromIndependentFrequenciesSet::updateFrequencies()
 
 void WordFromIndependentFrequenciesSet::setFrequencies(const vector<double>& frequencies) 
 {
-  if (frequencies.size() != getAlphabet()->getSize())
-    throw DimensionException("WordFromIndependentFrequenciesSet::setFrequencies", frequencies.size(), getAlphabet()->getSize());
+  if (frequencies.size() != getWordAlphabet()->getSize())
+    throw DimensionException("WordFromIndependentFrequenciesSet::setFrequencies", frequencies.size(), getWordAlphabet()->getSize());
   double sum = 0.0;
   size_t size = frequencies.size();
   for (size_t i = 0; i < size; i++)
@@ -275,6 +300,30 @@ WordFromUniqueFrequenciesSet::WordFromUniqueFrequenciesSet(
   updateFrequencies();
 }
 
+WordFromUniqueFrequenciesSet::WordFromUniqueFrequenciesSet(
+  const CodonAlphabet* pWA,
+  FrequenciesSet* pabsfreq,
+  const string& prefix,
+  const string& name) :
+  AbstractWordFrequenciesSet(new CanonicalStateMap(pWA, false), prefix, name),
+  pFreq_(pabsfreq),
+  NestedPrefix_(pabsfreq->getNamespace()),
+  length_(pWA->getLength())
+{
+  size_t i;
+
+  string st = "";
+  for (i = 0; i < length_; i++)
+  {
+    st += TextTools::toString(i + 1);
+  }
+
+  pFreq_->setNamespace(prefix+ st + "_" + NestedPrefix_);
+  addParameters_(pFreq_->getParameters());
+
+  updateFrequencies();
+}
+
 WordFromUniqueFrequenciesSet::WordFromUniqueFrequenciesSet(const WordFromUniqueFrequenciesSet& iwfs) :
   AbstractWordFrequenciesSet(iwfs),
   pFreq_(iwfs.pFreq_->clone()),
@@ -313,7 +362,7 @@ void WordFromUniqueFrequenciesSet::fireParameterChanged(const ParameterList& pl)
 
 void WordFromUniqueFrequenciesSet::updateFrequencies()
 {
-  size_t s = getAlphabet()->getSize();
+  size_t s = getWordAlphabet()->getSize();
   vector<double> f;
   size_t letsi = pFreq_->getAlphabet()->getSize();
 
@@ -335,8 +384,8 @@ void WordFromUniqueFrequenciesSet::updateFrequencies()
 
 void WordFromUniqueFrequenciesSet::setFrequencies(const vector<double>& frequencies) 
 {
-  if (frequencies.size() != getAlphabet()->getSize())
-    throw DimensionException("WordFromUniqueFrequenciesSet::setFrequencies", frequencies.size(), getAlphabet()->getSize());
+  if (frequencies.size() != getWordAlphabet()->getSize())
+    throw DimensionException("WordFromUniqueFrequenciesSet::setFrequencies", frequencies.size(), getWordAlphabet()->getSize());
   double sum = 0.0;
   size_t size = frequencies.size();
   for (size_t i = 0; i < size; i++)
diff --git a/src/Bpp/Phyl/Model/FrequenciesSet/WordFrequenciesSet.h b/src/Bpp/Phyl/Model/FrequenciesSet/WordFrequenciesSet.h
index de3db96..28145b0 100644
--- a/src/Bpp/Phyl/Model/FrequenciesSet/WordFrequenciesSet.h
+++ b/src/Bpp/Phyl/Model/FrequenciesSet/WordFrequenciesSet.h
@@ -41,6 +41,7 @@
 #define _WORDFREQUENCIESSET_H_
 
 #include <Bpp/Seq/Alphabet/WordAlphabet.h>
+#include <Bpp/Seq/Alphabet/CodonAlphabet.h>
 #include "FrequenciesSet.h"
 
 namespace bpp
@@ -70,7 +71,7 @@ protected:
 public:
   WordFrequenciesSet* clone() const = 0;
 
-  const WordAlphabet* getAlphabet() const = 0;
+  virtual const CoreWordAlphabet* getWordAlphabet() const = 0;
 
   /**
    *@ brief Returns the n-th FrequenciesSet&
@@ -105,9 +106,9 @@ public:
     return *this;
   }
 
-  const WordAlphabet* getAlphabet() const
+  const CoreWordAlphabet* getWordAlphabet() const
   {
-    return dynamic_cast<const WordAlphabet*>(AbstractFrequenciesSet::getAlphabet());
+    return dynamic_cast<const CoreWordAlphabet*>(AbstractFrequenciesSet::getAlphabet());
   }
 
   virtual ~AbstractWordFrequenciesSet();
@@ -138,6 +139,8 @@ public:
    */
   WordFromIndependentFrequenciesSet(const WordAlphabet* pWA, const std::vector<FrequenciesSet*>& freqVector, const std::string& prefix = "", const std::string& name="WordFromIndependent");
 
+  WordFromIndependentFrequenciesSet(const CodonAlphabet* pWA, const std::vector<FrequenciesSet*>& freqVector, const std::string& prefix = "", const std::string& name="WordFromIndependent");
+
   WordFromIndependentFrequenciesSet(const WordFromIndependentFrequenciesSet& iwfs);
 
   ~WordFromIndependentFrequenciesSet();
@@ -190,6 +193,8 @@ public:
    */
   WordFromUniqueFrequenciesSet(const WordAlphabet* pWA, FrequenciesSet* pabsfreq, const std::string& prefix = "", const std::string& name = "WordFromUnique");
 
+  WordFromUniqueFrequenciesSet(const CodonAlphabet* pWA, FrequenciesSet* pabsfreq, const std::string& prefix = "", const std::string& name = "WordFromUnique");
+
   WordFromUniqueFrequenciesSet(const WordFromUniqueFrequenciesSet& iwfs);
 
   WordFromUniqueFrequenciesSet& operator=(const WordFromUniqueFrequenciesSet& iwfs);
diff --git a/src/Bpp/Phyl/Model/FromMixtureSubstitutionModel.cpp b/src/Bpp/Phyl/Model/FromMixtureSubstitutionModel.cpp
index 959282d..ce8223c 100644
--- a/src/Bpp/Phyl/Model/FromMixtureSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/FromMixtureSubstitutionModel.cpp
@@ -45,7 +45,7 @@ using namespace std;
 /******************************************************************************/
 
 FromMixtureSubstitutionModel::FromMixtureSubstitutionModel(const MixedSubstitutionModel& mixedModel, const std::string& subModelName, const std::string& mixtDesc) :
-  AbstractParameterAliasable(mixedModel.getName() + "_" + subModelName),
+  AbstractParameterAliasable(mixedModel.getName() + "_" + subModelName + "."),
   subModel_(),
   mixtName_(mixtDesc)
 {
@@ -55,7 +55,24 @@ FromMixtureSubstitutionModel::FromMixtureSubstitutionModel(const MixedSubstituti
     throw ParameterNotFoundException("FromMixtureSubstitutionModel::FromMixtureSubstitutionModel : unknown model name", subModelName);
 
   subModel_ = std::unique_ptr<SubstitutionModel>(sm->clone());
-  subModel_->setNamespace(mixtName_);
+  subModel_->setNamespace(getNamespace());
+
+  subModel_->setRate(1);
+  addParameters_(subModel_->getParameters());
+}
+
+FromMixtureSubstitutionModel::FromMixtureSubstitutionModel(const MixedSubstitutionModel& mixedModel, size_t subModelNumber, const std::string& mixtDesc) :
+  AbstractParameterAliasable(mixedModel.getName() + "_" + TextTools::toString(subModelNumber) + "."),
+  subModel_(),
+  mixtName_(mixtDesc)
+{
+  if (subModelNumber>=mixedModel.getNumberOfModels())
+    throw ParameterNotFoundException("FromMixtureSubstitutionModel::FromMixtureSubstitutionModel : bad model number", TextTools::toString(subModelNumber));
+
+  const SubstitutionModel* sm = mixedModel.getNModel(subModelNumber);
+
+  subModel_ = std::unique_ptr<SubstitutionModel>(sm->clone());
+  subModel_->setNamespace(getNamespace());
 
   subModel_->setRate(1);
   addParameters_(subModel_->getParameters());
@@ -85,9 +102,3 @@ FromMixtureSubstitutionModel& FromMixtureSubstitutionModel::operator=(const From
 }
 
 
-std::string FromMixtureSubstitutionModel::getName() const
-{
-  size_t posp = mixtName_.find("(");
-
-  return mixtName_.substr(0, posp) + "_" + getModel().getName() + mixtName_.substr(posp);
-}
diff --git a/src/Bpp/Phyl/Model/FromMixtureSubstitutionModel.h b/src/Bpp/Phyl/Model/FromMixtureSubstitutionModel.h
index 5631f07..4352e39 100644
--- a/src/Bpp/Phyl/Model/FromMixtureSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/FromMixtureSubstitutionModel.h
@@ -5,230 +5,146 @@
 //
 
 /*
-   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 _FROM_MIXTURE_SUBSTITUTIONMODEL_H_
 #define _FROM_MIXTURE_SUBSTITUTIONMODEL_H_
 
 #include "AbstractSubstitutionModel.h"
-#include "MixtureOfSubstitutionModels.h"
+#include "MixedSubstitutionModel.h"
+#include "AbstractWrappedModel.h"
 
 namespace bpp
 {
 /**
  * @brief Model taken from a SubModel of a
- * MixtureOfSubstitutionModels.
+ * Mixture of SubstitutionModels.
  *
  * It has the same parameters as the SubModel.
  */
-class FromMixtureSubstitutionModel :
-  public virtual SubstitutionModel,
-  public AbstractParameterAliasable
-{
-private:
-  /*
-   * @brief The subModel taken from the MixtureOfSubstitutionModels.
-   *
-   * This subModel is normalized, even if it is not in the mixture.
-   *
-   */
-
-  std::unique_ptr<SubstitutionModel> subModel_;
-
-  /*
-   * @brief The name of the mixture model (for io purpose).
-   */
-
-  std::string mixtName_;
-
-public:
-  FromMixtureSubstitutionModel(const MixedSubstitutionModel& mixedModel, const std::string& subModelName, const std::string& mixtDesc);
-
-  FromMixtureSubstitutionModel(const FromMixtureSubstitutionModel& fmsm);
-
-  FromMixtureSubstitutionModel& operator=(const FromMixtureSubstitutionModel& fmsm);
-
-  ~FromMixtureSubstitutionModel() {}
-
-  FromMixtureSubstitutionModel* clone() const { return new FromMixtureSubstitutionModel(*this); }
-
-public:
-  const SubstitutionModel& getModel() const
-  {
-    return *subModel_.get();
-  }
-
-protected:
-  void updateMatrices();
-
-  SubstitutionModel& getModel()
+  class FromMixtureSubstitutionModel :
+    public virtual AbstractTotallyWrappedSubstitutionModel,
+    public AbstractParameterAliasable
   {
-    return *subModel_.get();
-  }
-
-public:
-  /*
-     *@ brief Methods to supersede SubstitutionModel methods.
-   *
-   * @{
-   */
-
-  const std::vector<int>& getAlphabetStates() const { return getModel().getAlphabetStates(); }
-
-  const StateMap& getStateMap() const { return getModel().getStateMap(); }
-
-  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); }
-
-  double freq(size_t i) const { return getModel().freq(i); }
-
-  double Qij(size_t i, size_t j) const { return getModel().Qij(i, j); }
-
-  double Pij_t    (size_t i, size_t j, double t) const { return getModel().Pij_t(i, j, t); }
-  double dPij_dt  (size_t i, size_t j, double t) const { return getModel().dPij_dt (i, j, t); }
-  double d2Pij_dt2(size_t i, size_t j, double t) const { return getModel().d2Pij_dt2(i, j, t); }
-
-  const Vdouble& getFrequencies() const { return getModel().getFrequencies(); }
-
-  const Matrix<double>& getGenerator() const { return getModel().getGenerator(); }
-
-  const Matrix<double>& getExchangeabilityMatrix() const { return getModel().getExchangeabilityMatrix(); }
+  private:
+    /*
+     * @brief The subModel taken from the MixtureOfSubstitutionModels.
+     *
+     * This subModel is normalized, even if it is not in the mixture.
+     *
+     */
 
-  double Sij(size_t i, size_t j) const { return getModel().Sij(i, j); }
+    std::unique_ptr<SubstitutionModel> subModel_;
 
-  const Matrix<double>& getPij_t(double t) const { return getModel().getPij_t(t); }
+    /*
+     * @brief The name of the mixture model (for io purpose).
+     */
 
-  const Matrix<double>& getdPij_dt(double t) const { return getModel().getdPij_dt(t); }
+    std::string mixtName_;
 
-  const Matrix<double>& getd2Pij_dt2(double t) const { return getModel().getd2Pij_dt2(t); }
+  public:
+    FromMixtureSubstitutionModel(const MixedSubstitutionModel& mixedModel, const std::string& subModelName, const std::string& mixtDesc);
 
-  void enableEigenDecomposition(bool yn) { getModel().enableEigenDecomposition(yn); }
+    FromMixtureSubstitutionModel(const MixedSubstitutionModel& mixedModel, size_t subModelNumber, const std::string& mixtDesc);
 
-  bool enableEigenDecomposition() { return getModel().enableEigenDecomposition(); }
+    FromMixtureSubstitutionModel(const FromMixtureSubstitutionModel& fmsm);
 
-  bool isDiagonalizable() const { return getModel().isDiagonalizable(); }
+    FromMixtureSubstitutionModel& operator=(const FromMixtureSubstitutionModel& fmsm);
 
-  bool isNonSingular() const { return getModel().isNonSingular(); }
+    ~FromMixtureSubstitutionModel() {}
 
-  const Vdouble& getEigenValues() const { return getModel().getEigenValues(); }
+    FromMixtureSubstitutionModel* clone() const { return new FromMixtureSubstitutionModel(*this); }
 
-  const Vdouble& getIEigenValues() const { return getModel().getIEigenValues(); }
+  public:
+    const SubstitutionModel& getSubstitutionModel() const
+    {
+      return *subModel_.get();
+    }
 
-  const Matrix<double>& getRowLeftEigenVectors() const { return getModel().getRowLeftEigenVectors(); }
+  protected:
+    SubstitutionModel& getSubstitutionModel()
+    {
+      return *subModel_.get();
+    }
 
-  const Matrix<double>& getColumnRightEigenVectors() const { return getModel().getColumnRightEigenVectors(); }
-
-  double getRate() const { return getModel().getRate(); }
-
-  void setRate(double rate) { return getModel().setRate(rate); }
-
-  void addRateParameter()
-  {
-    getModel().addRateParameter();
-    addParameter_(new Parameter(getNamespace() + "rate", getModel().getRate(), &Parameter::R_PLUS_STAR));
-  }
-
-  void setFreqFromData(const SequenceContainer& data, double pseudoCount = 0){getModel().setFreqFromData(data, pseudoCount); }
-
-  void setFreq(std::map<int, double>& frequ) {getModel().setFreq(frequ); }
-
-  const Alphabet* getAlphabet() const { return getModel().getAlphabet(); }
-
-  size_t getNumberOfStates() const { return getModel().getNumberOfStates(); }
-
-  double getInitValue(size_t i, int state) const throw (BadIntException) { return getModel().getInitValue(i, state); }
-
-  const FrequenciesSet* getFrequenciesSet() const {return getModel().getFrequenciesSet(); }
-
-  /*
-   * @}
-   *
-   */
-
-  /*
+  public:
+    /*
      *@ brief Methods to supersede AbstractSubstitutionModel methods.
-   *
-   * @{
-   */
-
-  /**
-   * @brief Tells the model that a parameter value has changed.
-   *
-   * This updates the matrices consequently.
-   */
-  void fireParameterChanged(const ParameterList& parameters)
-  {
-    AbstractParameterAliasable::fireParameterChanged(parameters);
-    getModel().matchParametersValues(parameters);
-  }
-
-  void setNamespace(const std::string& name)
-  {
-    AbstractParameterAliasable::setNamespace(name);
-    getModel().setNamespace(name);
-  }
-
-public:
-  bool isScalable() const 
-  {
-    return getModel().isScalable();
-  }
-
-  void setScalable(bool scalable)
-  {
-    getModel().setScalable(scalable);
-  }
-
-  void normalize()
-  {
-    getModel().normalize();
-  }
+     *
+     * @{
+     */
+
+    /**
+     * @brief Tells the model that a parameter value has changed.
+     *
+     * This updates the matrices consequently.
+     */
+    void fireParameterChanged(const ParameterList& parameters)
+    {
+      getModel().matchParametersValues(parameters);
+    }
+
+    virtual void setNamespace(const std::string& name)
+    {
+      AbstractParameterAliasable::setNamespace(name);
+      getModel().setNamespace(name);
+    }
+
+    virtual void addRateParameter()
+    {
+      getModel().addRateParameter();
+      addParameter_(new Parameter(getNamespace() + "rate", getModel().getRate(), &Parameter::R_PLUS_STAR)); 
+    }
     
-  double getScale() const { return getModel().getScale(); }
-
-  void setScale(double scale) { getModel().setScale(scale); }
-
-  /*
-   * @}
-   */
-
-  std::string getName() const;
-};
+    /*
+     * @}
+     */
+    
+    std::string getName() const
+    {
+      size_t posp = mixtName_.find("(");
+      
+      return mixtName_.substr(0, posp) + "_" + getModel().getName() + mixtName_.substr(posp);
+    }
+
+  protected:
+
+    void updateMatrices() 
+    {
+    }
+    
+    
+  };
 } // end of namespace bpp.
 
 #endif  // _FROM_MIXTURE_SUBSTITUTIONMODEL_H_
diff --git a/src/Bpp/Phyl/Model/FromMixtureSubstitutionModel.cpp b/src/Bpp/Phyl/Model/InMixedSubstitutionModel.cpp
similarity index 58%
copy from src/Bpp/Phyl/Model/FromMixtureSubstitutionModel.cpp
copy to src/Bpp/Phyl/Model/InMixedSubstitutionModel.cpp
index 959282d..9c3a61a 100644
--- a/src/Bpp/Phyl/Model/FromMixtureSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/InMixedSubstitutionModel.cpp
@@ -1,7 +1,7 @@
 //
-// File: FromMixtureSubstitutionModel.cpp
+// File: InMixedSubstitutionModel.cpp
 // Created by: Laurent Gueguen
-// Created on: samedi 24 octobre 2015, � 18h 50
+// Created on: vendredi 22 septembre 2017, � 09h 57
 //
 
 /*
@@ -37,57 +37,67 @@
    knowledge of the CeCILL license and that you accept its terms.
  */
 
-#include "FromMixtureSubstitutionModel.h"
+#include "InMixedSubstitutionModel.h"
 
 using namespace bpp;
 using namespace std;
 
 /******************************************************************************/
 
-FromMixtureSubstitutionModel::FromMixtureSubstitutionModel(const MixedSubstitutionModel& mixedModel, const std::string& subModelName, const std::string& mixtDesc) :
-  AbstractParameterAliasable(mixedModel.getName() + "_" + subModelName),
-  subModel_(),
+InMixedSubstitutionModel::InMixedSubstitutionModel(const MixedSubstitutionModel& mixedModel, const std::string& subModelName, const std::string& mixtDesc) :
+  AbstractParameterAliasable(mixedModel.getNamespace()),
+  mixedModel_(mixedModel.clone()),
+  subModelNumber_(0),
   mixtName_(mixtDesc)
 {
   const SubstitutionModel* sm = mixedModel.getSubModelWithName(subModelName);
 
   if (sm == 0)
-    throw ParameterNotFoundException("FromMixtureSubstitutionModel::FromMixtureSubstitutionModel : unknown model name", subModelName);
+    throw ParameterNotFoundException("InMixedSubstitutionModel::InMixedSubstitutionModel : unknown model name", subModelName);
+  else
+  {
+    Vint vn=mixedModel_->getSubmodelNumbers(subModelName);
+    subModelNumber_=(size_t)vn[0];
+  }
+  
+  addParameters_(mixedModel_->getParameters());
+}
 
-  subModel_ = std::unique_ptr<SubstitutionModel>(sm->clone());
-  subModel_->setNamespace(mixtName_);
+InMixedSubstitutionModel::InMixedSubstitutionModel(const MixedSubstitutionModel& mixedModel, size_t subModelNumber, const std::string& mixtDesc) :
+  AbstractParameterAliasable(mixedModel.getNamespace()),
+  mixedModel_(mixedModel.clone()),
+  subModelNumber_(subModelNumber),
+  mixtName_(mixtDesc)
+{
+  if (subModelNumber>=mixedModel.getNumberOfModels())
+    throw ParameterNotFoundException("InMixedSubstitutionModel::InMixedSubstitutionModel : bad model number", TextTools::toString(subModelNumber));
 
-  subModel_->setRate(1);
-  addParameters_(subModel_->getParameters());
+  addParameters_(mixedModel_->getParameters());
 }
 
 
 /******************************************************************************/
 
-FromMixtureSubstitutionModel::FromMixtureSubstitutionModel(const FromMixtureSubstitutionModel& fmsm) :
+InMixedSubstitutionModel::InMixedSubstitutionModel(const InMixedSubstitutionModel& fmsm) :
   AbstractParameterAliasable(fmsm),
-  subModel_(fmsm.subModel_->clone()),
+  mixedModel_(fmsm.mixedModel_->clone()),
+  subModelNumber_(fmsm.subModelNumber_),
   mixtName_(fmsm.mixtName_)
 {}
 
 
 /******************************************************************************/
 
-FromMixtureSubstitutionModel& FromMixtureSubstitutionModel::operator=(const FromMixtureSubstitutionModel& fmsm)
+InMixedSubstitutionModel& InMixedSubstitutionModel::operator=(const InMixedSubstitutionModel& fmsm)
 {
   AbstractParameterAliasable::operator=(fmsm);
 
-  subModel_ = std::unique_ptr<SubstitutionModel>(fmsm.subModel_->clone());
+  mixedModel_ = std::unique_ptr<MixedSubstitutionModel>(fmsm.mixedModel_->clone());
 
+  subModelNumber_ = fmsm.subModelNumber_;
+  
   mixtName_ = fmsm.mixtName_;
 
   return *this;
 }
 
-
-std::string FromMixtureSubstitutionModel::getName() const
-{
-  size_t posp = mixtName_.find("(");
-
-  return mixtName_.substr(0, posp) + "_" + getModel().getName() + mixtName_.substr(posp);
-}
diff --git a/src/Bpp/Phyl/Model/InMixedSubstitutionModel.h b/src/Bpp/Phyl/Model/InMixedSubstitutionModel.h
new file mode 100644
index 0000000..5acc6e5
--- /dev/null
+++ b/src/Bpp/Phyl/Model/InMixedSubstitutionModel.h
@@ -0,0 +1,314 @@
+//
+// File: InMixtureSubstitutionModel.h
+// Created by: Laurent Gueguen
+// Created on: vendredi 22 septembre 2017, � 09h 57
+//
+
+/*
+  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 _IN_MIXED_SUBSTITUTIONMODEL_H_
+#define _IN_MIXED_SUBSTITUTIONMODEL_H_
+
+#include "AbstractSubstitutionModel.h"
+#include "MixedSubstitutionModel.h"
+#include "AbstractWrappedModel.h"
+
+namespace bpp
+{
+/**
+ * @brief SubModel taken from a MixedSubstitutionModel, kept in the
+ * context of the MixedSubstitutionModel (see
+ * FromMixtureSubstitutionModel for an out of context subModel). So
+ * "rate" and "scale" are set for the MixedSubstitutionModel.
+ *
+ * But method getRate returns the specific rate of the subModel.
+ *
+ * It owns the MixedSubstitutionModel.
+ *
+ * It has the same parameters as the MixedSubstitutionModel.
+ */
+  
+  class InMixedSubstitutionModel :
+    public virtual AbstractWrappedSubstitutionModel,
+    public AbstractParameterAliasable
+  {
+  private:
+    /*
+     * @brief The MixedOfSubstitutionModels.
+     *
+     */
+
+    std::unique_ptr<MixedSubstitutionModel> mixedModel_;
+
+    /*
+     * @brief the number of the submodel
+     *
+     */
+
+    size_t subModelNumber_;
+  
+    /*
+     * @brief The name of the mixture model (for io purpose).
+     */
+
+    std::string mixtName_;
+
+  public:
+    InMixedSubstitutionModel(const MixedSubstitutionModel& mixedModel, const std::string& subModelName, const std::string& mixtDesc);
+
+    InMixedSubstitutionModel(const MixedSubstitutionModel& mixedModel, size_t subModelNumber, const std::string& mixtDesc);
+
+    InMixedSubstitutionModel(const InMixedSubstitutionModel& fmsm);
+
+    InMixedSubstitutionModel& operator=(const InMixedSubstitutionModel& fmsm);
+
+    InMixedSubstitutionModel* clone() const { return new InMixedSubstitutionModel(*this); }
+
+  public:
+    
+    const MixedSubstitutionModel& getMixedModel() const
+    {
+      return *mixedModel_.get();
+    }
+
+    const SubstitutionModel& getSubstitutionModel() const
+    {
+      return *mixedModel_->getNModel(subModelNumber_);
+    }
+
+    size_t getSubModelNumber() const
+    {
+      return subModelNumber_;
+    }
+
+    bool computeFrequencies() const
+    {
+      return getMixedModel().computeFrequencies();
+    }
+
+    /**
+     * @return Set if equilibrium frequencies should be computed from
+     * the generator
+     */
+    
+    void computeFrequencies(bool yn)
+    {
+      getMixedModel().computeFrequencies(yn);
+    }
+
+  protected:
+
+    Vdouble& getFrequencies_()
+    {
+      return getMixedModel().getFrequencies_();
+    }
+
+    /*
+     * @}
+     *
+     */
+
+    MixedSubstitutionModel& getMixedModel()
+    {
+      return *mixedModel_.get();
+    }
+
+    SubstitutionModel& getSubstitutionModel()
+    {
+      return *mixedModel_->getNModel(subModelNumber_);
+    }
+
+  public:
+
+    
+    /*
+     *@ brief Methods to supersede WrappedSubstitutionModel methods.
+     *
+     * @{
+     */
+
+    double freq(size_t i) const { return getModel().freq(i); }
+
+    double Pij_t    (size_t i, size_t j, double t) const { return getModel().Pij_t(i, j, t); }
+    double dPij_dt  (size_t i, size_t j, double t) const { return getModel().dPij_dt (i, j, t); }
+    double d2Pij_dt2(size_t i, size_t j, double t) const { return getModel().d2Pij_dt2(i, j, t); }
+
+    const Vdouble& getFrequencies() const { return getModel().getFrequencies(); }
+
+    const Matrix<double>& getPij_t(double t) const { return getModel().getPij_t(t); }
+
+    const Matrix<double>& getdPij_dt(double t) const { return getModel().getdPij_dt(t); }
+
+    const Matrix<double>& getd2Pij_dt2(double t) const { return getModel().getd2Pij_dt2(t); }
+
+    double getInitValue(size_t i, int state) const throw (IndexOutOfBoundsException, BadIntException)
+    {
+      return getModel().getInitValue(i,state);
+    }
+    
+    void setFreqFromData(const SequenceContainer& data, double pseudoCount = 0)
+    {
+      getMixedModel().setFreqFromData(data, pseudoCount);
+    }
+    
+    void setFreq(std::map<int, double>& frequencies)
+    {
+      getMixedModel().setFreq(frequencies);
+    }
+
+    /*
+     *@ brief Methods to supersede SubstitutionModel methods.
+     *
+     * @{
+     */
+
+    double Qij(size_t i, size_t j) const { return getSubstitutionModel().Qij(i, j); }
+
+    const Matrix<double>& getGenerator() const { return getSubstitutionModel().getGenerator(); }
+
+    const Matrix<double>& getExchangeabilityMatrix() const { return getSubstitutionModel().getExchangeabilityMatrix(); }
+
+    double Sij(size_t i, size_t j) const { return getSubstitutionModel().Sij(i, j); }
+
+    void enableEigenDecomposition(bool yn) { getMixedModel().enableEigenDecomposition(yn); }
+
+    bool enableEigenDecomposition() { return getMixedModel().enableEigenDecomposition(); }
+
+    bool isDiagonalizable() const { return getSubstitutionModel().isDiagonalizable(); }
+
+    bool isNonSingular() const { return getSubstitutionModel().isNonSingular(); }
+
+    const Vdouble& getEigenValues() const { return getSubstitutionModel().getEigenValues(); }
+
+    const Vdouble& getIEigenValues() const { return getSubstitutionModel().getIEigenValues(); }
+
+    const Matrix<double>& getRowLeftEigenVectors() const { return getSubstitutionModel().getRowLeftEigenVectors(); }
+
+    const Matrix<double>& getColumnRightEigenVectors() const { return getSubstitutionModel().getColumnRightEigenVectors(); }
+
+
+    /*
+     * @}
+     *
+     */
+
+    bool isScalable() const 
+    {
+      return getMixedModel().isScalable();
+    }
+
+    void setScalable(bool scalable)
+    {
+      getMixedModel().setScalable(scalable);
+    }
+
+ 
+    double getScale() const { return getMixedModel().getScale(); }
+
+    void setScale(double scale) { getMixedModel().setScale(scale); }
+
+
+    void normalize()
+    {
+      getMixedModel().normalize();
+    }
+
+    void setDiagonal()
+    {
+      getMixedModel().setDiagonal();
+    }
+
+    double getRate() const
+    {
+      return getModel().getRate();
+    }
+
+    void setRate(double rate)
+    {
+      return getMixedModel().setRate(rate);
+    }
+    
+    void addRateParameter()
+    {
+      getMixedModel().addRateParameter();
+      addParameter_(new Parameter(getNamespace() + "rate", getMixedModel().getRate(), &Parameter::R_PLUS_STAR));
+    }
+
+    /*
+     * @}
+     *
+     */
+
+    /*
+     *@ brief Methods to supersede AbstractSubstitutionModel methods.
+     *
+     * @{
+     */
+
+    /**
+     * @brief Tells the model that a parameter value has changed.
+     *
+     * This updates the matrices consequently.
+     */
+    void fireParameterChanged(const ParameterList& parameters)
+    {
+      getMixedModel().matchParametersValues(parameters);
+    }
+
+    void setNamespace(const std::string& name)
+    {
+      AbstractParameterAliasable::setNamespace(name);
+      getMixedModel().setNamespace(name);
+    }
+
+
+    /*
+     * @}
+     */
+
+    std::string getName() const
+    {
+      return mixedModel_->getName();
+    }
+
+  protected:
+
+    void updateMatrices() 
+    {
+    }
+  };
+  
+} // end of namespace bpp.
+
+#endif  // _IN_MIXED_SUBSTITUTIONMODEL_H_
diff --git a/src/Bpp/Phyl/Model/MarkovModulatedSubstitutionModel.cpp b/src/Bpp/Phyl/Model/MarkovModulatedSubstitutionModel.cpp
index e706148..530f5ea 100644
--- a/src/Bpp/Phyl/Model/MarkovModulatedSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/MarkovModulatedSubstitutionModel.cpp
@@ -66,6 +66,7 @@ MarkovModulatedSubstitutionModel::MarkovModulatedSubstitutionModel(
   eigenValues_         (model.eigenValues_),
   iEigenValues_        (model.iEigenValues_),
   eigenDecompose_      (model.eigenDecompose_),
+  compFreq_            (model.compFreq_),
   pijt_                (model.pijt_),
   dpijt_               (model.dpijt_),
   d2pijt_              (model.d2pijt_),
@@ -93,6 +94,7 @@ MarkovModulatedSubstitutionModel& MarkovModulatedSubstitutionModel::operator=(
   eigenValues_          = model.eigenValues_;
   iEigenValues_         = model.iEigenValues_;
   eigenDecompose_       = model.eigenDecompose_;
+  compFreq_             = model.compFreq_;
   pijt_                 = model.pijt_;
   dpijt_                = model.dpijt_;
   d2pijt_               = model.d2pijt_;
@@ -174,6 +176,22 @@ void MarkovModulatedSubstitutionModel::updateMatrices()
   MatrixTools::inv(rightEigenVectors_, leftEigenVectors_);
 }
 
+void MarkovModulatedSubstitutionModel::setDiagonal()
+{
+  for (size_t i = 0; i < getNumberOfStates(); i++)
+  {
+    double lambda=0;
+    Vdouble& row=generator_.getRow(i);
+    
+    for (size_t j = 0; j < getNumberOfStates(); j++)
+    {
+      if (j != i)
+        lambda += row[j];
+    }
+    row[i] = -lambda;
+  }
+}
+
 /******************************************************************************/
 
 const Matrix<double>& MarkovModulatedSubstitutionModel::getPij_t(double t) const
diff --git a/src/Bpp/Phyl/Model/MarkovModulatedSubstitutionModel.h b/src/Bpp/Phyl/Model/MarkovModulatedSubstitutionModel.h
index 9e33716..5679b62 100644
--- a/src/Bpp/Phyl/Model/MarkovModulatedSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/MarkovModulatedSubstitutionModel.h
@@ -49,28 +49,34 @@ namespace bpp
 {
 
   /**
-   * @brief Partial implementation of the Markov-modulated class of substitution
-   * models.
+   * @brief Partial implementation of the Markov-modulated class of
+   * substitution models.
    *
-   * This class wraps a substitution model and provide a matrix describing rate changes.
-   * The rate matrix must be initialized by derived classes of this class.
-   * Using these matrices, the diagonalization procedure of Galtier and Jean-Marie is used.
+   * This class wraps a substitution model and provide a matrix
+   * describing rate changes. The rate matrix must be initialized by
+   * derived classes of this class. Using these matrices, the
+   * diagonalization procedure of Galtier and Jean-Marie is used.
    *
    * Such models can be described using two matrices:
-   * a substitution matrix, @f$M at f$, with size @f$m at f$, which is a "standard" substitution model of any alphabet type,
+   * a substitution matrix, @f$M at f$, with size @f$m at f$, which is a
+   * "standard" substitution model of any alphabet type,
    * and a rate matrix @f$G at f$ of size @f$g at f$.
-   * The generator of the markov-modulated model, @f$Q at f$ can be written using Kronecker matrix operands:
+   * The generator of the markov-modulated model, @f$Q at f$ can be
+   * written using Kronecker matrix operands.
    * @f[
    * Q=D_R \otimes M + G \otimes I_m,
    * @f]
-   * where @f$D_R at f$ is the diagonal matrix of all rates, and @f$I_m at f$ is the identity matrix of size @f$m at f$.
+   * where @f$D_R at f$ is the diagonal matrix of all rates, and
+   * @f$I_m at f$ is the identity matrix of size @f$m at f$.
    *
-   * This generator is normalized so that branch lengths are measured in unit of mean number of substitutions per site,
-   * where susbstitution here means "change of alphabet state".
+   * This generator is normalized so that branch lengths are measured
+   * in unit of mean number of substitutions per site, where
+   * susbstitution here means "change of alphabet 
    * Rate changes are not counted.
    *
-   * Galtier N. and Jean-Marie A., Markov-modulated Markov chains and the covarion process of molecular evolution (2004).
-   * _Journal of Computational Biology_, 11:727-33.
+   * Galtier N. and Jean-Marie A., Markov-modulated Markov chains and
+   * the covarion process of molecular evolution (2004). _Journal of
+   * Computational Biology_, 11:727-33.
    */
   class MarkovModulatedSubstitutionModel:
     public virtual ReversibleSubstitutionModel,
@@ -132,6 +138,13 @@ namespace bpp
     bool eigenDecompose_;
 
     /**
+     * @brief Tell if the equilibrium frequencies  should be computed
+     * from the generator
+     */
+    
+    bool compFreq_;
+
+    /**
      * @brief These ones are for bookkeeping:
      */
     mutable RowMatrix<double> pijt_;
@@ -163,7 +176,7 @@ namespace bpp
       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), 
+      leftEigenVectors_(), rightEigenVectors_(), eigenValues_(), iEigenValues_(), eigenDecompose_(true), compFreq_(false), 
       pijt_(), dpijt_(), d2pijt_(), freq_(),
       normalizeRateChanges_(normalizeRateChanges),
       nestedPrefix_("model_" + model->getNamespace())
@@ -271,7 +284,9 @@ namespace bpp
       model_->normalize();
       updateMatrices();
     }
-    
+
+    void setDiagonal();
+
     double getScale() const
     {
       std::vector<double> v;
@@ -287,7 +302,12 @@ namespace bpp
     void enableEigenDecomposition(bool yn) { eigenDecompose_ = yn; }
 
     bool enableEigenDecomposition() { return eigenDecompose_; }
-	
+
+    bool computeFrequencies() const { return compFreq_; }
+    
+    void computeFrequencies(bool yn) { compFreq_ = yn; }
+      
+
     /**
      * @brief Tells the model that a parameter value has changed.
      *
@@ -315,6 +335,12 @@ namespace bpp
      */
     virtual void updateRatesModel() = 0;
 
+    Vdouble& getFrequencies_()
+    {
+      return freq_;
+    }
+    
+
   };
 
 } //end of namespace bpp.
diff --git a/src/Bpp/Phyl/Model/MixedSubstitutionModel.h b/src/Bpp/Phyl/Model/MixedSubstitutionModel.h
index d4df76e..8f57eff 100644
--- a/src/Bpp/Phyl/Model/MixedSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/MixedSubstitutionModel.h
@@ -137,7 +137,7 @@ namespace bpp
      *
      */
   
-    virtual Vint getSubmodelNumbers(std::string& desc) const = 0;
+    virtual Vint getSubmodelNumbers(const std::string& desc) const = 0;
 
 
   };
diff --git a/src/Bpp/Phyl/Model/MixedSubstitutionModelSet.cpp b/src/Bpp/Phyl/Model/MixedSubstitutionModelSet.cpp
index 3af933a..576ebaa 100644
--- a/src/Bpp/Phyl/Model/MixedSubstitutionModelSet.cpp
+++ b/src/Bpp/Phyl/Model/MixedSubstitutionModelSet.cpp
@@ -116,7 +116,7 @@ bool MixedSubstitutionModelSet::complete()
   size_t nbm = getNumberOfModels();
   for (i = 0; i < nbm; i++)
   {
-    const MixedSubstitutionModel* pSM = dynamic_cast<const MixedSubstitutionModel*>(getTransitionModel(i));
+    const MixedSubstitutionModel* pSM = dynamic_cast<const MixedSubstitutionModel*>(getModel(i));
     if (pSM)
     {
       if (nhn.getNode(i).size() != pSM->getNumberOfModels())
@@ -130,7 +130,7 @@ bool MixedSubstitutionModelSet::complete()
   addEmptyHyperNode();
   for (i = 0; i < nbm; i++)
   {
-    const MixedSubstitutionModel* pSM = dynamic_cast<const MixedSubstitutionModel*>(getTransitionModel(i));
+    const MixedSubstitutionModel* pSM = dynamic_cast<const MixedSubstitutionModel*>(getModel(i));
     if (pSM)
     {
       const MixedSubstitutionModelSet::HyperNode::Node& nd = nhn.getNode(i);
@@ -203,7 +203,7 @@ void MixedSubstitutionModelSet::computeHyperNodesProbabilities()
   MixedSubstitutionModel* pfSM = 0;
   for (fmM = 0; fmM < nbm; fmM++)
   {
-    pfSM = dynamic_cast<MixedSubstitutionModel*>(getTransitionModel(fmM));
+    pfSM = dynamic_cast<MixedSubstitutionModel*>(getModel(fmM));
     if (pfSM != NULL)
       break;
   }
@@ -233,7 +233,7 @@ void MixedSubstitutionModelSet::computeHyperNodesProbabilities()
 
   for (size_t iM = fmM + 1; iM < nbm; iM++)
   {
-    pfSM = dynamic_cast<MixedSubstitutionModel*>(getTransitionModel(iM));
+    pfSM = dynamic_cast<MixedSubstitutionModel*>(getModel(iM));
     if (pfSM != NULL)
     {
       for (size_t nh = 0; nh < nbh; nh++)
@@ -280,7 +280,7 @@ double MixedSubstitutionModelSet::getHyperNodeProbability(const HyperNode& hn) c
   for (size_t fmM = 0; fmM < nbm; fmM++)
   {
     const MixedSubstitutionModelSet::HyperNode::Node& fnd = hn.getNode(fmM);
-    const MixedSubstitutionModel* pfSM = dynamic_cast<const MixedSubstitutionModel*>(getTransitionModel(fmM));
+    const MixedSubstitutionModel* pfSM = dynamic_cast<const MixedSubstitutionModel*>(getModel(fmM));
     if (pfSM != NULL)
     {
       double x = 0;
@@ -308,7 +308,7 @@ MixedSubstitutionModelSet::HyperNode::HyperNode(const MixedSubstitutionModelSet*
 {
   for (size_t i = 0; i < pMSMS->getNumberOfModels(); i++)
   {
-    const MixedSubstitutionModel* pSM = dynamic_cast<const MixedSubstitutionModel*>(pMSMS->getTransitionModel(i));
+    const MixedSubstitutionModel* pSM = dynamic_cast<const MixedSubstitutionModel*>(pMSMS->getModel(i));
     if (!pSM)
       vUnused_.push_back(static_cast<int>(i));
   }
diff --git a/src/Bpp/Phyl/Model/MixedSubstitutionModelSet.h b/src/Bpp/Phyl/Model/MixedSubstitutionModelSet.h
index 4ec7694..e43d2c2 100644
--- a/src/Bpp/Phyl/Model/MixedSubstitutionModelSet.h
+++ b/src/Bpp/Phyl/Model/MixedSubstitutionModelSet.h
@@ -304,21 +304,21 @@ public:
   void clear();
 
   /*
-     *@brief adds a new empty HyperNode to the end of the HyperNodes
+   *@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
+   *@brief adds the copy of an HyperNode to the end of the
    * HyperNodes list.
    */
 
   void addHyperNode(const HyperNode& hn);
 
   /*
-     *@brief If necessary, adds a new HyperNode such that all
+   *@brief If necessary, adds a new HyperNode such that all
    *       submodels of the mixture models are at least in an
    *       HyperNode.
    *
@@ -329,13 +329,13 @@ public:
   bool complete();
 
   /*
-     *@brief adds a submodel number to the nMth mixed model of the
+   *@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
+   *@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)
    */
 
@@ -348,7 +348,7 @@ public:
   const HyperNode& getHyperNode(size_t i) const {return *vpHyperNodes_[i]; }
 
   /*
-     *@brief Checks if all the path (ie hypernodes) are exclusive.
+   *@brief Checks if all the path (ie hypernodes) are exclusive.
    *
    */
 
@@ -357,26 +357,25 @@ public:
   void fireParameterChanged(const ParameterList& parameters);
 
   /*
-     *@brief compute the probabilities in all the HyperNodes
+   *@brief compute the probabilities in all the HyperNodes
    *
    */
 
   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.
+   *@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.
+   *     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.
+   *@param hn the HyperNode which conditional probability is computed.
    */
 
   double getHyperNodeProbability(const HyperNode& hn) const;
diff --git a/src/Bpp/Phyl/Model/MixtureOfASubstitutionModel.cpp b/src/Bpp/Phyl/Model/MixtureOfASubstitutionModel.cpp
index ebdea62..30a851a 100644
--- a/src/Bpp/Phyl/Model/MixtureOfASubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/MixtureOfASubstitutionModel.cpp
@@ -287,7 +287,7 @@ const SubstitutionModel* MixtureOfASubstitutionModel::getSubModelWithName(const
   return NULL;
 }
 
-Vint MixtureOfASubstitutionModel::getSubmodelNumbers(string& desc) const
+Vint MixtureOfASubstitutionModel::getSubmodelNumbers(const string& desc) const
 {
   vector<string> parnames = modelsContainer_[0]->getParameters().getParameterNames();
   std::map<std::string, size_t> msubn;
diff --git a/src/Bpp/Phyl/Model/MixtureOfASubstitutionModel.h b/src/Bpp/Phyl/Model/MixtureOfASubstitutionModel.h
index 358cc2d..2ea2886 100644
--- a/src/Bpp/Phyl/Model/MixtureOfASubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/MixtureOfASubstitutionModel.h
@@ -145,7 +145,7 @@ public:
    *
    */
 
-  Vint getSubmodelNumbers(std::string& desc) const;
+  Vint getSubmodelNumbers(const std::string& desc) const;
 
   /**
    * @brief sets the eq frequencies of the first nested model, and
diff --git a/src/Bpp/Phyl/Model/MixtureOfSubstitutionModels.cpp b/src/Bpp/Phyl/Model/MixtureOfSubstitutionModels.cpp
index 4ebe65b..e72f9d6 100644
--- a/src/Bpp/Phyl/Model/MixtureOfSubstitutionModels.cpp
+++ b/src/Bpp/Phyl/Model/MixtureOfSubstitutionModels.cpp
@@ -305,7 +305,7 @@ void MixtureOfSubstitutionModels::setVRates(const Vdouble& vd)
   }
 }
 
-Vint MixtureOfSubstitutionModels::getSubmodelNumbers(string& desc) const
+Vint MixtureOfSubstitutionModels::getSubmodelNumbers(const string& desc) const
 {
   size_t i;
   for (i = 0; i < getNumberOfModels(); i++)
diff --git a/src/Bpp/Phyl/Model/MixtureOfSubstitutionModels.h b/src/Bpp/Phyl/Model/MixtureOfSubstitutionModels.h
index e36114f..43b5c1e 100644
--- a/src/Bpp/Phyl/Model/MixtureOfSubstitutionModels.h
+++ b/src/Bpp/Phyl/Model/MixtureOfSubstitutionModels.h
@@ -188,7 +188,7 @@ public:
    * @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;
+  Vint getSubmodelNumbers(const std::string& desc) const;
 
   /**
    * @brief applies setFreq to all the models of the mixture and
diff --git a/src/Bpp/Phyl/Model/Nucleotide/L95.cpp b/src/Bpp/Phyl/Model/Nucleotide/L95.cpp
index 6d6daca..e2704e0 100755
--- a/src/Bpp/Phyl/Model/Nucleotide/L95.cpp
+++ b/src/Bpp/Phyl/Model/Nucleotide/L95.cpp
@@ -66,6 +66,7 @@ L95::L95(
   addParameter_(new Parameter("L95.kappa", kappa, new IntervalConstraint(0, 1000, false, false, NumConstants::MILLI()), true));
   addParameter_(new Parameter("L95.theta", theta, new IntervalConstraint(0, 1, false, false, NumConstants::MILLI()), true));
 
+  computeFrequencies(false);  
   updateMatrices();
 }
 
diff --git a/src/Bpp/Phyl/Model/Nucleotide/RN95.cpp b/src/Bpp/Phyl/Model/Nucleotide/RN95.cpp
index 01b58cf..acb70a8 100644
--- a/src/Bpp/Phyl/Model/Nucleotide/RN95.cpp
+++ b/src/Bpp/Phyl/Model/Nucleotide/RN95.cpp
@@ -114,6 +114,7 @@ RN95::RN95(
   addParameter_(new Parameter("RN95.alphaP", alphaP, new IntervalConstraint(1, 1, false), true));
   addParameter_(new Parameter("RN95.sigmaP", sigmaP, new IntervalConstraint(1, 1, false), true));
 
+  computeFrequencies(false);
   updateMatrices();
 }
 
diff --git a/src/Bpp/Phyl/Model/Nucleotide/RN95s.cpp b/src/Bpp/Phyl/Model/Nucleotide/RN95s.cpp
index a0339ba..032eba0 100644
--- a/src/Bpp/Phyl/Model/Nucleotide/RN95s.cpp
+++ b/src/Bpp/Phyl/Model/Nucleotide/RN95s.cpp
@@ -85,6 +85,7 @@ RN95s::RN95s(const NucleicAlphabet* alphabet,
   addParameter_(new Parameter("RN95s.gamma", gamma_, new IntervalConstraint(0, 0.5, false, false), true));
   addParameter_(new Parameter("RN95s.alphaP", alphaP, new IntervalConstraint(1, 1, false), true));
 
+  computeFrequencies(false);
   updateMatrices();
 }
 
diff --git a/src/Bpp/Phyl/Model/Nucleotide/YpR.cpp b/src/Bpp/Phyl/Model/Nucleotide/YpR.cpp
index 21c1433..0e427e6 100644
--- a/src/Bpp/Phyl/Model/Nucleotide/YpR.cpp
+++ b/src/Bpp/Phyl/Model/Nucleotide/YpR.cpp
@@ -59,7 +59,10 @@ YpR::YpR(const RNY* alph, SubstitutionModel* const pm, const std::string& prefix
 {
   pmodel_->setNamespace(prefix + _nestedPrefix);
   pmodel_->enableEigenDecomposition(0);
+  pmodel_->computeFrequencies(false);
+
   addParameters_(pmodel_->getParameters());
+  computeFrequencies(true);
 }
 
 YpR::YpR(const YpR& ypr, const std::string& prefix) :
diff --git a/src/Bpp/Phyl/Model/Nucleotide/gBGC.cpp b/src/Bpp/Phyl/Model/Nucleotide/gBGC.cpp
index 68ea70d..fc5aa13 100644
--- a/src/Bpp/Phyl/Model/Nucleotide/gBGC.cpp
+++ b/src/Bpp/Phyl/Model/Nucleotide/gBGC.cpp
@@ -58,9 +58,12 @@ gBGC::gBGC(const NucleicAlphabet* alph, NucleotideSubstitutionModel* const pm, d
 {
   model_->setNamespace("gBGC." + nestedPrefix_);
   model_->enableEigenDecomposition(0);
+  model_->computeFrequencies(false);
+  
   addParameters_(model_->getParameters());
   addParameter_(new Parameter("gBGC.B", B_, new IntervalConstraint(-999, 10, true, true), true));
 
+  computeFrequencies(true);
   updateMatrices();
 }
 
diff --git a/src/Bpp/Phyl/Model/Nucleotide/gBGC.h b/src/Bpp/Phyl/Model/Nucleotide/gBGC.h
index 5eca0ab..e9d731e 100644
--- a/src/Bpp/Phyl/Model/Nucleotide/gBGC.h
+++ b/src/Bpp/Phyl/Model/Nucleotide/gBGC.h
@@ -68,9 +68,9 @@ namespace bpp
  * corresponds to fixation, and stands for a dubious selection.
  *
  * With this term, the mutation rates from A and T to C and G are
- * multiplied by @f$ \frac{B}{2} . \frac{1}{1-exp(-B)}@f$, and
+ * multiplied by @f$ B . \frac{1}{1-exp(-B)}@f$, and
  * the mutation rates from C and G to A and T are multiplied by
- * @f$ \frac{B}{2} . \frac{1}{exp(B)-1}@f$.
+ * @f$ B . \frac{1}{exp(B)-1}@f$.
  *
  * @see AbstractSubstitutionModel
  *
diff --git a/src/Bpp/Phyl/Model/OneChangeRegisterTransitionModel.cpp b/src/Bpp/Phyl/Model/OneChangeRegisterTransitionModel.cpp
new file mode 100644
index 0000000..53039e4
--- /dev/null
+++ b/src/Bpp/Phyl/Model/OneChangeRegisterTransitionModel.cpp
@@ -0,0 +1,422 @@
+//
+// File: OneChangeRegisterTransitionModel.cpp
+// Created by: Laurent Gueguen
+// Created on: samedi 24 octobre 2015, � 18h 50
+//
+
+/*
+   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 "OneChangeRegisterTransitionModel.h"
+#include <Bpp/Numeric/Matrix/MatrixTools.h>
+
+using namespace bpp;
+using namespace std;
+
+OneChangeRegisterTransitionModel::OneChangeRegisterTransitionModel(const SubstitutionModel& originalModel, const SubstitutionRegister& reg, size_t numReg) :
+  AbstractParameterAliasable("OneChange."),
+  AbstractFromSubstitutionModelTransitionModel(originalModel, "OneChange."),
+  otherChanges_(getNumberOfStates()),
+  modelChanged_(new AnonymousSubstitutionModel(getAlphabet(), originalModel.getStateMap().clone())),
+  registerName_(reg.getName()),
+  vNumRegs_(vector<size_t>(1,numReg))
+{
+  if ((numReg<=0) || (numReg>reg.getNumberOfSubstitutionTypes()))
+    throw IndexOutOfBoundsException("OneChangeRegisterTransitionModel::OneChangeRegisterTransitionModel : wrong number for register category", numReg, 1, reg.getNumberOfSubstitutionTypes());
+
+  for (size_t i=0;i<size_;i++)
+    for (size_t j=0;j<size_;j++)
+      if (reg.getType(i,j)!=numReg)
+        otherChanges_[i].push_back(j);
+      else
+        modelChanged_->setGenerator()(i,j)=0;
+
+  updateMatrices();
+  
+}
+
+OneChangeRegisterTransitionModel::OneChangeRegisterTransitionModel(const SubstitutionModel& originalModel, const SubstitutionRegister& reg, vector<size_t> vNumRegs) :
+  AbstractParameterAliasable("OneChange."),
+  AbstractFromSubstitutionModelTransitionModel(originalModel, "OneChange."),
+  otherChanges_(getNumberOfStates()),
+  modelChanged_(new AnonymousSubstitutionModel(getAlphabet(), originalModel.getStateMap().clone())),
+  registerName_(reg.getName()),
+  vNumRegs_(vNumRegs)
+{
+  for (const auto& numReg : vNumRegs_)
+    if ((numReg<=0) || (numReg>reg.getNumberOfSubstitutionTypes()))
+      throw IndexOutOfBoundsException("OneChangeRegisterTransitionModel::OneChangeRegisterTransitionModel : wrong number for register category", numReg, 1, reg.getNumberOfSubstitutionTypes());
+
+  for (size_t i=0;i<size_;i++)
+    for (size_t j=0;j<size_;j++)
+    {
+      bool othCh=true;
+      size_t regt=reg.getType(i,j);
+      
+      for (const auto& numReg : vNumRegs_)
+      {
+        if (regt==numReg)
+        {
+          othCh=false;
+          break;
+        }
+      }
+      if (othCh)
+        otherChanges_[i].push_back(j);
+      else
+        modelChanged_->setGenerator()(i,j)=0;
+    }
+
+  updateMatrices();  
+}
+
+/******************************************************************************/
+
+void OneChangeRegisterTransitionModel::updateMatrices()
+{
+  const RowMatrix<double>& gen=getSubstitutionModel().getGenerator();
+  
+  for (size_t i = 0; i < size_; i++)
+    for (const auto& j : otherChanges_[i])
+      modelChanged_->setGenerator()(i,j)=gen(i, j);
+
+  modelChanged_->updateMatrices();
+}
+
+double OneChangeRegisterTransitionModel::Pij_t(size_t i, size_t j, double t) const
+{
+  if (t==0)
+  {
+    const RowMatrix<double>& gen=getSubstitutionModel().getGenerator();
+    double si=-VectorTools::sum(gen.getRow(i));
+    if (si!=0)
+      return (getSubstitutionModel().getGenerator()(i,j)-modelChanged_->getGenerator()(i,j))/si;
+    else
+      return (i==j)?1:0;
+  }
+
+  const RowMatrix<double>& ch_t=modelChanged_->getPij_t(t);
+
+  double si=1-VectorTools::sum(ch_t.getRow(i));
+  if (si==0)
+    return getModel().Pij_t(i,j,t);
+
+  return (getModel().Pij_t(i,j,t)-ch_t(i,j))/si;
+}
+
+double OneChangeRegisterTransitionModel::dPij_dt  (size_t i, size_t j, double t) const
+{
+
+  if (t==0)
+  {
+    const RowMatrix<double>& Qch=modelChanged_->getGenerator();
+    double si=VectorTools::sum(Qch.getRow(i));
+
+    if (si==0)
+      return 0;
+
+    RowMatrix<double> Qch2;
+
+    MatrixTools::mult<double>(Qch,Qch,Qch2);
+    double dsi=VectorTools::sum(Qch2.getRow(i));
+
+    const RowMatrix<double>& Q=getSubstitutionModel().getGenerator();
+    double q2ij(0);
+
+    for (size_t k = 0; k < size_; ++k)
+      q2ij+=Q(i,k)*Q(k,j);
+    
+    return ((-q2ij+Qch2(i,j))/si + (Q(i,j)-Qch(i,j))*dsi/(si*si))/2;
+  }
+  
+  const RowMatrix<double>& ch_t=modelChanged_->getPij_t(t);
+  const RowMatrix<double>& dch_dt=modelChanged_->getdPij_dt(t);
+
+  double si=1-VectorTools::sum(ch_t.getRow(i));
+  if (si==0)
+    return getModel().dPij_dt(i,j,t);
+  
+  double dsi=-VectorTools::sum(dch_dt.getRow(i));
+  
+  return ((getModel().dPij_dt(i,j,t)-dch_dt(i,j))*si-dsi*(getModel().Pij_t(i,j,t)-ch_t(i,j)))/(si*si);
+}
+
+double OneChangeRegisterTransitionModel::d2Pij_dt2(size_t i, size_t j, double t) const
+{
+  if (t==0)
+  {
+    const RowMatrix<double>& Q=getSubstitutionModel().getGenerator();
+    const RowMatrix<double>& Qch=modelChanged_->getGenerator();
+    double si=VectorTools::sum(Qch.getRow(i));
+
+    if (si==0)
+      return 0;
+
+    RowMatrix<double> Q2;
+    MatrixTools::mult<double>(Q,Q,Q2);
+
+    RowMatrix<double> Qch2, Qch3;
+    MatrixTools::mult<double>(Qch,Qch,Qch2);
+    MatrixTools::mult<double>(Qch,Qch2,Qch3);
+    
+    double dsi=VectorTools::sum(Qch2.getRow(i));
+    double d2si=VectorTools::sum(Qch3.getRow(i));
+
+    double q3ij(0);
+
+    for (size_t k = 0; k < size_; ++k)
+      q3ij+=Q2(i,k)*Q(k,j);
+    
+    return ((Q(i,j)-Qch(i,j))*(si*d2si/3-dsi*dsi/2)+(Q2(i,j)-Qch2(i,j))*si*dsi/2-(q3ij-Qch3(i,j))*si*si/3)/(si*si*si);
+  }
+  
+  const RowMatrix<double>& ch_t=modelChanged_->getPij_t(t);
+  const RowMatrix<double>& dch_dt=modelChanged_->getdPij_dt(t);
+  const RowMatrix<double>& d2ch_dt2=modelChanged_->getd2Pij_dt2(t);
+
+  double d2u=getModel().d2Pij_dt2(i,j,t)-d2ch_dt2(i,j);
+  double du=getModel().dPij_dt(i,j,t)-dch_dt(i,j);
+  double u=getModel().Pij_t(i,j,t)-ch_t(i,j);
+  
+  double si=1-VectorTools::sum(ch_t.getRow(i));
+  if (si==0)
+    return 0;
+
+  double si2=si*si;
+  double dsi=VectorTools::sum(dch_dt.getRow(i));
+  double d2si=VectorTools::sum(d2ch_dt2.getRow(i));
+  
+  return (d2u*si-d2si*u)/si-2*dsi*du/si2+2*dsi*dsi*u/(si2*si);
+}
+
+const Matrix<double>& OneChangeRegisterTransitionModel::getPij_t(double t) const
+{
+  if (t==0)
+  {
+    const RowMatrix<double>& Q=getSubstitutionModel().getGenerator();
+    const RowMatrix<double>& Qch=modelChanged_->getGenerator();
+
+    for (size_t i=0;i<size_;i++)
+    {
+      vector<double>& pi_t=pij_t.getRow(i);
+
+      double si=-VectorTools::sum(Qch.getRow(i));
+      if (si!=0)
+      {
+        const vector<double>& qi=Q.getRow(i);
+        const vector<double>& qchi=Qch.getRow(i);
+
+        for (size_t j=0; j<size_;j++)
+          pi_t[j]=(qi[j]-qchi[j])/si;
+      }
+      else
+        for (size_t j=0; j<size_;j++)
+          pi_t[j]= (i==j)?1:0;
+    }
+    return pij_t;
+  }
+  
+  const RowMatrix<double>& orig_t=getModel().getPij_t(t);
+  const RowMatrix<double>& ch_t=modelChanged_->getPij_t(t);
+
+
+  for (unsigned int i = 0; i < size_; ++i) {
+    vector<double>& pi_t=pij_t.getRow(i);
+    const vector<double>& origi_t=orig_t.getRow(i);
+    const vector<double>& chi_t=ch_t.getRow(i);
+
+    double si=1-VectorTools::sum(chi_t);
+    if (si==0)
+      for (auto& x : pi_t)
+        x=0;
+    else      
+      for (unsigned int j = 0; j < size_; ++j) 
+        pi_t[j]=(origi_t[j]-chi_t[j])/si;
+  }
+
+  return pij_t;
+}
+
+
+const Matrix<double>& OneChangeRegisterTransitionModel::getdPij_dt(double t) const
+{
+  if (t==0)
+  {
+    const RowMatrix<double>& Q=getSubstitutionModel().getGenerator();
+    const RowMatrix<double>& Qch=modelChanged_->getGenerator();
+    
+    RowMatrix<double> Qch2;
+    MatrixTools::mult<double>(Qch,Qch,Qch2);
+    
+    RowMatrix<double> Q2;
+    MatrixTools::mult<double>(Q,Q,Q2);
+    
+    for (size_t i=0;i<size_;i++)
+    {
+      vector<double>& dpi_t=dpij_t.getRow(i);
+      
+      double si=VectorTools::sum(Qch.getRow(i));
+      if (si!=0)
+      {
+        double dsi=VectorTools::sum(Qch2.getRow(i));
+        const vector<double>& qi=Q.getRow(i);
+        const vector<double>& qchi=Qch.getRow(i);
+        const vector<double>& q2i=Q2.getRow(i);
+        const vector<double>& q2chi=Qch2.getRow(i);
+        
+        for (size_t j=0; j<size_;j++)
+          dpi_t[j]= ((-q2i[j]+q2chi[j])/si + (qi[j]-qchi[j])*dsi/(si*si))/2;
+      }
+      else
+        for (auto& x : dpi_t)
+          x=0;
+    }
+    return dpij_t;
+  }
+  
+  const RowMatrix<double>& orig_t=getModel().getPij_t(t);
+  const RowMatrix<double>& ch_t=modelChanged_->getPij_t(t);
+  const RowMatrix<double>& dorig_dt=getModel().getdPij_dt(t);
+  const RowMatrix<double>& dch_dt=modelChanged_->getdPij_dt(t);
+
+  for (unsigned int i = 0; i < size_; ++i) {
+    vector<double>& dpi_dt=dpij_t.getRow(i);
+    const vector<double>& chi_t=ch_t.getRow(i);
+    
+    double si=1-VectorTools::sum(chi_t);
+    if (si==0)
+    {
+      for (auto& x : dpi_dt)
+        x=0;
+      continue;
+    }
+    
+    const vector<double>& origi_t=orig_t.getRow(i);
+    const vector<double>& dorigi_dt=dorig_dt.getRow(i);
+    const vector<double>& dchi_dt=dch_dt.getRow(i);
+
+    double dsi=-VectorTools::sum(dchi_dt);
+
+    for (unsigned int j = 0; j < size_; ++j) 
+      dpi_dt[j]= ((dorigi_dt[j]-dchi_dt[j])*si-dsi*(origi_t[j]-chi_t[j]))/(si*si);
+  }
+  
+  return dpij_t;
+}
+
+
+const Matrix<double>& OneChangeRegisterTransitionModel::getd2Pij_dt2(double t) const
+{
+  if (t==0)
+  {
+    const RowMatrix<double>& Q=getSubstitutionModel().getGenerator();
+    const RowMatrix<double>& Qch=modelChanged_->getGenerator();
+    
+    RowMatrix<double> Qch2, Qch3;
+    MatrixTools::mult<double>(Qch,Qch,Qch2);
+    MatrixTools::mult<double>(Qch,Qch2,Qch3);
+    
+    RowMatrix<double> Q2, Q3;
+    MatrixTools::mult<double>(Q,Q,Q2);
+    MatrixTools::mult<double>(Q,Q2,Q3);
+    
+    for (size_t i=0;i<size_;i++)
+    {
+      vector<double>& d2pi_t=d2pij_t.getRow(i);
+      
+      double si=VectorTools::sum(Qch.getRow(i));
+      if (si!=0)
+      {
+        double dsi=VectorTools::sum(Qch2.getRow(i));
+        double d2si=VectorTools::sum(Qch3.getRow(i));
+        const vector<double>& qi=Q.getRow(i);
+        const vector<double>& qchi=Qch.getRow(i);
+        const vector<double>& q2i=Q2.getRow(i);
+        const vector<double>& q2chi=Qch2.getRow(i);
+        const vector<double>& q3i=Q3.getRow(i);
+        const vector<double>& q3chi=Qch3.getRow(i);
+        
+        for (size_t j=0; j<size_;j++)
+          d2pi_t[j]=   ((qi[j]-qchi[j])*(si*d2si/3-dsi*dsi/2)+(q2i[j]-q2chi[j])*si*dsi/2-(q3i[j]-q3chi[j])*si*si/3)/(si*si*si);
+      }
+      else
+        for (auto& x : d2pi_t)
+          x=0;
+    }
+    return d2pij_t;
+  }
+  
+  const RowMatrix<double>& orig_t=getModel().getPij_t(t);
+  const RowMatrix<double>& ch_t=modelChanged_->getPij_t(t);
+  const RowMatrix<double>& dorig_dt=getModel().getdPij_dt(t);
+  const RowMatrix<double>& dch_dt=modelChanged_->getdPij_dt(t);
+  const RowMatrix<double>& d2orig_dt2=getModel().getd2Pij_dt2(t);
+  const RowMatrix<double>& d2ch_dt2=modelChanged_->getd2Pij_dt2(t);
+
+  for (unsigned int i = 0; i < size_; ++i) {
+    vector<double>& d2pi_dt2=d2pij_t.getRow(i);
+    const vector<double>& chi_t=ch_t.getRow(i);
+
+    double si=1-VectorTools::sum(chi_t);
+    if (si==0)
+    {
+      for (auto& x : d2pi_dt2)
+        x=0;
+      continue;
+    }
+
+    const vector<double>& origi_t=orig_t.getRow(i);
+    const vector<double>& dorigi_dt=dorig_dt.getRow(i);
+    const vector<double>& dchi_dt=dch_dt.getRow(i);
+    const vector<double>& d2origi_dt2=d2orig_dt2.getRow(i);
+    const vector<double>& d2chi_dt2=d2ch_dt2.getRow(i);
+    
+    double dsi=-VectorTools::sum(dchi_dt);
+    double d2si=-VectorTools::sum(d2chi_dt2);
+
+    double si2=si*si;
+  
+    for (unsigned int j = 0; j < size_; ++j)
+    {
+      double d2u=d2origi_dt2[j]-d2chi_dt2[j];
+      double du=dorigi_dt[j]-dchi_dt[j];
+      double u=origi_t[j]-chi_t[j];
+  
+      d2pi_dt2[j]=(d2u*si-d2si*u-2*dsi*du)/si2+2*dsi*dsi*u/(si2*si);
+    }
+  }
+  
+  return d2pij_t;
+}
+
+
diff --git a/src/Bpp/Phyl/Model/OneChangeRegisterTransitionModel.h b/src/Bpp/Phyl/Model/OneChangeRegisterTransitionModel.h
new file mode 100644
index 0000000..d081120
--- /dev/null
+++ b/src/Bpp/Phyl/Model/OneChangeRegisterTransitionModel.h
@@ -0,0 +1,215 @@
+//
+// File: OneChangeRegisterTransitionModel.h
+// Created by: Laurent Gueguen
+// Created on: samedi 24 octobre 2015, � 18h 28
+//
+
+/*
+  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 _ONE_CHANGE_REGISTER_TRANSITION_MODEL_H_
+#define _ONE_CHANGE_REGISTER_TRANSITION_MODEL_H_
+
+#include "AbstractFromSubstitutionModelTransitionModel.h"
+#include "AnonymousSubstitutionModel.h"
+
+#include "../Mapping/SubstitutionRegister.h"
+
+namespace bpp
+{
+/**
+ * @brief From a model, compute transition probabilities given there
+ * is at least a change of a category (ie a non null number in a
+ * register) in the branch.
+ *
+ * It has the same parameters as the SubModel.
+ *
+ * @see SubstitutionRegister
+ */
+
+  class OneChangeRegisterTransitionModel :
+    public AbstractFromSubstitutionModelTransitionModel
+  {
+  private:
+    /*
+     * The coordinates of the sustitutions or non-sustitutions that
+     * are NOT considered (ie for which the changes generator equals
+     * the model one).
+     *
+     */
+    
+    std::vector<std::vector<size_t> > otherChanges_;
+
+    /*
+     * The SubstitutionModel in which generator has registered changes
+     * set to 0.
+     */
+
+    std::unique_ptr<AnonymousSubstitutionModel> modelChanged_;
+
+    /*
+     * For output
+     *
+     */
+
+    std::string registerName_;
+
+    /*
+     *
+     * Vector of considered categories numbers in the register
+     *
+     */
+
+    std::vector<size_t> vNumRegs_;
+
+  public:
+    /*
+     * @brief Constructor
+     *
+     * @param originalModel the substitution model used
+     * @param reg the register in which the considered type of event is
+     * defined.
+     * @param numReg the number of the considered event in the
+     * register.
+     *
+     */
+    
+    OneChangeRegisterTransitionModel(const SubstitutionModel& originalModel, const SubstitutionRegister& reg, size_t numReg);
+
+    /*
+     * @brief Constructor
+     *
+     * @param originalModel the substitution model used
+     * @param reg the register in which the considered type of event is
+     * defined.
+     * @param vNumRegs the vector of numbers of the considered event
+     * in the register.
+     *
+     */
+    
+    OneChangeRegisterTransitionModel(const SubstitutionModel& originalModel, const SubstitutionRegister& reg, std::vector<size_t> vNumRegs);
+
+    OneChangeRegisterTransitionModel(const OneChangeRegisterTransitionModel& fmsm) :
+      AbstractParameterAliasable(fmsm),
+      AbstractFromSubstitutionModelTransitionModel(fmsm),
+      otherChanges_(fmsm.otherChanges_),
+      modelChanged_(std::unique_ptr<AnonymousSubstitutionModel>(fmsm.modelChanged_->clone())),
+      registerName_(fmsm.registerName_),
+      vNumRegs_(fmsm.vNumRegs_)
+    {
+    }
+    
+
+    OneChangeRegisterTransitionModel& operator=(const OneChangeRegisterTransitionModel& fmsm)
+    {
+      AbstractFromSubstitutionModelTransitionModel::operator=(fmsm);
+      otherChanges_=fmsm.otherChanges_;
+      modelChanged_=std::unique_ptr<AnonymousSubstitutionModel>(fmsm.modelChanged_->clone());
+      registerName_=fmsm.registerName_;
+      vNumRegs_=fmsm.vNumRegs_;
+        
+      return *this;
+    }
+    
+    ~OneChangeRegisterTransitionModel() {
+    }
+
+    OneChangeRegisterTransitionModel* clone() const { return new OneChangeRegisterTransitionModel(*this); }
+
+  public:
+
+    void fireParameterChanged(const ParameterList& parameters)
+    {
+      AbstractFromSubstitutionModelTransitionModel::fireParameterChanged(parameters);
+      updateMatrices();
+    }
+
+    double Pij_t    (size_t i, size_t j, double t) const;
+    double dPij_dt  (size_t i, size_t j, double t) const;
+    double d2Pij_dt2(size_t i, size_t j, double t) const;
+    
+    const Matrix<double>& getPij_t(double t) const;
+    
+    const Matrix<double>& getdPij_dt(double t) const;
+
+    const Matrix<double>& getd2Pij_dt2(double t) const;
+
+    
+    double freq(size_t i) const { return modelChanged_->freq(i); }
+
+    const Vdouble& getFrequencies() const { return modelChanged_->getFrequencies(); }
+
+    const FrequenciesSet* getFrequenciesSet() const {return modelChanged_->getFrequenciesSet(); }
+
+    void setFreqFromData(const SequenceContainer& data, double pseudoCount)
+    {
+      getModel().setFreqFromData(data, pseudoCount);
+    }
+
+    virtual void setFreq(std::map<int, double>& m)
+    {  
+      getModel().setFreq(m);
+    }
+
+    double getRate() const { return getModel().getRate(); }
+
+    void setRate(double rate) { return getModel().setRate(rate); }
+
+    double getInitValue(size_t i, int state) const throw (BadIntException) { return modelChanged_->getInitValue(i, state); }
+
+    void updateMatrices();
+    
+    std::string getName() const
+    {
+      return "OneChange";
+    }
+
+    const std::string& getRegisterName() const
+    {
+      return registerName_;
+    }
+
+    const std::vector<size_t>& getRegisterNumbers() const
+    {
+      return vNumRegs_;
+    }
+    
+    /*
+     * @}
+     *
+     */
+
+  };
+} // end of namespace bpp.
+
+#endif  // _ONE_CHANGE_REGISTER_TRANSITION_MODEL_H_
diff --git a/src/Bpp/Phyl/Model/OneChangeTransitionModel.cpp b/src/Bpp/Phyl/Model/OneChangeTransitionModel.cpp
index e774e62..ead73a8 100644
--- a/src/Bpp/Phyl/Model/OneChangeTransitionModel.cpp
+++ b/src/Bpp/Phyl/Model/OneChangeTransitionModel.cpp
@@ -47,7 +47,7 @@ using namespace std;
 
 double OneChangeTransitionModel::Pij_t    (size_t i, size_t j, double t) const
 {
-  double qii=getModel().Qij(i,i);
+  double qii=getSubstitutionModel().Qij(i,i);
   if (qii==0)
   {
     return (i==j?1:0);
@@ -60,13 +60,13 @@ double OneChangeTransitionModel::Pij_t    (size_t i, size_t j, double t) const
       return (getModel().Pij_t(i,j,t)-(i==j?v:0))/(1-v);
     }
     else
-      return (i==j?0:-getModel().Qij(i,j)/qii);
+      return (i==j?0:-getSubstitutionModel().Qij(i,j)/qii);
   }
 }
 
 double OneChangeTransitionModel::dPij_dt  (size_t i, size_t j, double t) const
 {
-  const RowMatrix<double>& Q=getModel().getGenerator();
+  const RowMatrix<double>& Q=getSubstitutionModel().getGenerator();
   double qii=Q(i,i);
   
   if (qii==0)
@@ -92,7 +92,7 @@ double OneChangeTransitionModel::d2Pij_dt2(size_t i, size_t j, double t) const
 {
   if (t!=0)
   {
-    double qii=getModel().Qij(i,i);
+    double qii=getSubstitutionModel().Qij(i,i);
       
     if (qii==0)
     {
@@ -108,7 +108,7 @@ double OneChangeTransitionModel::d2Pij_dt2(size_t i, size_t j, double t) const
   }
   else
   {
-    const RowMatrix<double>& Q=getModel().getGenerator();
+    const RowMatrix<double>& Q=getSubstitutionModel().getGenerator();
     double qii=Q(i,i);
     
     if (qii==0)
@@ -117,7 +117,7 @@ double OneChangeTransitionModel::d2Pij_dt2(size_t i, size_t j, double t) const
     double q2ik,q2ij=0,q3ij=0;
     
     for (size_t k = 0; k < size_; ++k)
-    {
+    { 
       q2ik=0;
       for (size_t l = 0; l < size_; ++l)
         q2ik+=Q(i,l)*Q(l,k);
@@ -134,7 +134,7 @@ double OneChangeTransitionModel::d2Pij_dt2(size_t i, size_t j, double t) const
 const Matrix<double>& OneChangeTransitionModel::getPij_t(double t) const
 {
   const RowMatrix<double>& origPij=getModel().getPij_t(t);
-  const RowMatrix<double>& Q=getModel().getGenerator();
+  const RowMatrix<double>& Q=getSubstitutionModel().getGenerator();
   
   for (unsigned int i = 0; i < size_; ++i) {
     vector<double>& pi_t=pij_t.getRow(i);
@@ -178,7 +178,7 @@ const Matrix<double>& OneChangeTransitionModel::getdPij_dt(double t) const
   
     for (unsigned int i = 0; i < size_; ++i) {
       vector<double>& dpi_t=dpij_t.getRow(i);
-      double qii=getModel().Qij(i,i);
+      double qii=getSubstitutionModel().Qij(i,i);
       
       if (qii==0)
       {
@@ -201,7 +201,7 @@ const Matrix<double>& OneChangeTransitionModel::getdPij_dt(double t) const
   }
   else
   {
-    const RowMatrix<double>& Q=getModel().getGenerator();
+    const RowMatrix<double>& Q=getSubstitutionModel().getGenerator();
     RowMatrix<double> Q2;
     MatrixTools::mult<double>(Q,Q,Q2);
     
@@ -239,7 +239,7 @@ const Matrix<double>& OneChangeTransitionModel::getd2Pij_dt2(double t) const
     const RowMatrix<double>& origd2Pij=getModel().getd2Pij_dt2(t);
   
     for (unsigned int i = 0; i < size_; ++i) {
-      double qii=getModel().Qij(i,i);
+      double qii=getSubstitutionModel().Qij(i,i);
       vector<double>& d2pi_t=d2pij_t.getRow(i);
       
       if (qii==0)
@@ -269,7 +269,7 @@ const Matrix<double>& OneChangeTransitionModel::getd2Pij_dt2(double t) const
   }
   else
   {
-    const RowMatrix<double>& Q=getModel().getGenerator();
+    const RowMatrix<double>& Q=getSubstitutionModel().getGenerator();
     RowMatrix<double> Q2;
     MatrixTools::mult<double>(Q,Q,Q2);
     RowMatrix<double> Q3;
diff --git a/src/Bpp/Phyl/Model/OneChangeTransitionModel.h b/src/Bpp/Phyl/Model/OneChangeTransitionModel.h
index e72a920..c148f22 100644
--- a/src/Bpp/Phyl/Model/OneChangeTransitionModel.h
+++ b/src/Bpp/Phyl/Model/OneChangeTransitionModel.h
@@ -56,11 +56,13 @@ namespace bpp
   {
   public:
     OneChangeTransitionModel(const SubstitutionModel& originalModel) :
-      AbstractFromSubstitutionModelTransitionModel(originalModel)
+      AbstractParameterAliasable("OneChange."),
+      AbstractFromSubstitutionModelTransitionModel(originalModel, "OneChange.")
     {
     }
     
     OneChangeTransitionModel(const OneChangeTransitionModel& fmsm) :
+      AbstractParameterAliasable(fmsm),
       AbstractFromSubstitutionModelTransitionModel(fmsm)
     {
     }
@@ -77,22 +79,45 @@ namespace bpp
     OneChangeTransitionModel* clone() const { return new OneChangeTransitionModel(*this); }
 
   public:
-    double freq(size_t i) const { return getModel().freq(i); }
-
     double Pij_t    (size_t i, size_t j, double t) const;
     double dPij_dt  (size_t i, size_t j, double t) const;
     double d2Pij_dt2(size_t i, size_t j, double t) const;
     
-    const Vdouble& getFrequencies() const { return getModel().getFrequencies(); }
-
-    const FrequenciesSet* getFrequenciesSet() const {return getModel().getFrequenciesSet(); }
-
     const Matrix<double>& getPij_t(double t) const;
     
     const Matrix<double>& getdPij_dt(double t) const;
 
     const Matrix<double>& getd2Pij_dt2(double t) const;
 
+    
+    double freq(size_t i) const { return getModel().freq(i); }
+
+    const Vdouble& getFrequencies() const { return getModel().getFrequencies(); }
+
+    const FrequenciesSet* getFrequenciesSet() const {return getModel().getFrequenciesSet(); }
+
+    void setFreqFromData(const SequenceContainer& data, double pseudoCount)
+    {
+      getModel().setFreqFromData(data, pseudoCount);
+    }
+
+    virtual void setFreq(std::map<int, double>& m)
+    {  
+      getModel().setFreq(m);
+    }
+
+    double getRate() const { return getModel().getRate(); }
+
+    void setRate(double rate) { return getModel().setRate(rate); }
+
+    double getInitValue(size_t i, int state) const throw (BadIntException) { return getModel().getInitValue(i, state); }
+
+    std::string getName() const
+    {
+      return "OneChange";
+    }
+
+    
     /*
      * @}
      *
diff --git a/src/Bpp/Phyl/Model/Protein/DSO78.h b/src/Bpp/Phyl/Model/Protein/DSO78.h
index 0c8692d..62c2fef 100755
--- a/src/Bpp/Phyl/Model/Protein/DSO78.h
+++ b/src/Bpp/Phyl/Model/Protein/DSO78.h
@@ -122,6 +122,12 @@ namespace bpp
       AbstractReversibleSubstitutionModel::fireParameterChanged(parameters);
     }
 
+    void setNamespace(const std::string& prefix)
+    {
+      AbstractParameterAliasable::setNamespace(prefix);
+      freqSet_->setNamespace(prefix + freqSet_->getName() + ".");
+    }
+
     void setFrequenciesSet(const ProteinFrequenciesSet& freqSet)
     {
       delete freqSet_;
diff --git a/src/Bpp/Phyl/Model/Protein/JCprot.cpp b/src/Bpp/Phyl/Model/Protein/JCprot.cpp
index 919868e..d7e5225 100755
--- a/src/Bpp/Phyl/Model/Protein/JCprot.cpp
+++ b/src/Bpp/Phyl/Model/Protein/JCprot.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 "JCprot.h"
@@ -54,7 +54,7 @@ using namespace std;
 JCprot::JCprot(const ProteicAlphabet* alpha) :
   AbstractParameterAliasable("JC69."),
   AbstractReversibleProteinSubstitutionModel(alpha, new CanonicalStateMap(alpha, false), "JC69."),
-  exp_(), p_(size_, size_), freqSet_(0)
+  exp_(), p_(size_, size_), freqSet_(0), withFreq_(0)
 {
   freqSet_ = new FixedProteinFrequenciesSet(alpha, freq_);
   updateMatrices();
@@ -63,12 +63,13 @@ JCprot::JCprot(const ProteicAlphabet* alpha) :
 JCprot::JCprot(const ProteicAlphabet* alpha, ProteinFrequenciesSet* freqSet, bool initFreqs) :
   AbstractParameterAliasable("JC69+F."),
   AbstractReversibleProteinSubstitutionModel(alpha, new CanonicalStateMap(alpha, false), "JC69+F."),
-  exp_(), p_(size_, size_), freqSet_(freqSet)
+  exp_(), p_(size_, size_), freqSet_(freqSet), withFreq_(true)
 {
   freqSet_->setNamespace("JC69+F."+freqSet_->getNamespace());
   if (initFreqs) freqSet_->setFrequencies(freq_);
   else freq_ = freqSet_->getFrequencies();
   addParameters_(freqSet_->getParameters());
+
   updateMatrices();  
 }
 
@@ -77,102 +78,140 @@ JCprot::JCprot(const ProteicAlphabet* alpha, ProteinFrequenciesSet* freqSet, boo
 	
 void JCprot::updateMatrices()
 {
-	// Frequencies:
-	for (unsigned int i = 0; i < 20; i++) freq_[i] = 1. / 20.;
+  for (unsigned int i = 0; i < 20; i++)
+    for (unsigned int j = 0; j < 20; j++)
+      exchangeability_(i, j) = (i == j) ? -20. : 20./19.;
 
-	// Generator:
-	for (unsigned int i = 0; i < 20; i++)
+  if (!withFreq_)
   {
-		for (unsigned int j = 0; j < 20; j++)
+    // Frequencies:
+    for (unsigned int i = 0; i < 20; i++) freq_[i] = 1. / 20.;
+    
+    // Generator:
+    for (unsigned int i = 0; i < 20; i++)
     {
-			generator_(i, j) = (i == j) ? -1. : 1./19.;
-			exchangeability_(i, j) = generator_(i, j) * 20.;
-		}
-	}
-	
-	// Eigen values:
-	eigenValues_[0] = 0;
-	for (unsigned int i = 1; i < 20; i++) eigenValues_[i] = -20. / 19.;
-	
-	// Eigen vectors:
-	for (unsigned int i = 0; i < 20; i++) leftEigenVectors_(0,i) = 1./20.;
-	for (unsigned int i = 1; i < 20; i++) 
-		for (unsigned int j = 0; j < 20; j++)
-			leftEigenVectors_(i,j) = -1./20.;
-	for (unsigned int i = 0; i < 19; i++) leftEigenVectors_(19-i,i) = 19./20.;
-
-	for (unsigned int i = 0; i < 20; i++) rightEigenVectors_(i,0) = 1.;
-	for (unsigned int i = 1; i < 20; i++) rightEigenVectors_(19,i) = -1.;
-	for (unsigned int i = 0; i < 19; i++) 
-		for (unsigned int j = 1; j < 20; j++)
-			rightEigenVectors_(i,j) = 0.;
-	for (unsigned int i = 1; i < 20; i++) rightEigenVectors_(19-i,i) = 1.;
-
+      for (unsigned int j = 0; j < 20; j++)
+      {
+        generator_(i, j) = (i == j) ? -1. : 1./19.;
+      }
+    }
+    
+    // Eigen values:
+    eigenValues_[0] = 0;
+    for (unsigned int i = 1; i < 20; i++) eigenValues_[i] = -20. / 19.;
+    
+    // Eigen vectors:
+    for (unsigned int i = 0; i < 20; i++) leftEigenVectors_(0,i) = 1./20.;
+    for (unsigned int i = 1; i < 20; i++) 
+      for (unsigned int j = 0; j < 20; j++)
+        leftEigenVectors_(i,j) = -1./20.;
+    for (unsigned int i = 0; i < 19; i++) leftEigenVectors_(19-i,i) = 19./20.;
+    
+    for (unsigned int i = 0; i < 20; i++) rightEigenVectors_(i,0) = 1.;
+    for (unsigned int i = 1; i < 20; i++) rightEigenVectors_(19,i) = -1.;
+    for (unsigned int i = 0; i < 19; i++) 
+      for (unsigned int j = 1; j < 20; j++)
+      rightEigenVectors_(i,j) = 0.;
+    for (unsigned int i = 1; i < 20; i++) rightEigenVectors_(19-i,i) = 1.;
+  }
+  else
+    AbstractReversibleSubstitutionModel::updateMatrices();
 }
 	
 /******************************************************************************/
 
 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);
+  if (!withFreq_)
+  {
+    if(i == j) return 1./20. + 19./20. * exp(-  rate_ * 20./19. * d);
+    else       return 1./20. -  1./20. * exp(-  rate_ * 20./19. * d);
+  }
+  else
+    return AbstractSubstitutionModel::Pij_t(i,j,d);
 }
 
 /******************************************************************************/
 
 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);
+  if (!withFreq_)
+  {
+    if(i == j) return -  rate_ *        exp(-  rate_ * 20./19. * d);
+    else       return  rate_ * 1./19. * exp(-  rate_ * 20./19. * d);
+  }
+  else
+    return AbstractSubstitutionModel::dPij_dt(i,j,d);
 }
 
 /******************************************************************************/
 
 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);
+  if (!withFreq_)
+  {
+    if(i == j) return    rate_ *  rate_ * 20./19.  * exp(-  rate_ * 20./19. * d);
+    else       return -  rate_ *  rate_ * 20./361. * exp(-  rate_ * 20./19. * d);
+  }
+  else
+    return AbstractSubstitutionModel::d2Pij_dt2(i,j,d);
+
 }
 
 /******************************************************************************/
 
 const Matrix<double>& JCprot::getPij_t(double d) const
 {
-  exp_ = exp(-  rate_ * 20./19. * d);
-	for(unsigned int i = 0; i < size_; i++)
+  if (!withFreq_)
   {
-		for(unsigned int j = 0; j < size_; j++)
+    exp_ = exp(-  rate_ * 20./19. * d);
+    for(unsigned int i = 0; i < size_; i++)
     {
-			p_(i,j) = (i==j) ? 1./20. + 19./20. * exp_ : 1./20. - 1./20. * exp_;
-		}
-	}
-	return p_;
+      for(unsigned int j = 0; j < size_; j++)
+      {
+        p_(i,j) = (i==j) ? 1./20. + 19./20. * exp_ : 1./20. - 1./20. * exp_;
+      }
+    }
+    return p_;
+  }
+  else
+    return AbstractSubstitutionModel::getPij_t(d);
 }
 
 const Matrix<double>& JCprot::getdPij_dt(double d) const
 {
-  exp_ = exp(-  rate_ * 20./19. * d);
-	for(unsigned int i = 0; i < size_; i++)
+  if (!withFreq_)
   {
-		for(unsigned int j = 0; j < size_; j++)
+    exp_ = exp(-  rate_ * 20./19. * d);
+    for(unsigned int i = 0; i < size_; i++)
     {
-      p_(i,j) =  rate_ * ((i==j) ? - exp_ : 1./19. * exp_);
-		}
-	}
-	return p_;
+      for(unsigned int j = 0; j < size_; j++)
+      {
+        p_(i,j) =  rate_ * ((i==j) ? - exp_ : 1./19. * exp_);
+      }
+    }
+    return p_;
+  }
+  else
+    return AbstractSubstitutionModel::getdPij_dt(d);
 }
 
 const Matrix<double>& JCprot::getd2Pij_dt2(double d) const
 {
-  exp_ = exp( rate_ * - 20./19. * d);
-	for(unsigned int i = 0; i < size_; i++)
+  if (!withFreq_)
   {
-		for(unsigned int j = 0; j < size_; j++)
+    exp_ = exp( rate_ * - 20./19. * d);
+    for(unsigned int i = 0; i < size_; i++)
     {
-      p_(i,j) =  rate_ *  rate_ * ((i==j) ? 20./19. * exp_ : - 20./361. * exp_);
-		}
-	}
-	return p_;
+      for(unsigned int j = 0; j < size_; j++)
+      {
+        p_(i,j) =  rate_ *  rate_ * ((i==j) ? 20./19. * exp_ : - 20./361. * exp_);
+      }
+    }
+    return p_;
+  }
+  else
+    return AbstractSubstitutionModel::getd2Pij_dt2(d);
 }
 
 /******************************************************************************/
diff --git a/src/Bpp/Phyl/Model/Protein/JCprot.h b/src/Bpp/Phyl/Model/Protein/JCprot.h
index 0ab4b96..7363dc1 100755
--- a/src/Bpp/Phyl/Model/Protein/JCprot.h
+++ b/src/Bpp/Phyl/Model/Protein/JCprot.h
@@ -138,7 +138,8 @@ namespace bpp
     mutable double exp_;
     mutable RowMatrix<double> p_;
     ProteinFrequenciesSet* freqSet_;
-
+    bool withFreq_;
+    
   public:
     /**
      * @brief Build a simple JC69 model, with original equilibrium frequencies.
@@ -162,7 +163,8 @@ namespace bpp
       AbstractReversibleProteinSubstitutionModel(model),
       exp_(model.exp_),
       p_(model.p_),
-      freqSet_(dynamic_cast<ProteinFrequenciesSet*>(model.freqSet_->clone()))
+      freqSet_(dynamic_cast<ProteinFrequenciesSet*>(model.freqSet_->clone())),
+      withFreq_(model.withFreq_)
     {}
 
     JCprot& operator=(const JCprot& model)
@@ -173,6 +175,7 @@ namespace bpp
       p_   = model.p_;
       if (freqSet_) delete freqSet_;
       freqSet_ = dynamic_cast<ProteinFrequenciesSet*>(model.freqSet_->clone());
+      withFreq_ = model.withFreq_;
       return *this;
     }
 
@@ -190,10 +193,7 @@ namespace bpp
 
     std::string getName() const 
     { 
-      if (freqSet_->getNamespace().find("+F.")!=std::string::npos)
-        return "JC69+F"; 
-      else 
-        return "JC69"; 
+      return (withFreq_?"JC69+F":"JC69");
     }
 	
     void fireParameterChanged(const ParameterList& parameters)
@@ -213,6 +213,12 @@ namespace bpp
 
     const FrequenciesSet* getFrequenciesSet() const { return freqSet_; }
 
+    void setNamespace(const std::string& prefix)
+    {
+      AbstractParameterAliasable::setNamespace(prefix);
+      freqSet_->setNamespace(prefix + freqSet_->getName() + ".");
+    }
+
     void setFreqFromData(const SequenceContainer& data, double pseudoCount = 0);
 
   protected:
diff --git a/src/Bpp/Phyl/Model/Protein/JTT92.h b/src/Bpp/Phyl/Model/Protein/JTT92.h
index 7cd97c3..1c9e062 100755
--- a/src/Bpp/Phyl/Model/Protein/JTT92.h
+++ b/src/Bpp/Phyl/Model/Protein/JTT92.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 _JTT92_H_
@@ -63,9 +63,9 @@ namespace bpp
  * - Jones DT, Taylor WR and Thornton JM (1992), _Computer Applications In The Biosciences_, 8(3) 275-82. 
  * - Kosiol C and Goldman N (2005), _Molecular Biology And Evolution_ 22(2) 193-9. 
  */
-class JTT92 :
-  public AbstractReversibleProteinSubstitutionModel
-{
+  class JTT92 :
+    public AbstractReversibleProteinSubstitutionModel
+  {
   private:
     ProteinFrequenciesSet* freqSet_;
 
@@ -115,6 +115,13 @@ class JTT92 :
         return "JTT92"; 
     }
 
+    void setNamespace(const std::string& prefix)
+    {
+      AbstractParameterAliasable::setNamespace(prefix);
+      freqSet_->setNamespace(prefix + freqSet_->getName() + ".");
+    }
+
+
     void fireParameterChanged(const ParameterList& parameters)
     {
       freqSet_->matchParametersValues(parameters);
@@ -134,7 +141,7 @@ class JTT92 :
 
     void setFreqFromData(const SequenceContainer& data, double pseudoCount = 0);
 
-};
+  };
 
 } //end of namespace bpp.
 
diff --git a/src/Bpp/Phyl/Model/Protein/LG08.h b/src/Bpp/Phyl/Model/Protein/LG08.h
index b6ee317..5314faf 100644
--- a/src/Bpp/Phyl/Model/Protein/LG08.h
+++ b/src/Bpp/Phyl/Model/Protein/LG08.h
@@ -128,6 +128,12 @@ namespace bpp
       addParameters_(freqSet_->getParameters());
     }
 
+    void setNamespace(const std::string& prefix)
+    {
+      AbstractParameterAliasable::setNamespace(prefix);
+      freqSet_->setNamespace(prefix + freqSet_->getName() + ".");
+    }
+
     const FrequenciesSet* getFrequenciesSet() const { return freqSet_; }
 
     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
index ad4a626..5cffd4b 100644
--- a/src/Bpp/Phyl/Model/Protein/LG10_EX_EHO.cpp
+++ b/src/Bpp/Phyl/Model/Protein/LG10_EX_EHO.cpp
@@ -38,6 +38,7 @@
 
 #include "LG10_EX_EHO.h"
 #include "../FrequenciesSet/ProteinFrequenciesSet.h"
+#include "../MixtureOfSubstitutionModels.h"
 
 #include <Bpp/Numeric/Prob/SimpleDiscreteDistribution.h>
 
@@ -48,8 +49,7 @@ using namespace std;
 /******************************************************************************/
 
 LG10_EX_EHO::LG10_EX_EHO(const ProteicAlphabet* alpha) : 
-  AbstractBiblioMixedSubstitutionModel("LG10_EX_EHO."),
-  pmixmodel_()
+  AbstractBiblioMixedSubstitutionModel("LG10_EX_EHO.")
 {
   // build the submodel
 	
@@ -87,22 +87,6 @@ LG10_EX_EHO::LG10_EX_EHO(const ProteicAlphabet* alpha) :
   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) :
diff --git a/src/Bpp/Phyl/Model/Protein/LG10_EX_EHO.h b/src/Bpp/Phyl/Model/Protein/LG10_EX_EHO.h
index ad88f1f..3acd90f 100644
--- a/src/Bpp/Phyl/Model/Protein/LG10_EX_EHO.h
+++ b/src/Bpp/Phyl/Model/Protein/LG10_EX_EHO.h
@@ -5,42 +5,41 @@
 //
 
 /*
- Copyright or © or Copr. CNRS, (November 16, 2004)
+  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 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 _LG10_EX_EHO_H_
 #define _LG10_EX_EHO_H_
 
-#include "../MixtureOfSubstitutionModels.h"
 #include "ProteinSubstitutionModel.h"
 #include "../AbstractSubstitutionModel.h"
 #include "../AbstractBiblioMixedSubstitutionModel.h"
@@ -71,58 +70,51 @@ namespace bpp
  *
  * Le S.Q., Gascuel O. (2010) Syst. Biol. 59(3):277–287
  */
-class LG10_EX_EHO :
-  public AbstractBiblioMixedSubstitutionModel
-{
-public:
-  class EmbeddedModel :
-    public AbstractReversibleProteinSubstitutionModel
+  class LG10_EX_EHO :
+    public AbstractBiblioMixedSubstitutionModel
   {
-private:
-    double proportion_;
-    string name_;
-
-public:
-    EmbeddedModel(const ProteicAlphabet* alpha, string name);
-    virtual ~EmbeddedModel() {}
-    EmbeddedModel* clone() const { return new EmbeddedModel(*this); }
-    string getName() const { return name_;}
-    double getProportion() const { return proportion_;}
-  };
-
-private:
-  std::unique_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();
+  public:
+    class EmbeddedModel :
+      public AbstractReversibleProteinSubstitutionModel
+    {
+    private:
+      double proportion_;
+      string name_;
+
+    public:
+      EmbeddedModel(const ProteicAlphabet* alpha, string name);
+      virtual ~EmbeddedModel() {}
+      EmbeddedModel* clone() const { return new EmbeddedModel(*this); }
+      string getName() const { return name_;}
+      double getProportion() const { return proportion_;}
+    };
+
+  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* clone() const { return new LG10_EX_EHO(*this); }
+
+    LG10_EX_EHO(const LG10_EX_EHO& mod2) :
+      AbstractBiblioMixedSubstitutionModel(mod2)
+    {}
+
+    LG10_EX_EHO& operator=(const LG10_EX_EHO& mod2)
+    {
+      AbstractBiblioMixedSubstitutionModel::operator=(mod2);
+
+      return *this;
+    }
+
+    std::string getName() const { return "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 4b0dbe3..508c213 100644
--- a/src/Bpp/Phyl/Model/Protein/LGL08_CAT.cpp
+++ b/src/Bpp/Phyl/Model/Protein/LGL08_CAT.cpp
@@ -38,6 +38,7 @@
 
 #include "LGL08_CAT.h"
 #include "../FrequenciesSet/ProteinFrequenciesSet.h"
+#include "../MixtureOfSubstitutionModels.h"
 
 #include <Bpp/Numeric/Prob/SimpleDiscreteDistribution.h>
 
@@ -48,8 +49,7 @@ using namespace std;
 /******************************************************************************/
 
 LGL08_CAT::LGL08_CAT(const ProteicAlphabet* alpha, unsigned int nbCat) :
-  AbstractBiblioMixedSubstitutionModel("LGL08_CAT."),
-  pmixmodel_()
+  AbstractBiblioMixedSubstitutionModel("LGL08_CAT.")
 {
   // build the submodel
 
@@ -83,21 +83,6 @@ LGL08_CAT::LGL08_CAT(const ProteicAlphabet* alpha, unsigned int nbCat) :
   updateMatrices();
 }
 
-LGL08_CAT::LGL08_CAT(const LGL08_CAT& mod2) : AbstractBiblioMixedSubstitutionModel(mod2),
-  pmixmodel_(new MixtureOfSubstitutionModels(*mod2.pmixmodel_))
-{}
-
-LGL08_CAT& LGL08_CAT::operator=(const LGL08_CAT& mod2)
-{
-  AbstractBiblioMixedSubstitutionModel::operator=(mod2);
-
-  pmixmodel_.reset(new MixtureOfSubstitutionModels(*mod2.pmixmodel_));
-
-  return *this;
-}
-
-LGL08_CAT::~LGL08_CAT() {}
-
 /**************** sub model classes */ // ////////
 
 LGL08_CAT::EmbeddedModel::EmbeddedModel(const ProteicAlphabet* alpha, string name, unsigned int nbCat) :
diff --git a/src/Bpp/Phyl/Model/Protein/LGL08_CAT.h b/src/Bpp/Phyl/Model/Protein/LGL08_CAT.h
index ff87244..b89979d 100644
--- a/src/Bpp/Phyl/Model/Protein/LGL08_CAT.h
+++ b/src/Bpp/Phyl/Model/Protein/LGL08_CAT.h
@@ -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. 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 _LGL08_CAT_H_
 #define _LGL08_CAT_H_
@@ -71,58 +71,48 @@ namespace bpp
  * Le S.Q., Gascuel O. & Lartillot N. (2008) Bioinformatics 24:2317–2323.
  */
 
-class LGL08_CAT :
-  public AbstractBiblioMixedSubstitutionModel
-{
-public:
-  class EmbeddedModel :
-    public AbstractReversibleProteinSubstitutionModel
+  class LGL08_CAT :
+    public AbstractBiblioMixedSubstitutionModel
   {
-private:
-    double proportion_;
-    string name_;
-
-public:
-    EmbeddedModel(const ProteicAlphabet* alpha, string name, unsigned int nbCat = 10);
-    virtual ~EmbeddedModel(){}
-    EmbeddedModel* clone() const { return new EmbeddedModel(*this); }
-    string getName() const { return name_;}
-    double getProportion() const { return proportion_;}
-  };
-
-private:
-  std::unique_ptr<MixtureOfSubstitutionModels> pmixmodel_;
-
-public:
-  /**
-   * @brief Build a CAT model, with original equilibrium frequencies, probabilities and rates.
-   *
-   * @param alpha A proteic alphabet.
-   * @param nbCat number of profiles
-   *
-   */
-  LGL08_CAT(const ProteicAlphabet* alpha, unsigned int nbCat = 10);
-
-  ~LGL08_CAT();
-
-  LGL08_CAT* clone() const { return new LGL08_CAT(*this); }
+  public:
+    class EmbeddedModel :
+      public AbstractReversibleProteinSubstitutionModel
+    {
+    private:
+      double proportion_;
+      string name_;
+
+    public:
+      EmbeddedModel(const ProteicAlphabet* alpha, string name, unsigned int nbCat = 10);
+      virtual ~EmbeddedModel(){}
+      EmbeddedModel* clone() const { return new EmbeddedModel(*this); }
+      string getName() const { return name_;}
+      double getProportion() const { return proportion_;}
+    };
+
+  public:
+    /**
+     * @brief Build a CAT model, with original equilibrium frequencies, probabilities and rates.
+     *
+     * @param alpha A proteic alphabet.
+     * @param nbCat number of profiles
+     *
+     */
+    LGL08_CAT(const ProteicAlphabet* alpha, unsigned int nbCat = 10);
+
+    LGL08_CAT* clone() const { return new LGL08_CAT(*this); }
+
+    LGL08_CAT(const LGL08_CAT& mod2) :
+      AbstractBiblioMixedSubstitutionModel(mod2)
+    {}
+
+    LGL08_CAT& operator=(const LGL08_CAT& mod2)
+    {
+      AbstractBiblioMixedSubstitutionModel::operator=(mod2);
+      return *this;
+    }
 
-  LGL08_CAT(const LGL08_CAT&);
-
-  LGL08_CAT& operator=(const LGL08_CAT&);
-
-  const SubstitutionModel& getModel() const { return *pmixmodel_.get(); }
-
-  const MixedSubstitutionModel& getMixedModel() const { return *pmixmodel_.get(); }
-
-  std::string getName() const { return "LGL08_CAT"; }
-  
-private:
-  SubstitutionModel& getModel() { return *pmixmodel_.get(); }
-
-  MixedSubstitutionModel& getMixedModel() { return *pmixmodel_.get(); }
-
-};
+  };
 } // end of namespace bpp.
 
 #endif  // _LGL08_CAT_H_
diff --git a/src/Bpp/Phyl/Model/Protein/LLG08_EHO.cpp b/src/Bpp/Phyl/Model/Protein/LLG08_EHO.cpp
index 5c537d2..453d541 100644
--- a/src/Bpp/Phyl/Model/Protein/LLG08_EHO.cpp
+++ b/src/Bpp/Phyl/Model/Protein/LLG08_EHO.cpp
@@ -38,6 +38,7 @@
 
 #include "LLG08_EHO.h"
 #include "../FrequenciesSet/ProteinFrequenciesSet.h"
+#include "../MixtureOfSubstitutionModels.h"
 
 #include <Bpp/Numeric/Prob/SimpleDiscreteDistribution.h>
 
@@ -48,8 +49,7 @@ using namespace std;
 /******************************************************************************/
 
 LLG08_EHO::LLG08_EHO(const ProteicAlphabet* alpha) :
-  AbstractBiblioMixedSubstitutionModel("LLG08_EHO."),
-  pmixmodel_()
+  AbstractBiblioMixedSubstitutionModel("LLG08_EHO.")
 {
   // build the submodel
 
@@ -84,20 +84,6 @@ LLG08_EHO::LLG08_EHO(const ProteicAlphabet* alpha) :
   updateMatrices();
 }
 
-LLG08_EHO::LLG08_EHO(const LLG08_EHO& mod2) : AbstractBiblioMixedSubstitutionModel(mod2),
-  pmixmodel_(new MixtureOfSubstitutionModels(*mod2.pmixmodel_))
-{}
-
-LLG08_EHO& LLG08_EHO::operator=(const LLG08_EHO& mod2)
-{
-  AbstractBiblioMixedSubstitutionModel::operator=(mod2);
-
-  pmixmodel_.reset(new MixtureOfSubstitutionModels(*mod2.pmixmodel_));
-  return *this;
-}
-
-LLG08_EHO::~LLG08_EHO() {}
-
 /**************** sub model classes */ // ////////
 
 LLG08_EHO::EmbeddedModel::EmbeddedModel(const ProteicAlphabet* alpha, string name) :
diff --git a/src/Bpp/Phyl/Model/Protein/LLG08_EHO.h b/src/Bpp/Phyl/Model/Protein/LLG08_EHO.h
index 1daaa27..704f5e8 100644
--- a/src/Bpp/Phyl/Model/Protein/LLG08_EHO.h
+++ b/src/Bpp/Phyl/Model/Protein/LLG08_EHO.h
@@ -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. 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 _LLG08_EHO_H_
 #define _LLG08_EHO_H_
@@ -75,58 +75,51 @@ namespace bpp
  * Le S.Q., Lartillot N., Gascuel O. (2008) Phil. Trans. R. Soc. B 363:3965--3976.
  */
 
-class LLG08_EHO :
-  public AbstractBiblioMixedSubstitutionModel
-{
-public:
-  class EmbeddedModel :
-    public AbstractReversibleProteinSubstitutionModel
+  class LLG08_EHO :
+    public AbstractBiblioMixedSubstitutionModel
   {
-private:
-    double proportion_;
-    string name_;
-
-public:
-    EmbeddedModel(const ProteicAlphabet* alpha, string name);
-    virtual ~EmbeddedModel(){}
-    EmbeddedModel* clone() const { return new EmbeddedModel(*this); }
-    string getName() const { return name_;}
-    double getProportion() const { return proportion_;}
+  public:
+    class EmbeddedModel :
+      public AbstractReversibleProteinSubstitutionModel
+    {
+    private:
+      double proportion_;
+      string name_;
+
+    public:
+      EmbeddedModel(const ProteicAlphabet* alpha, string name);
+      virtual ~EmbeddedModel(){}
+      EmbeddedModel* clone() const { return new EmbeddedModel(*this); }
+      string getName() const { return name_;}
+      double getProportion() const { return proportion_;}
+    };
+
+  public:
+    /**
+     * @brief Build a  EH0 model, with original equilibrium frequencies, probabilities and rates.
+     *
+     * @param alpha A proteic alphabet.
+     *
+     */
+
+    LLG08_EHO(const ProteicAlphabet* alpha);
+
+    LLG08_EHO* clone() const { return new LLG08_EHO(*this); }
+
+    LLG08_EHO(const LLG08_EHO& mod2) :
+      AbstractBiblioMixedSubstitutionModel(mod2)
+    {}
+
+    LLG08_EHO& operator=(const LLG08_EHO& mod2)
+    {
+      AbstractBiblioMixedSubstitutionModel::operator=(mod2);
+
+      return *this;
+    }
+
+
+    std::string getName() const { return "LLG08_EHO"; }
   };
-
-private:
-  unique_ptr<MixtureOfSubstitutionModels> pmixmodel_;
-
-public:
-  /**
-   * @brief Build a  EH0 model, with original equilibrium frequencies, probabilities and rates.
-   *
-   * @param alpha A proteic alphabet.
-   *
-   */
-
-  LLG08_EHO(const ProteicAlphabet* alpha);
-
-  ~LLG08_EHO();
-
-  LLG08_EHO* clone() const { return new LLG08_EHO(*this); }
-
-  LLG08_EHO(const LLG08_EHO&);
-
-  LLG08_EHO& operator=(const LLG08_EHO&);
-
-  const SubstitutionModel& getModel() const { return *pmixmodel_.get(); }
-
-  const MixedSubstitutionModel& getMixedModel() const { return *pmixmodel_.get(); }
-
-  std::string getName() const { return "LLG08_EHO"; }
-  
-private:
-  SubstitutionModel& getModel() { return *pmixmodel_.get(); }
-
-  MixedSubstitutionModel& getMixedModel() { return *pmixmodel_.get(); }
-
-};
 } // end of namespace bpp.
 
 #endif  // _LLG08_EHO_H_
diff --git a/src/Bpp/Phyl/Model/Protein/LLG08_EX2.cpp b/src/Bpp/Phyl/Model/Protein/LLG08_EX2.cpp
index 4cc149e..25b11f1 100644
--- a/src/Bpp/Phyl/Model/Protein/LLG08_EX2.cpp
+++ b/src/Bpp/Phyl/Model/Protein/LLG08_EX2.cpp
@@ -38,6 +38,7 @@
 
 #include "LLG08_EX2.h"
 #include "../FrequenciesSet/ProteinFrequenciesSet.h"
+#include "../MixtureOfSubstitutionModels.h"
 
 #include <Bpp/Numeric/Prob/SimpleDiscreteDistribution.h>
 
@@ -48,8 +49,7 @@ using namespace std;
 /******************************************************************************/
 
 LLG08_EX2::LLG08_EX2(const ProteicAlphabet* alpha) :
-  AbstractBiblioMixedSubstitutionModel("LLG08_EX2."),
-  pmixmodel_()
+  AbstractBiblioMixedSubstitutionModel("LLG08_EX2.")
 {
   // build the submodel
 
@@ -83,21 +83,6 @@ LLG08_EX2::LLG08_EX2(const ProteicAlphabet* alpha) :
   updateMatrices();
 }
 
-LLG08_EX2::LLG08_EX2(const LLG08_EX2& mod2) : AbstractBiblioMixedSubstitutionModel(mod2),
-  pmixmodel_(new MixtureOfSubstitutionModels(*mod2.pmixmodel_))
-{}
-
-LLG08_EX2& LLG08_EX2::operator=(const LLG08_EX2& mod2)
-{
-  AbstractBiblioMixedSubstitutionModel::operator=(mod2);
-
-  pmixmodel_.reset(new MixtureOfSubstitutionModels(*mod2.pmixmodel_));
-
-  return *this;
-}
-
-LLG08_EX2::~LLG08_EX2() {}
-
 /**************** sub model classes */ // ////////
 
 LLG08_EX2::EmbeddedModel::EmbeddedModel(const ProteicAlphabet* alpha, string name) :
diff --git a/src/Bpp/Phyl/Model/Protein/LLG08_EX2.h b/src/Bpp/Phyl/Model/Protein/LLG08_EX2.h
index 4c1165d..6a3327d 100644
--- a/src/Bpp/Phyl/Model/Protein/LLG08_EX2.h
+++ b/src/Bpp/Phyl/Model/Protein/LLG08_EX2.h
@@ -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. 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 _LLG08_EX2_H_
 #define _LLG08_EX2_H_
@@ -71,58 +71,48 @@ namespace bpp
  * Le S.Q., Lartillot N., Gascuel O. (2008) Phil. Trans. R. Soc. B 363:3965--3976.
  */
 
-class LLG08_EX2 :
-  public AbstractBiblioMixedSubstitutionModel
-{
-public:
-  class EmbeddedModel :
-    public AbstractReversibleProteinSubstitutionModel
+  class LLG08_EX2 :
+    public AbstractBiblioMixedSubstitutionModel
   {
-private:
-    double proportion_;
-    string name_;
-
-public:
-    EmbeddedModel(const ProteicAlphabet* alpha, string name);
-    virtual ~EmbeddedModel(){}
-    EmbeddedModel* clone() const { return new EmbeddedModel(*this); }
-    string getName() const { return name_;}
-    double getProportion() const { return proportion_;}
+  public:
+    class EmbeddedModel :
+      public AbstractReversibleProteinSubstitutionModel
+    {
+    private:
+      double proportion_;
+      string name_;
+
+    public:
+      EmbeddedModel(const ProteicAlphabet* alpha, string name);
+      virtual ~EmbeddedModel(){}
+      EmbeddedModel* clone() const { return new EmbeddedModel(*this); }
+      string getName() const { return name_;}
+      double getProportion() const { return proportion_;}
+    };
+
+  public:
+    /**
+     * @brief Build a  EX2 model, with original equilibrium frequencies, probabilities and rates.
+     *
+     * @param alpha A proteic alphabet.
+     *
+     */
+
+    LLG08_EX2(const ProteicAlphabet* alpha);
+
+    LLG08_EX2* clone() const { return new LLG08_EX2(*this); }
+
+    LLG08_EX2(const LLG08_EX2& mod2) : AbstractBiblioMixedSubstitutionModel(mod2)
+    {}
+
+    LLG08_EX2& operator=(const LLG08_EX2& mod2)
+    {
+      AbstractBiblioMixedSubstitutionModel::operator=(mod2);
+      return *this;
+    }
+
+    std::string getName() const { return "LLG08_EX2"; }
   };
-
-private:
-  std::unique_ptr<MixtureOfSubstitutionModels> pmixmodel_;
-
-public:
-  /**
-   * @brief Build a  EX2 model, with original equilibrium frequencies, probabilities and rates.
-   *
-   * @param alpha A proteic alphabet.
-   *
-   */
-
-  LLG08_EX2(const ProteicAlphabet* alpha);
-
-  virtual ~LLG08_EX2();
-
-  LLG08_EX2* clone() const { return new LLG08_EX2(*this); }
-
-  LLG08_EX2(const LLG08_EX2&);
-
-  LLG08_EX2& operator=(const LLG08_EX2&);
-
-  const SubstitutionModel& getModel() const { return *pmixmodel_.get(); }
-
-  const MixedSubstitutionModel& getMixedModel() const { return *pmixmodel_.get(); }
-
-  std::string getName() const { return "LLG08_EX2"; }
-  
-private:
-  SubstitutionModel& getModel() { return *pmixmodel_.get(); }
-
-  MixedSubstitutionModel& getMixedModel() { return *pmixmodel_.get(); }
-
-};
 } // end of namespace bpp.
 
 #endif  // _LLG08_EX2_H_
diff --git a/src/Bpp/Phyl/Model/Protein/LLG08_EX3.cpp b/src/Bpp/Phyl/Model/Protein/LLG08_EX3.cpp
index 5ebcb1a..07cebf0 100644
--- a/src/Bpp/Phyl/Model/Protein/LLG08_EX3.cpp
+++ b/src/Bpp/Phyl/Model/Protein/LLG08_EX3.cpp
@@ -38,6 +38,7 @@
 
 #include "LLG08_EX3.h"
 #include "../FrequenciesSet/ProteinFrequenciesSet.h"
+#include "../MixtureOfSubstitutionModels.h"
 
 #include <Bpp/Numeric/Prob/SimpleDiscreteDistribution.h>
 
@@ -48,8 +49,7 @@ using namespace std;
 /******************************************************************************/
 
 LLG08_EX3::LLG08_EX3(const ProteicAlphabet* alpha) :
-  AbstractBiblioMixedSubstitutionModel("LLG08_EX3."),
-  pmixmodel_()
+  AbstractBiblioMixedSubstitutionModel("LLG08_EX3.")
 {
   // build the submodel
 
@@ -84,21 +84,6 @@ LLG08_EX3::LLG08_EX3(const ProteicAlphabet* alpha) :
   updateMatrices();
 }
 
-LLG08_EX3::LLG08_EX3(const LLG08_EX3& mod2) : AbstractBiblioMixedSubstitutionModel(mod2),
-  pmixmodel_(new MixtureOfSubstitutionModels(*mod2.pmixmodel_))
-{}
-
-LLG08_EX3& LLG08_EX3::operator=(const LLG08_EX3& mod2)
-{
-  AbstractBiblioMixedSubstitutionModel::operator=(mod2);
-
-  pmixmodel_.reset(new MixtureOfSubstitutionModels(*mod2.pmixmodel_));
-
-  return *this;
-}
-
-LLG08_EX3::~LLG08_EX3() {}
-
 /**************** sub model classes */ // ////////
 
 LLG08_EX3::EmbeddedModel::EmbeddedModel(const ProteicAlphabet* alpha, string name) :
diff --git a/src/Bpp/Phyl/Model/Protein/LLG08_EX3.h b/src/Bpp/Phyl/Model/Protein/LLG08_EX3.h
index efbb5df..76e8d31 100644
--- a/src/Bpp/Phyl/Model/Protein/LLG08_EX3.h
+++ b/src/Bpp/Phyl/Model/Protein/LLG08_EX3.h
@@ -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. 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 _LLG08_EX3_H_
 #define _LLG08_EX3_H_
@@ -76,58 +76,49 @@ namespace bpp
  * Le S.Q., Lartillot N., Gascuel O. (2008) Phil. Trans. R. Soc. B 363:3965--3976.
  */
 
-class LLG08_EX3 :
-  public AbstractBiblioMixedSubstitutionModel
-{
-public:
-  class EmbeddedModel :
-    public AbstractReversibleProteinSubstitutionModel
+  class LLG08_EX3 :
+    public AbstractBiblioMixedSubstitutionModel
   {
-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::unique_ptr<MixtureOfSubstitutionModels> pmixmodel_;
-
-public:
-  /**
-   * @brief Build a  EX3 model, with original equilibrium frequencies, probabilities and rates.
-   *
-   * @param alpha A proteic alphabet.
-   *
-   */
-
-  LLG08_EX3(const ProteicAlphabet* alpha);
-
-  ~LLG08_EX3();
-
-  LLG08_EX3* clone() const { return new LLG08_EX3(*this); }
-
-  LLG08_EX3(const LLG08_EX3&);
-
-  LLG08_EX3& operator=(const LLG08_EX3&);
-
-  const SubstitutionModel& getModel() const { return *pmixmodel_.get(); }
-
-  const MixedSubstitutionModel& getMixedModel() const { return *pmixmodel_.get(); }
-
-  std::string getName() const { return "LLG08_EX3"; }
+  public:
+    class EmbeddedModel :
+      public AbstractReversibleProteinSubstitutionModel
+    {
+    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_;}
+    };
+
+  public:
+    /**
+     * @brief Build a  EX3 model, with original equilibrium frequencies, probabilities and rates.
+     *
+     * @param alpha A proteic alphabet.
+     *
+     */
+
+    LLG08_EX3(const ProteicAlphabet* alpha);
+
+    LLG08_EX3* clone() const { return new LLG08_EX3(*this); }
+
+    LLG08_EX3(const LLG08_EX3& mod2) : AbstractBiblioMixedSubstitutionModel(mod2)
+    {}
+
+    LLG08_EX3& operator=(const LLG08_EX3& mod2)
+    {
+      AbstractBiblioMixedSubstitutionModel::operator=(mod2);
+      return *this;
+    }
+
+    std::string getName() const { return "LLG08_EX3"; }
   
-private:
-  SubstitutionModel& getModel() { return *pmixmodel_.get(); }
-
-  MixedSubstitutionModel& getMixedModel() { return *pmixmodel_.get(); }
-
-};
+  };
 } // end of namespace bpp.
 
 #endif  // _LLG08_EX3_H_
diff --git a/src/Bpp/Phyl/Model/Protein/LLG08_UL2.cpp b/src/Bpp/Phyl/Model/Protein/LLG08_UL2.cpp
index cafe1f7..3e1137d 100644
--- a/src/Bpp/Phyl/Model/Protein/LLG08_UL2.cpp
+++ b/src/Bpp/Phyl/Model/Protein/LLG08_UL2.cpp
@@ -38,6 +38,7 @@
 
 #include "LLG08_UL2.h"
 #include "../FrequenciesSet/ProteinFrequenciesSet.h"
+#include "../MixtureOfSubstitutionModels.h"
 
 #include <Bpp/Numeric/Prob/SimpleDiscreteDistribution.h>
 
@@ -48,8 +49,7 @@ using namespace std;
 /******************************************************************************/
 
 LLG08_UL2::LLG08_UL2(const ProteicAlphabet* alpha) :
-  AbstractBiblioMixedSubstitutionModel("LLG08_UL2."),
-  pmixmodel_()
+  AbstractBiblioMixedSubstitutionModel("LLG08_UL2.")
 {
   // build the submodel
 
@@ -83,21 +83,6 @@ LLG08_UL2::LLG08_UL2(const ProteicAlphabet* alpha) :
   updateMatrices();
 }
 
-LLG08_UL2::LLG08_UL2(const LLG08_UL2& mod2) : AbstractBiblioMixedSubstitutionModel(mod2),
-  pmixmodel_(new MixtureOfSubstitutionModels(*mod2.pmixmodel_))
-{}
-
-LLG08_UL2& LLG08_UL2::operator=(const LLG08_UL2& mod2)
-{
-  AbstractBiblioMixedSubstitutionModel::operator=(mod2);
-
-  pmixmodel_.reset(new MixtureOfSubstitutionModels(*mod2.pmixmodel_));
-
-  return *this;
-}
-
-LLG08_UL2::~LLG08_UL2() {}
-
 /**************** sub model classes */ // ////////
 
 LLG08_UL2::EmbeddedModel::EmbeddedModel(const ProteicAlphabet* alpha, string name) :
diff --git a/src/Bpp/Phyl/Model/Protein/LLG08_UL2.h b/src/Bpp/Phyl/Model/Protein/LLG08_UL2.h
index 031fbb2..ac6c04c 100644
--- a/src/Bpp/Phyl/Model/Protein/LLG08_UL2.h
+++ b/src/Bpp/Phyl/Model/Protein/LLG08_UL2.h
@@ -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. 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 _LLG08_UL2_H_
 #define _LLG08_UL2_H_
@@ -71,58 +71,50 @@ namespace bpp
  * Le S.Q., Lartillot N., Gascuel O. (2008) Phil. Trans. R. Soc. B 363:3965--3976.
  */
 
-class LLG08_UL2 :
-  public AbstractBiblioMixedSubstitutionModel
-{
-public:
-  class EmbeddedModel :
-    public AbstractReversibleProteinSubstitutionModel
+  class LLG08_UL2 :
+    public AbstractBiblioMixedSubstitutionModel
   {
-private:
-    double proportion_;
-    string name_;
-
-public:
-    EmbeddedModel(const ProteicAlphabet* alpha, string name);
-    virtual ~EmbeddedModel() {}
-    EmbeddedModel* clone() const { return new EmbeddedModel(*this); }
-    string getName() const { return name_;}
-    double getProportion() const { return proportion_;}
+  public:
+    class EmbeddedModel :
+      public AbstractReversibleProteinSubstitutionModel
+    {
+    private:
+      double proportion_;
+      string name_;
+
+    public:
+      EmbeddedModel(const ProteicAlphabet* alpha, string name);
+      virtual ~EmbeddedModel() {}
+      EmbeddedModel* clone() const { return new EmbeddedModel(*this); }
+      string getName() const { return name_;}
+      double getProportion() const { return proportion_;}
+    };
+
+  public:
+    /**
+     * @brief Build a  UL2 model, with original equilibrium frequencies, probabilities and rates.
+     *
+     * @param alpha A proteic alphabet.
+     *
+     */
+
+    LLG08_UL2(const ProteicAlphabet* alpha);
+
+    LLG08_UL2* clone() const { return new LLG08_UL2(*this); }
+
+    LLG08_UL2(const LLG08_UL2& mod2) :
+      AbstractBiblioMixedSubstitutionModel(mod2)
+    {
+    }
+
+    LLG08_UL2& operator=(const LLG08_UL2& mod2) 
+    {
+      AbstractBiblioMixedSubstitutionModel::operator=(mod2);
+      return *this;
+    }
+
+    std::string getName() const { return "LLG08_UL2"; }
   };
-
-private:
-  std::unique_ptr<MixtureOfSubstitutionModels> pmixmodel_;
-
-public:
-  /**
-   * @brief Build a  UL2 model, with original equilibrium frequencies, probabilities and rates.
-   *
-   * @param alpha A proteic alphabet.
-   *
-   */
-
-  LLG08_UL2(const ProteicAlphabet* alpha);
-
-  ~LLG08_UL2();
-
-  LLG08_UL2* clone() const { return new LLG08_UL2(*this); }
-
-  LLG08_UL2(const LLG08_UL2&);
-
-  LLG08_UL2& operator=(const LLG08_UL2&);
-
-  const SubstitutionModel& getModel() const { return *pmixmodel_.get(); }
-
-  const MixedSubstitutionModel& getMixedModel() const { return *pmixmodel_.get(); }
-
-  std::string getName() const { return "LLG08_UL2"; }
-  
-private:
-  SubstitutionModel& getModel() { return *pmixmodel_.get(); }
-
-  MixedSubstitutionModel& getMixedModel() { return *pmixmodel_.get(); }
-
-};
 } // end of namespace bpp.
 
 #endif  // _LLG08_UL2_H_
diff --git a/src/Bpp/Phyl/Model/Protein/LLG08_UL3.cpp b/src/Bpp/Phyl/Model/Protein/LLG08_UL3.cpp
index 90acf9a..c8dfe11 100644
--- a/src/Bpp/Phyl/Model/Protein/LLG08_UL3.cpp
+++ b/src/Bpp/Phyl/Model/Protein/LLG08_UL3.cpp
@@ -38,6 +38,7 @@
 
 #include "LLG08_UL3.h"
 #include "../FrequenciesSet/ProteinFrequenciesSet.h"
+#include "../MixtureOfSubstitutionModels.h"
 
 #include <Bpp/Numeric/Prob/SimpleDiscreteDistribution.h>
 
@@ -48,8 +49,7 @@ using namespace std;
 /******************************************************************************/
 
 LLG08_UL3::LLG08_UL3(const ProteicAlphabet* alpha) :
-  AbstractBiblioMixedSubstitutionModel("LLG08_UL3."),
-  pmixmodel_()
+  AbstractBiblioMixedSubstitutionModel("LLG08_UL3.")
 {
   // build the submodel
 
@@ -84,20 +84,6 @@ LLG08_UL3::LLG08_UL3(const ProteicAlphabet* alpha) :
   updateMatrices();
 }
 
-LLG08_UL3::LLG08_UL3(const LLG08_UL3& mod2) : AbstractBiblioMixedSubstitutionModel(mod2),
-  pmixmodel_(new MixtureOfSubstitutionModels(*mod2.pmixmodel_))
-{}
-
-LLG08_UL3& LLG08_UL3::operator=(const LLG08_UL3& mod2)
-{
-  AbstractBiblioMixedSubstitutionModel::operator=(mod2);
-
-  pmixmodel_.reset(new MixtureOfSubstitutionModels(*mod2.pmixmodel_));
-
-  return *this;
-}
-
-LLG08_UL3::~LLG08_UL3() {}
 
 /**************** sub model classes */ // ////////
 
diff --git a/src/Bpp/Phyl/Model/Protein/LLG08_UL3.h b/src/Bpp/Phyl/Model/Protein/LLG08_UL3.h
index a8e867b..1c646b6 100644
--- a/src/Bpp/Phyl/Model/Protein/LLG08_UL3.h
+++ b/src/Bpp/Phyl/Model/Protein/LLG08_UL3.h
@@ -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. 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 _LLG08_UL3_H_
 #define _LLG08_UL3_H_
@@ -75,58 +75,49 @@ namespace bpp
  * Le S.Q., Lartillot N., Gascuel O. (2008) Phil. Trans. R. Soc. B 363:3965--3976.
  */
 
-class LLG08_UL3 :
-  public AbstractBiblioMixedSubstitutionModel
-{
-public:
-  class EmbeddedModel :
-    public AbstractReversibleProteinSubstitutionModel
+  class LLG08_UL3 :
+    public AbstractBiblioMixedSubstitutionModel
   {
-private:
-    double proportion_;
-    string name_;
-
-public:
-    EmbeddedModel(const ProteicAlphabet* alpha, string name);
-    virtual ~EmbeddedModel(){}
-    EmbeddedModel* clone() const { return new EmbeddedModel(*this); }
-    string getName() const { return name_;}
-    double getProportion() const { return proportion_;}
+  public:
+    class EmbeddedModel :
+      public AbstractReversibleProteinSubstitutionModel
+    {
+    private:
+      double proportion_;
+      string name_;
+
+    public:
+      EmbeddedModel(const ProteicAlphabet* alpha, string name);
+      virtual ~EmbeddedModel(){}
+      EmbeddedModel* clone() const { return new EmbeddedModel(*this); }
+      string getName() const { return name_;}
+      double getProportion() const { return proportion_;}
+    };
+
+  public:
+    /**
+     * @brief Build a  UL3 model, with original equilibrium frequencies, probabilities and rates.
+     *
+     * @param alpha A proteic alphabet.
+     *
+     */
+
+    LLG08_UL3(const ProteicAlphabet* alpha);
+
+    LLG08_UL3* clone() const { return new LLG08_UL3(*this); }
+
+    LLG08_UL3(const LLG08_UL3& mod2) : AbstractBiblioMixedSubstitutionModel(mod2)
+    {}
+
+    LLG08_UL3& operator=(const LLG08_UL3& mod2)
+    {
+      AbstractBiblioMixedSubstitutionModel::operator=(mod2);
+
+      return *this;
+    }
+
+    std::string getName() const { return "LLG08_UL3"; }
   };
-
-private:
-  std::unique_ptr<MixtureOfSubstitutionModels> pmixmodel_;
-
-public:
-  /**
-   * @brief Build a  UL3 model, with original equilibrium frequencies, probabilities and rates.
-   *
-   * @param alpha A proteic alphabet.
-   *
-   */
-
-  LLG08_UL3(const ProteicAlphabet* alpha);
-
-  ~LLG08_UL3();
-
-  LLG08_UL3* clone() const { return new LLG08_UL3(*this); }
-
-  LLG08_UL3(const LLG08_UL3&);
-
-  LLG08_UL3& operator=(const LLG08_UL3&);
-
-  const SubstitutionModel& getModel() const { return *pmixmodel_.get(); }
-
-  const MixedSubstitutionModel& getMixedModel() const { return *pmixmodel_.get(); }
-
-  std::string getName() const { return "LLG08_UL3"; }
-  
-private:
-  SubstitutionModel& getModel() { return *pmixmodel_.get(); }
-
-  MixedSubstitutionModel& getMixedModel() { return *pmixmodel_.get(); }
-
-};
 } // end of namespace bpp.
 
 #endif  // _LLG08_UL3_H_
diff --git a/src/Bpp/Phyl/Model/Protein/UserProteinSubstitutionModel.h b/src/Bpp/Phyl/Model/Protein/UserProteinSubstitutionModel.h
index 0410f18..8f0caa5 100755
--- a/src/Bpp/Phyl/Model/Protein/UserProteinSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/Protein/UserProteinSubstitutionModel.h
@@ -130,6 +130,13 @@ namespace bpp
       AbstractReversibleSubstitutionModel::fireParameterChanged(parameters);
     }
 
+    void setNamespace(const std::string& prefix)
+    {
+      AbstractParameterAliasable::setNamespace(prefix);
+      freqSet_->setNamespace(prefix + freqSet_->getName() + ".");
+    }
+
+
     void setFrequenciesSet(const ProteinFrequenciesSet& freqSet)
     {
       delete freqSet_;
diff --git a/src/Bpp/Phyl/Model/Protein/WAG01.h b/src/Bpp/Phyl/Model/Protein/WAG01.h
index aad704f..9063879 100644
--- a/src/Bpp/Phyl/Model/Protein/WAG01.h
+++ b/src/Bpp/Phyl/Model/Protein/WAG01.h
@@ -126,6 +126,12 @@ namespace bpp
       AbstractReversibleSubstitutionModel::fireParameterChanged(parameters);
     }
 
+    void setNamespace(const std::string& prefix)
+    {
+      AbstractParameterAliasable::setNamespace(prefix);
+      freqSet_->setNamespace(prefix + freqSet_->getName() + ".");
+    }
+
     void setFrequenciesSet(const ProteinFrequenciesSet& freqSet)
     {
       delete freqSet_;
diff --git a/src/Bpp/Phyl/Model/RE08.h b/src/Bpp/Phyl/Model/RE08.h
index 5d4acbb..b75c43c 100755
--- a/src/Bpp/Phyl/Model/RE08.h
+++ b/src/Bpp/Phyl/Model/RE08.h
@@ -324,6 +324,10 @@ namespace bpp
     }
 
     size_t getNumberOfStates() const { return RE08::getNumberOfStates(); }
+
+    const FrequenciesSet* getFrequenciesSet() const {
+      return ((AbstractSubstitutionModel*)getNestedModel())->getFrequenciesSet();
+    }
   };
 
 
diff --git a/src/Bpp/Phyl/Model/RegisterRatesSubstitutionModel.cpp b/src/Bpp/Phyl/Model/RegisterRatesSubstitutionModel.cpp
new file mode 100644
index 0000000..d9cdf13
--- /dev/null
+++ b/src/Bpp/Phyl/Model/RegisterRatesSubstitutionModel.cpp
@@ -0,0 +1,113 @@
+//
+// File: RegisterRatesSubstitutionModel.cpp
+// Created by: Laurent Gueguen
+// Created on: samedi 24 octobre 2015, � 18h 50
+//
+
+/*
+   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 "RegisterRatesSubstitutionModel.h"
+#include <Bpp/Numeric/Matrix/MatrixTools.h>
+
+using namespace bpp;
+using namespace std;
+
+RegisterRatesSubstitutionModel::RegisterRatesSubstitutionModel(const SubstitutionModel& originalModel, const SubstitutionRegister& reg, bool  isNormalized) :
+  AbstractParameterAliasable("FromRegister."),
+  AbstractSubstitutionModel(originalModel.getAlphabet(), originalModel.getStateMap().clone(), "FromRegister."),
+  originalModel_(originalModel.clone()),
+  registerName_(reg.getName()),
+  vRegStates_(),
+  nbTypes_(reg.getNumberOfSubstitutionTypes()),
+  vRates_(reg.getNumberOfSubstitutionTypes())
+{
+//  getSubstitutionModel().enableEigenDecomposition(false);
+  
+  // record register types
+  isScalable_=isNormalized;
+  
+
+  vRegStates_.resize(nbTypes_);
+  for (auto& vreg : vRegStates_)
+    vreg.resize(getNumberOfStates());
+
+  for (size_t i = 0; i < getNumberOfStates(); i++)
+    for (size_t j = 0; j < getNumberOfStates(); j++)
+      if (i!=j)
+      {
+        size_t nR=reg.getType(i,j);
+        if (nR!=0)
+          vRegStates_[nR-1][i].push_back((unsigned int)j);
+      }
+
+  /// !!! The order of the inclusion of parameters should not be
+  // changed (see updateMatrices for vRates_ update).
+  // rates for all register types
+  for (size_t i=1;i<=nbTypes_;i++)
+    addParameter_(new Parameter("FromRegister.rho_"+reg.getTypeName(i), 1, &Parameter::R_PLUS));
+
+  getModel().setNamespace(getNamespace()+getModel().getNamespace());
+  addParameters_(getModel().getParameters());
+  updateMatrices();
+}
+
+/******************************************************************************/
+
+void RegisterRatesSubstitutionModel::updateMatrices()
+{
+  for (size_t i = 0; i < vRates_.size(); i++)
+    vRates_[i]=getParameter_(i).getValue();
+  
+  RowMatrix<double>& gen=generator_;
+
+  gen=getSubstitutionModel().getGenerator();
+
+  for (size_t t = 0; t < nbTypes_; t++)
+  {
+    double rate = vRates_[t];
+    const VVuint& v=vRegStates_[t];
+    
+    for (size_t i = 0; i < getNumberOfStates(); i++)
+    {
+      const Vuint& v2=v[i];
+      for (const auto& j : v2)
+        gen(i,j)*=rate;
+    }
+  }
+
+  setDiagonal();
+  
+  AbstractSubstitutionModel::updateMatrices();
+}
+
diff --git a/src/Bpp/Phyl/Model/RegisterRatesSubstitutionModel.h b/src/Bpp/Phyl/Model/RegisterRatesSubstitutionModel.h
new file mode 100644
index 0000000..9d20298
--- /dev/null
+++ b/src/Bpp/Phyl/Model/RegisterRatesSubstitutionModel.h
@@ -0,0 +1,268 @@
+//
+// File: RegisterRatesSubstitutionModel.h
+// Created by: Laurent Gueguen
+// Created on: lundi 16 octobre 2017, à 16h 38
+//
+
+/*
+  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 _REGISTER_RATES_TRANSITION_MODEL_H_
+#define _REGISTER_RATES_TRANSITION_MODEL_H_
+
+#include <Bpp/Numeric/AbstractParameterAliasable.h>
+
+#include "AbstractWrappedModel.h"
+#include "AnonymousSubstitutionModel.h"
+#include "AbstractSubstitutionModel.h"
+
+#include "../Mapping/SubstitutionRegister.h"
+
+namespace bpp
+{
+/**
+ * @brief From a model, substitution rates are set into categories
+ * following a given register. Each substitution of a category is then
+ * multiplied by a rate parameter specific to this category.
+ *
+ * It has the same parameters as the SubModel.
+ *
+ * @see SubstitutionRegister
+ */
+
+  class RegisterRatesSubstitutionModel :
+    virtual public AbstractWrappedSubstitutionModel,
+    virtual public AbstractSubstitutionModel
+  {
+  private:
+    /*
+     * @brief The related model.
+     *
+     */
+    
+    std::unique_ptr<SubstitutionModel> originalModel_;
+
+    /*
+     * For output
+     *
+     */
+
+    std::string registerName_;
+
+    /*
+     * @brief Vector of register state -> vector of from states ->
+     * vector of to states (for acceleration purpose)
+     *
+     */ 
+
+    
+    VVVuint vRegStates_;
+    size_t nbTypes_;
+    
+    /*
+     * @brief vector of the rates of the register types
+     *
+     */
+
+    Vdouble vRates_;
+    
+  public:
+    /*
+     * @brief Constructor
+     *
+     * @param originalModel the substitution model used
+     * @param reg the register in which the considered types of event are
+     * used.
+     * @param isNormalized says if model is normalized (default false)
+     *
+     */
+    
+    RegisterRatesSubstitutionModel(const SubstitutionModel& originalModel, const SubstitutionRegister& reg, bool isNormalized = false);
+    
+
+    RegisterRatesSubstitutionModel(const RegisterRatesSubstitutionModel& fmsm) :
+      AbstractParameterAliasable(fmsm),
+      AbstractSubstitutionModel(fmsm),
+      originalModel_(fmsm.originalModel_->clone()),
+      registerName_(fmsm.registerName_),
+      vRegStates_(fmsm.vRegStates_),
+      nbTypes_(fmsm.nbTypes_),
+      vRates_(fmsm.vRates_)
+    {}
+    
+
+    RegisterRatesSubstitutionModel& operator=(const RegisterRatesSubstitutionModel& fmsm)
+    {
+      AbstractSubstitutionModel::operator=(fmsm);
+      originalModel_.reset(fmsm.originalModel_->clone());
+      
+      registerName_= fmsm.registerName_;
+      vRegStates_ = fmsm.vRegStates_;
+      nbTypes_ = fmsm.nbTypes_;
+      vRates_ = fmsm.vRates_;
+        
+      return *this;
+    }
+    
+    ~RegisterRatesSubstitutionModel() {}
+
+    RegisterRatesSubstitutionModel* clone() const { return new RegisterRatesSubstitutionModel(*this); }
+
+  public:
+
+    /*
+     * @brief clear overrides of AbstractSubstitutionModel and
+     * AbstractWrappedSubstitutionModel.
+     *
+     */
+    
+    const std::vector<int>& getAlphabetStates() const
+    {
+      return AbstractWrappedSubstitutionModel::getAlphabetStates();
+    }
+    
+    std::vector<long unsigned int> getModelStates(int i) const
+    {
+      return AbstractWrappedSubstitutionModel::getModelStates(i);
+    }
+
+    std::vector<long unsigned int> getModelStates(const std::string& s) const
+    {
+      return AbstractWrappedSubstitutionModel::getModelStates(s);
+    }
+
+    int getAlphabetStateAsInt(size_t i) const{
+      return AbstractWrappedSubstitutionModel::getAlphabetStateAsInt(i);
+    }
+
+    std::string getAlphabetStateAsChar(size_t s) const
+    {
+      return AbstractWrappedSubstitutionModel::getAlphabetStateAsChar(s);
+    }
+
+    const Alphabet* getAlphabet() const
+    {
+      return AbstractWrappedSubstitutionModel::getAlphabet();
+    }
+
+    const StateMap& getStateMap() const
+    {
+      return AbstractWrappedSubstitutionModel::getStateMap();
+    }
+
+    
+    /*
+     * @brief From AbstractWrappedSubstitutionModel
+     *
+     */
+      
+    const SubstitutionModel& getSubstitutionModel() const
+    {
+      return *originalModel_.get();
+    }
+
+    const TransitionModel& getModel() const
+    {
+      return *originalModel_.get();
+    }
+
+  protected:
+    SubstitutionModel& getSubstitutionModel()
+    {
+      return *originalModel_.get();
+    }
+
+    
+    TransitionModel& getModel()
+    {
+      return *originalModel_.get();
+    }
+
+  public:
+
+    /*
+     * @brief From AbstractSubstitutionModel
+     *
+     */
+    
+    void fireParameterChanged(const ParameterList& parameters)
+    {
+      getSubstitutionModel().matchParametersValues(parameters);
+
+      AbstractParameterAliasable::fireParameterChanged(parameters);
+      
+      updateMatrices();
+    }
+    
+    size_t getNumberOfStates() const
+    {
+      return getModel().getNumberOfStates();
+    }
+
+  public:
+
+    void updateMatrices();
+    
+    std::string getName() const
+    {
+      return "FromRegister";
+    }
+
+    const std::string& getRegisterName() const
+    {
+      return registerName_;
+    }
+
+    void addRateParameter()
+    {
+      throw Exception("RegisterRatesSubstitutionModel::addRateParameter method should not be called, because rates are defined through registers.");
+    }
+
+    /*
+     * @}
+     *
+     */
+
+    void setRate(double rate) { getModel().setRate(rate); }
+
+    double getRate() const { return getModel().getRate(); }
+
+
+  private:
+
+    void setRegStates_();
+      
+  };
+} // end of namespace bpp.
+
+#endif  // _REGISTER_RATES_TRANSITION_MODEL_H_
diff --git a/src/Bpp/Phyl/Model/SubstitutionModel.h b/src/Bpp/Phyl/Model/SubstitutionModel.h
index 543350e..85fab7e 100755
--- a/src/Bpp/Phyl/Model/SubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/SubstitutionModel.h
@@ -209,6 +209,20 @@ namespace bpp
     virtual const Vdouble& getFrequencies() const = 0;
 
     /**
+     * @return Says if equilibrium frequencies should be computed from
+     * the generator
+     */
+    
+    virtual bool computeFrequencies() const = 0;
+
+    /**
+     * @return Set if equilibrium frequencies should be computed from
+     * the generator
+     */
+    
+    virtual void computeFrequencies(bool yn) = 0;
+
+    /**
      * @return All probabilities of change from state i to state j during time t.
      * @see Pij_t()
      */
@@ -299,6 +313,14 @@ namespace bpp
      */
     
     virtual const FrequenciesSet* getFrequenciesSet() const {return NULL;}
+
+  protected:
+
+    virtual Vdouble& getFrequencies_() = 0;
+
+    friend class AbstractTotallyWrappedModel;
+    friend class AbstractFromSubstitutionModelTransitionModel;
+    friend class InMixedSubstitutionModel;
   };
 
   
@@ -408,8 +430,15 @@ namespace bpp
 
     SubstitutionModel* clone() const = 0;
 
-  public:
+  protected:
+    /**
+     * @brief A method for computing all necessary matrices
+     *
+     */
+    
+    virtual void updateMatrices() = 0;
 
+  public:
     /**
      * @return The rate in the generator of change from state i to state j.
      *
@@ -531,20 +560,14 @@ namespace bpp
      */
   
     virtual void normalize() = 0;
-  
-    /**
-     * @brief Get the rate
-     */
-    virtual double getRate() const = 0;
 
     /**
-     * @brief Set the rate of the model (must be positive).
-     * @param rate must be positive.
+     * @brief set the diagonal of the generator such that sum on each
+     * line equals 0.
+     *
      */
-    virtual void setRate(double rate) = 0;
-
-    virtual void addRateParameter() = 0;
-
+  
+    virtual void setDiagonal() = 0;
   };
 
 
diff --git a/src/Bpp/Phyl/Model/SubstitutionModelSet.cpp b/src/Bpp/Phyl/Model/SubstitutionModelSet.cpp
index ee202dd..84e3243 100644
--- a/src/Bpp/Phyl/Model/SubstitutionModelSet.cpp
+++ b/src/Bpp/Phyl/Model/SubstitutionModelSet.cpp
@@ -305,7 +305,7 @@ bool SubstitutionModelSet::hasMixedSubstitutionModel() const
 {
   for (size_t i = 0; i < getNumberOfModels(); i++)
     {
-      if ((dynamic_cast<const MixedSubstitutionModel*>(getTransitionModel(i)) != NULL) && (modelToNodes_[i].size()>1))
+      if ((dynamic_cast<const MixedSubstitutionModel*>(getModel(i)) != NULL) && (modelToNodes_[i].size()>1))
         return true;
     }
   return false;
diff --git a/src/Bpp/Phyl/Model/SubstitutionModelSet.h b/src/Bpp/Phyl/Model/SubstitutionModelSet.h
index fbb6b3c..b6ff208 100644
--- a/src/Bpp/Phyl/Model/SubstitutionModelSet.h
+++ b/src/Bpp/Phyl/Model/SubstitutionModelSet.h
@@ -206,7 +206,10 @@ public:
 
   virtual ~SubstitutionModelSet()
   {
-    for (auto model : modelSet_) { delete model; }
+    for (auto& model : modelSet_)
+    {
+      delete model;
+    }
   }
 
   SubstitutionModelSet* clone() const { return new SubstitutionModelSet(*this); }
@@ -247,47 +250,31 @@ public:
    * @param i Index of the model in the set.
    * @return A pointer toward the corresponding model.
    */
-  
-  const SubstitutionModel* getModel(size_t i) const throw (IndexOutOfBoundsException)
-  {
-    std::cerr << "#warning : SubstitutionModelSet::getModel function is deprecated in Bio++ 2.3.0. Replace it with SubstitutionModelSet::getSubstitutionModel." << std::endl;
-
-    return getSubstitutionModel(i);
-  }
-
-  SubstitutionModel* getModel(size_t i) throw (IndexOutOfBoundsException)
-  {
-    std::cerr << "#warning : SubstitutionModelSet::getModel function is deprecated in Bio++ 2.3.0. Replace it with SubstitutionModelSet::getSubstitutionModel." << std::endl;
-
-    return getSubstitutionModel(i);
-  }
 
-  const TransitionModel* getTransitionModel(size_t i) const throw (IndexOutOfBoundsException)
+  const TransitionModel* getModel(size_t i) const throw (IndexOutOfBoundsException)
   {
     if (i >= modelSet_.size()) throw IndexOutOfBoundsException("SubstitutionModelSet::getNumberOfModels().", 0, modelSet_.size() - 1, i);
     return modelSet_[i];
   }
 
-  TransitionModel* getTransitionModel(size_t i) throw (IndexOutOfBoundsException)
+  TransitionModel* getModel(size_t i) throw (IndexOutOfBoundsException)
   {
     if (i >= modelSet_.size()) throw IndexOutOfBoundsException("SubstitutionModelSet::getNumberOfModels().", 0, modelSet_.size() - 1, i);
     return modelSet_[i];
   }
 
-  /*
-   * @brief Return a markovian substitution model (or null)
-   *
+  /**
+   *@brief Return a markovian substitution model (or null)
    */
-  
   const SubstitutionModel* getSubstitutionModel(size_t i) const throw (IndexOutOfBoundsException)
   {
     try
     {
-      return dynamic_cast<const SubstitutionModel*>(getTransitionModel(i));
+      return dynamic_cast<const SubstitutionModel*>(getModel(i));
     }
     catch (std::bad_cast& bc)
     {
-      throw Exception("SubstitutionModelSet::getSubstitutionModel : model is not a sustitution model " + getTransitionModel(i)->getName());
+      throw Exception("SubstitutionModelSet::getSubstitutionModel : model is not a sustitution model " + getModel(i)->getName());
     }
   }
   
@@ -296,11 +283,11 @@ public:
   {
     try
     {
-      return dynamic_cast<SubstitutionModel*>(getTransitionModel(i));
+      return dynamic_cast<SubstitutionModel*>(getModel(i));
     }
     catch (std::bad_cast& bc)
     {
-      throw Exception("SubstitutionModelSet::getSubstitutionModel : model is not a sustitution model " + getTransitionModel(i)->getName());
+      throw Exception("SubstitutionModelSet::getSubstitutionModel : model is not a sustitution model " + getModel(i)->getName());
     }
   }
 
@@ -311,7 +298,7 @@ public:
  
   bool hasOnlySubstitutionModels() const
   {
-    for (auto mod : modelSet_)
+    for (const auto& mod : modelSet_)
       if (dynamic_cast<const SubstitutionModel*>(mod)==0)
         return false;
 
@@ -483,19 +470,19 @@ public:
    * @see Alphabet
    */
   virtual const std::vector<int>& getAlphabetStates() const {
-    return getTransitionModel(0)->getAlphabetStates();
+    return getModel(0)->getAlphabetStates();
   }
 
   virtual const StateMap& getStateMap() const {
-    return getTransitionModel(0)->getStateMap();
+    return getModel(0)->getStateMap();
   }
 
   virtual std::vector<size_t> getModelStates(int code) const {
-    return getTransitionModel(0)->getModelStates(code);
+    return getModel(0)->getModelStates(code);
   }
 
   virtual std::vector<size_t> getModelStates(const std::string& code) const {
-    return getTransitionModel(0)->getModelStates(code);
+    return getModel(0)->getModelStates(code);
   }
 
   /**
@@ -503,7 +490,7 @@ public:
    * @return The corresponding alphabet state as character code.
    */
   virtual int getAlphabetStateAsInt(size_t index) const {
-    return getTransitionModel(0)->getAlphabetStateAsInt(index);
+    return getModel(0)->getAlphabetStateAsInt(index);
   }
   
   /**
@@ -511,7 +498,7 @@ public:
    * @return The corresponding alphabet state as character code.
    */
   virtual std::string getAlphabetStateAsChar(size_t index) const {
-    return getTransitionModel(0)->getAlphabetStateAsChar(index);
+    return getModel(0)->getAlphabetStateAsChar(index);
   }
 
   /**
diff --git a/src/Bpp/Phyl/Model/WordSubstitutionModel.cpp b/src/Bpp/Phyl/Model/WordSubstitutionModel.cpp
index 3e1c0e3..5279794 100644
--- a/src/Bpp/Phyl/Model/WordSubstitutionModel.cpp
+++ b/src/Bpp/Phyl/Model/WordSubstitutionModel.cpp
@@ -71,6 +71,10 @@ WordSubstitutionModel::WordSubstitutionModel(
     addParameter_(new Parameter("Word.relrate" + TextTools::toString(i + 1), 1.0 / static_cast<int>(nbmod - i), &Parameter::PROP_CONSTRAINT_EX));
   }
 
+  enableEigenDecomposition(false); // the product of the position
+                                   // specific transition probabilities
+  
+  computeFrequencies(false); // it is done in AbstractWordSubstitutionModel
   WordSubstitutionModel::updateMatrices();
 }
 
@@ -80,7 +84,11 @@ WordSubstitutionModel::WordSubstitutionModel(
   const std::string& prefix) :
   AbstractParameterAliasable((prefix == "") ? "Word." : prefix),
   AbstractWordSubstitutionModel(alph, stateMap, (prefix == "") ? "Word." : prefix)
-{}
+{
+  enableEigenDecomposition(false); // the product of the position
+                                   // specific transition probabilities
+  computeFrequencies(false); // it is done in AbstractWordSubstitutionModel
+}
 
 WordSubstitutionModel::WordSubstitutionModel(
   SubstitutionModel* pmodel,
@@ -99,6 +107,9 @@ WordSubstitutionModel::WordSubstitutionModel(
     addParameter_(new Parameter("Word.relrate" + TextTools::toString(i + 1), 1.0 / static_cast<int>(num - i ), &Parameter::PROP_CONSTRAINT_EX));
   }
 
+  enableEigenDecomposition(false); // the product of the position
+                                   // specific transition probabilities
+  computeFrequencies(false); // it is done in AbstractWordSubstitutionModel
   WordSubstitutionModel::updateMatrices();
 }
 
diff --git a/src/Bpp/Phyl/Model/WordSubstitutionModel.h b/src/Bpp/Phyl/Model/WordSubstitutionModel.h
index 5513520..7d3e00b 100644
--- a/src/Bpp/Phyl/Model/WordSubstitutionModel.h
+++ b/src/Bpp/Phyl/Model/WordSubstitutionModel.h
@@ -88,6 +88,7 @@ public:
    *   are owned by the instance.
    * @param prefix the Namespace.
    */
+
   WordSubstitutionModel(ModelList& modelList, const std::string& prefix = "");
 
   /**
diff --git a/src/Bpp/Phyl/Simulation/HomogeneousSequenceSimulator.h b/src/Bpp/Phyl/Model/WrappedModel.h
similarity index 59%
copy from src/Bpp/Phyl/Simulation/HomogeneousSequenceSimulator.h
copy to src/Bpp/Phyl/Model/WrappedModel.h
index 746044f..34ac6f5 100644
--- a/src/Bpp/Phyl/Simulation/HomogeneousSequenceSimulator.h
+++ b/src/Bpp/Phyl/Model/WrappedModel.h
@@ -1,26 +1,26 @@
 //
-// File: HomogeneousSequenceSimulator.h
-// Created by: Julien Dutheil
-// Created on: Wed Aug  24 15:20 2005
+// File: WrappedModel.h
+// Created by: Laurent Guéguen
+// Created on: mardi 26 septembre 2017, à 16h 18
 //
 
 /*
-  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.
 
   This software is governed by the CeCILL  license under French law and
-  abiding by the rules of distribution of free software.  You can  use, 
+  abiding by the rules of distribution of free software.  You can  use,
   modify and/ or redistribute the software under the terms of the CeCILL
   license as circulated by CEA, CNRS and INRIA at the following URL
-  "http://www.cecill.info". 
+  "http://www.cecill.info".
 
   As a counterpart to the access to the source code and  rights to copy,
   modify and redistribute granted by the license, users are provided only
   with a limited warranty  and the software's author,  the holder of the
   economic rights,  and the successive licensors  have only  limited
-  liability. 
+  liability.
 
   In this respect, the user's attention is drawn to the risks associated
   with loading,  using,  modifying and/or developing or reproducing the
@@ -29,49 +29,57 @@
   therefore means  that it is reserved for developers  and  experienced
   professionals having in-depth computer knowledge. Users are therefore
   encouraged to load and test the software's suitability as regards their
-  requirements in conditions enabling the security of their systems and/or 
-  data to be ensured and,  more generally, to use and operate it in the 
-  same conditions as regards security. 
+  requirements in conditions enabling the security of their systems and/or
+  data to be ensured and,  more generally, to use and operate it in the
+  same conditions as regards security.
 
   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 _HOMOGENEOUSSEQUENCESIMULATOR_H_
-#define _HOMOGENEOUSSEQUENCESIMULATOR_H_
+#ifndef _WRAPPED_MODEL_H_
+#define _WRAPPED_MODEL_H_
 
-#include "NonHomogeneousSequenceSimulator.h"
+#include "SubstitutionModel.h"
 
 namespace bpp
 {
-
 /**
- * @brief Site and sequences simulation under homogeneous models.
+ * @brief Wrapping model class
+ *
  *
- * This is an alias class, for clarity and backward compatibility.
  */
-  class HomogeneousSequenceSimulator:
-    public NonHomogeneousSequenceSimulator
+
+  class WrappedModel :
+    public virtual TransitionModel
   {
   public:
-		
-    HomogeneousSequenceSimulator(
-      const TransitionModel* model,
-      const DiscreteDistribution* rate,
-      const Tree* tree
-      ) : NonHomogeneousSequenceSimulator(model, rate, tree) {}
-			
-    virtual ~HomogeneousSequenceSimulator() {}
+    WrappedModel() {}
+    virtual ~WrappedModel() {}
+    
+    virtual const TransitionModel& getModel() const = 0;
 
+  protected:
+    virtual TransitionModel& getModel() = 0;
+  };
+  
+    
+  class WrappedSubstitutionModel :
+    public virtual WrappedModel,
+    public virtual SubstitutionModel
+  {
   public:
-    const TransitionModel* getModel() const
-    {
-      return getSubstitutionModelSet()->getTransitionModel(0);
-    }
-	
+    WrappedSubstitutionModel() {}
+    
+    virtual ~WrappedSubstitutionModel() {}
+    
+    virtual const SubstitutionModel& getSubstitutionModel() const = 0;
+
+  protected:
+    virtual SubstitutionModel& getSubstitutionModel() = 0;
   };
+} // end of namespace bpp.
 
-} //end of namespace bpp.
 
-#endif //_HOMOGENEOUSSEQUENCESIMULATOR_H_
+#endif  // _WRAPPED_MODEL_SUBSTITUTIONMODEL_H_
 
diff --git a/src/Bpp/Phyl/OptimizationTools.cpp b/src/Bpp/Phyl/OptimizationTools.cpp
index 72592a0..3f7ac3e 100644
--- a/src/Bpp/Phyl/OptimizationTools.cpp
+++ b/src/Bpp/Phyl/OptimizationTools.cpp
@@ -656,7 +656,7 @@ DistanceMatrix* OptimizationTools::estimateDistanceMatrix(
   estimationMethod.setVerbose(verbose);
   if (param == DISTANCEMETHOD_PAIRWISE)
   {
-    ParameterList tmp = estimationMethod.getSubstitutionModel().getIndependentParameters();
+    ParameterList tmp = estimationMethod.getModel().getIndependentParameters();
     tmp.addParameters(estimationMethod.getRateDistribution().getIndependentParameters());
     tmp.deleteParameters(parametersToIgnore.getParameterNames());
     estimationMethod.setAdditionalParameters(tmp);
@@ -690,7 +690,7 @@ TreeTemplate<Node>* OptimizationTools::buildDistanceTree(
   estimationMethod.setVerbose(verbose);
   if (param == DISTANCEMETHOD_PAIRWISE)
   {
-    ParameterList tmp = estimationMethod.getSubstitutionModel().getIndependentParameters();
+    ParameterList tmp = estimationMethod.getModel().getIndependentParameters();
     tmp.addParameters(estimationMethod.getRateDistribution().getIndependentParameters());
     tmp.deleteParameters(parametersToIgnore.getParameterNames());
     estimationMethod.setAdditionalParameters(tmp);
@@ -741,7 +741,7 @@ TreeTemplate<Node>* OptimizationTools::buildDistanceTree(
       break;  // Ends here.
 
     // Now, re-estimate parameters:
-    unique_ptr<TransitionModel> model(estimationMethod.getSubstitutionModel().clone());
+    unique_ptr<TransitionModel> model(estimationMethod.getModel().clone());
     unique_ptr<DiscreteDistribution> rdist(estimationMethod.getRateDistribution().clone());
     DRHomogeneousTreeLikelihood tl(*tree,
         *estimationMethod.getData(),
diff --git a/src/Bpp/Phyl/Simulation/HomogeneousSequenceSimulator.h b/src/Bpp/Phyl/Simulation/HomogeneousSequenceSimulator.h
index 746044f..4f43813 100644
--- a/src/Bpp/Phyl/Simulation/HomogeneousSequenceSimulator.h
+++ b/src/Bpp/Phyl/Simulation/HomogeneousSequenceSimulator.h
@@ -66,7 +66,7 @@ namespace bpp
   public:
     const TransitionModel* getModel() const
     {
-      return getSubstitutionModelSet()->getTransitionModel(0);
+      return getSubstitutionModelSet()->getModel(0);
     }
 	
   };
diff --git a/src/Bpp/Phyl/Simulation/MutationProcess.cpp b/src/Bpp/Phyl/Simulation/MutationProcess.cpp
index 135ebc9..c189ece 100644
--- a/src/Bpp/Phyl/Simulation/MutationProcess.cpp
+++ b/src/Bpp/Phyl/Simulation/MutationProcess.cpp
@@ -43,6 +43,7 @@
 #include <Bpp/Numeric/Random/RandomTools.h>
 
 using namespace bpp;
+using namespace std;
 
 /******************************************************************************/
 
@@ -105,6 +106,7 @@ MutationPath AbstractMutationProcess::detailedEvolve(size_t initialState, double
   MutationPath mp(model_->getAlphabet(), initialState, time);
   double t = 0;
   size_t currentState = initialState;
+    
   t += getTimeBeforeNextMutationEvent(currentState);
   while (t < time)
   {
@@ -128,24 +130,29 @@ SimpleMutationProcess::SimpleMutationProcess(const SubstitutionModel* model) :
   RowMatrix<double> Q = model->getGenerator();
   for (size_t i = 0; i < size_; i++)
   {
-    repartition_[i] = Vdouble(size_);
-    double cum = 0;
-    double sum_Q = 0;
-    for (size_t j = 0; j < size_; j++)
+    repartition_[i] = Vdouble(size_,0);
+    if (abs(Q(i,i))> NumConstants::TINY())
     {
-      if (j != i) sum_Q += Q(i, j);
-    }
-    for (size_t j = 0; j < size_; j++)
-    {
-      if (j != i)
+      double cum = 0;
+      double sum_Q = 0;
+      for (size_t j = 0; j < size_; j++)
+      {
+        if (j != i) sum_Q += Q(i, j);
+      }
+      
+      for (size_t j = 0; j < size_; j++)
       {
-        cum += model->Qij(i, j) / sum_Q;
-        repartition_[i][j] = cum;
+        if (j != i)
+        {
+          cum += model->Qij(i, j) / sum_Q;
+          repartition_[i][j] = cum;
+        }
+        else repartition_[i][j] = -1;
+        // Forbiden value: does not correspond to a change.
       }
-      else repartition_[i][j] = -1;
-      // Forbiden value: does not correspond to a change.
     }
   }
+  
   // Note that I use cumulative probabilities in repartition_ (hence the name).
   // These cumulative probabilities are useful for the 'mutate(...)' function.
 }
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 4f39a0d..b963371 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -61,6 +61,7 @@ set (CPP_FILES
   Bpp/Phyl/Likelihood/RNonHomogeneousMixedTreeLikelihood.cpp
   Bpp/Phyl/Likelihood/RNonHomogeneousTreeLikelihood.cpp
   Bpp/Phyl/Likelihood/TreeLikelihoodTools.cpp
+  Bpp/Phyl/Mapping/DecompositionMethods.cpp
   Bpp/Phyl/Mapping/DecompositionReward.cpp
   Bpp/Phyl/Mapping/DecompositionSubstitutionCount.cpp
   Bpp/Phyl/Mapping/LaplaceSubstitutionCount.cpp
@@ -81,19 +82,20 @@ set (CPP_FILES
   Bpp/Phyl/Model/AbstractSubstitutionModel.cpp
   Bpp/Phyl/Model/AbstractWordSubstitutionModel.cpp
   Bpp/Phyl/Model/BinarySubstitutionModel.cpp
+  Bpp/Phyl/Model/Codon/AbstractCodonAARateSubstitutionModel.cpp
+  Bpp/Phyl/Model/Codon/AbstractCodonAAFitnessSubstitutionModel.cpp
   Bpp/Phyl/Model/Codon/AbstractCodonCpGSubstitutionModel.cpp
+  Bpp/Phyl/Model/Codon/AbstractCodonBGCSubstitutionModel.cpp
   Bpp/Phyl/Model/Codon/AbstractCodonDistanceSubstitutionModel.cpp
   Bpp/Phyl/Model/Codon/AbstractCodonFitnessSubstitutionModel.cpp
   Bpp/Phyl/Model/Codon/AbstractCodonFrequenciesSubstitutionModel.cpp
   Bpp/Phyl/Model/Codon/AbstractCodonPhaseFrequenciesSubstitutionModel.cpp
   Bpp/Phyl/Model/Codon/AbstractCodonSubstitutionModel.cpp
   Bpp/Phyl/Model/Codon/AbstractKroneckerCodonSubstitutionModel.cpp
-  Bpp/Phyl/Model/Codon/CodonDistanceCpGSubstitutionModel.cpp
+  Bpp/Phyl/Model/Codon/CodonAdHocSubstitutionModel.cpp
   Bpp/Phyl/Model/Codon/CodonDistanceFrequenciesSubstitutionModel.cpp
   Bpp/Phyl/Model/Codon/CodonDistancePhaseFrequenciesSubstitutionModel.cpp
   Bpp/Phyl/Model/Codon/CodonDistanceSubstitutionModel.cpp
-  Bpp/Phyl/Model/Codon/CodonRateFrequenciesSubstitutionModel.cpp
-  Bpp/Phyl/Model/Codon/CodonRateSubstitutionModel.cpp
   Bpp/Phyl/Model/Codon/GY94.cpp
   Bpp/Phyl/Model/Codon/KCM.cpp
   Bpp/Phyl/Model/Codon/KroneckerCodonDistanceFrequenciesSubstitutionModel.cpp 
@@ -115,6 +117,7 @@ set (CPP_FILES
   Bpp/Phyl/Model/FrequenciesSet/NucleotideFrequenciesSet.cpp
   Bpp/Phyl/Model/FrequenciesSet/WordFrequenciesSet.cpp
   Bpp/Phyl/Model/FromMixtureSubstitutionModel.cpp
+  Bpp/Phyl/Model/InMixedSubstitutionModel.cpp
   Bpp/Phyl/Model/KroneckerWordSubstitutionModel.cpp
   Bpp/Phyl/Model/MarkovModulatedSubstitutionModel.cpp
   Bpp/Phyl/Model/MixedSubstitutionModelSet.cpp
@@ -134,6 +137,7 @@ set (CPP_FILES
   Bpp/Phyl/Model/Nucleotide/YpR.cpp
   Bpp/Phyl/Model/Nucleotide/gBGC.cpp
   Bpp/Phyl/Model/OneChangeTransitionModel.cpp
+  Bpp/Phyl/Model/OneChangeRegisterTransitionModel.cpp
   Bpp/Phyl/Model/Protein/Coala.cpp
   Bpp/Phyl/Model/Protein/CoalaCore.cpp
   Bpp/Phyl/Model/Protein/DSO78.cpp
@@ -150,6 +154,7 @@ set (CPP_FILES
   Bpp/Phyl/Model/Protein/UserProteinSubstitutionModel.cpp
   Bpp/Phyl/Model/Protein/WAG01.cpp
   Bpp/Phyl/Model/RE08.cpp
+  Bpp/Phyl/Model/RegisterRatesSubstitutionModel.cpp
   Bpp/Phyl/Model/StateMap.cpp
   Bpp/Phyl/Model/SubstitutionModelSet.cpp
   Bpp/Phyl/Model/SubstitutionModelSetTools.cpp
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 206cef3..0a472cf 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -16,9 +16,12 @@ foreach (test_cpp_file ${test_cpp_files})
   get_filename_component (test_name ${test_cpp_file} NAME_WE)
   add_executable (${test_name} ${test_cpp_file})
   target_link_libraries (${test_name} ${PROJECT_NAME}-shared)
+  set_target_properties (${test_name} PROPERTIES POSITION_INDEPENDENT_CODE TRUE)
   add_test (
     NAME ${test_name}
     WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
     COMMAND ${test_name}
     )
+  set_tests_properties (${test_name} PROPERTIES TIMEOUT 60000)
 endforeach (test_cpp_file)
+
diff --git a/test/test_likelihood_clock.cpp b/test/test_likelihood_clock.cpp
index fa70e89..2e0b9d7 100644
--- a/test/test_likelihood_clock.cpp
+++ b/test/test_likelihood_clock.cpp
@@ -41,7 +41,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/Model/RateDistribution/ConstantRateDistribution.h>
 #include <Bpp/Phyl/Simulation/HomogeneousSequenceSimulator.h>
 #include <Bpp/Phyl/Likelihood/RHomogeneousTreeLikelihood.h>
 #include <Bpp/Phyl/Likelihood/RHomogeneousClockTreeLikelihood.h>
@@ -60,8 +60,8 @@ void fitModelH(SubstitutionModel* model, DiscreteDistribution* rdist, const Tree
   ApplicationTools::displayResult("Test model", model->getName());
   cout << setprecision(20) << tl.getValue() << endl;
   ApplicationTools::displayResult("* initial likelihood", tl.getValue());
-  if (abs(tl.getValue() - initialValue) > 0.0001)
-    throw Exception("Incorrect initial value.");
+  if (abs(tl.getValue() - initialValue) > 0.001)
+    throw Exception("Incorrect initial value:" + TextTools::toString(tl.getValue()) + "<>" + TextTools::toString(initialValue));
   unique_ptr<OutputStream> messenger(new StlOutputStream(new ofstream("messages.txt", ios::out)));
   unique_ptr<OutputStream> profiler(new StlOutputStream(new ofstream("profile.txt", ios::out)));
   profiler->setPrecision(20);
@@ -69,8 +69,8 @@ void fitModelH(SubstitutionModel* model, DiscreteDistribution* rdist, const Tree
   cout << setprecision(20) << tl.getValue() << endl;
   ApplicationTools::displayResult("* likelihood after full optimization", tl.getValue());
   tl.getParameters().printParameters(cout);
-  if (abs(tl.getValue() - finalValue) > 0.0001)
-    throw Exception("Incorrect final value.");
+  if (abs(tl.getValue() - finalValue) > 0.001)
+    throw Exception("Incorrect final value:" + TextTools::toString(tl.getValue()) + "<>" + TextTools::toString(finalValue));
 }
 
 void fitModelHClock(SubstitutionModel* model, DiscreteDistribution* rdist, const Tree& tree, const SiteContainer& sites,
@@ -83,7 +83,7 @@ void fitModelHClock(SubstitutionModel* model, DiscreteDistribution* rdist, const
   cout << setprecision(20) << tl.getValue() << endl;
   ApplicationTools::displayResult("* initial likelihood", tl.getValue());
   if (abs(tl.getValue() - initialValue) > 0.001)
-    throw Exception("Incorrect initial value.");
+    throw Exception("Incorrect initial value:" + TextTools::toString(tl.getValue()) + "<>" + TextTools::toString(initialValue));
   unique_ptr<OutputStream> messenger(new StlOutputStream(new ofstream("messages.txt", ios::out)));
   unique_ptr<OutputStream> profiler(new StlOutputStream(new ofstream("profile.txt", ios::out)));
   profiler->setPrecision(20);
@@ -92,7 +92,7 @@ void fitModelHClock(SubstitutionModel* model, DiscreteDistribution* rdist, const
   ApplicationTools::displayResult("* likelihood after full optimization", tl.getValue());
   tl.getParameters().printParameters(cout);
   if (abs(tl.getValue() - finalValue) > 0.001)
-    throw Exception("Incorrect final value.");
+    throw Exception("Incorrect final value:" + TextTools::toString(tl.getValue()) + "<>" + TextTools::toString(finalValue));
 }
 
 int main() {
@@ -103,7 +103,7 @@ int main() {
 
   const NucleicAlphabet* alphabet = &AlphabetTools::DNA_ALPHABET;
   SubstitutionModel* model = new T92(alphabet, 3.);
-  DiscreteDistribution* rdist = new GammaDiscreteRateDistribution(4, 1.0);
+  DiscreteDistribution* rdist = new ConstantRateDistribution();
 
   VectorSiteContainer sites(alphabet);
   sites.addSequence(BasicSequence("A", "AAATGGCTGTGCACGTC", alphabet));
@@ -112,13 +112,13 @@ int main() {
   sites.addSequence(BasicSequence("D", "CAACGGGAGTGCGCCTA", alphabet));
 
   try {
-    fitModelH(model, rdist, *tree, sites, 93.017264552603336369, 71.265543199977557265);
+    fitModelH(model, rdist, *tree, sites, 94.3957, 71.2657);
   } catch (Exception& ex) {
     cerr << ex.what() << endl;
     return 1;
   }
   try {
-    fitModelHClock(model, rdist, *tree, sites, 92.27912072473920090943, 71.26554020984087856050);
+    fitModelHClock(model, rdist, *tree, sites, 92.3295, 71.2657);
   } catch (Exception& ex) {
     cerr << ex.what() << endl;
     return 1;
diff --git a/test/test_mapping.cpp b/test/test_mapping.cpp
index cb649d9..1729fcf 100644
--- a/test/test_mapping.cpp
+++ b/test/test_mapping.cpp
@@ -64,7 +64,8 @@ using namespace bpp;
 using namespace std;
 
 int main() {
-  TreeTemplate<Node>* tree = TreeTemplateTools::parenthesisToTree("((A:0.001, B:0.002):0.008,C:0.01,D:0.1);");
+  try {
+  TreeTemplate<Node>* tree = TreeTemplateTools::parenthesisToTree("((A:0.001, B:0.002):0.008,C:0.01,D:0.02);");
   vector<int> ids = tree->getNodesId();
   ids.pop_back(); //Ignore root
 
@@ -79,23 +80,12 @@ int main() {
   TotalSubstitutionRegister* totReg = new TotalSubstitutionRegister(model);
   ComprehensiveSubstitutionRegister* detReg = new ComprehensiveSubstitutionRegister(model);
 
-
-  cout << "test mem" << endl;
-  ProteicAlphabet* alphabet2 = new ProteicAlphabet();
-  ReversibleSubstitutionModel* model2 = new JTT92(alphabet2);
-  AlphabetIndex1* ind = new GranthamAAVolumeIndex();
-  for (size_t i = 0; i < 1000000; i++) {
-    cout << i << endl;
-    unique_ptr<DecompositionReward> d(new DecompositionReward(model2, ind));
-  }
-  cout << "done" << endl;
-
-  unsigned int n = 20000;
+  size_t n = 50000;
   vector< vector<double> > realMap(n);
   vector< vector< vector<double> > > realMapTotal(n);
   vector< vector< vector<double> > > realMapDetailed(n);
   VectorSiteContainer sites(tree->getLeavesNames(), alphabet);
-  for (unsigned int i = 0; i < n; ++i) {
+  for (size_t i = 0; i < n; ++i) {
     ApplicationTools::displayGauge(i, n - 1, '=');
     unique_ptr<RASiteSimulationResult> result(simulator.dSimulateSite());
     realMap[i].resize(ids.size());
@@ -108,11 +98,11 @@ int main() {
       result->getSubstitutionCount(ids[j], *totReg, realMapTotal[i][j]);
       result->getSubstitutionCount(ids[j], *detReg, realMapDetailed[i][j]);
       if (realMapTotal[i][j][0] != realMap[i][j]) {
-        cerr << "Error, total substitution register provides wrong result." << endl;
+        throw Exception("Error, total substitution register provides wrong result.");
         return 1;
       }
       if (abs(VectorTools::sum(realMapDetailed[i][j]) - realMap[i][j]) > 0.000001) {
-        cerr << "Error, detailed substitution register provides wrong result." << endl;
+        throw Exception("Error, detailed substitution register provides wrong result.");
         return 1;
       }
     }
@@ -132,7 +122,7 @@ int main() {
 
   SubstitutionCount* sCountAna = new LaplaceSubstitutionCount(model, 10);
   Matrix<double>* m = sCountAna->getAllNumbersOfSubstitutions(0.001, 1);
-  cout << "Analytical total count:" << endl;
+  cout << "Analytical (Laplace) total count:" << endl;
   MatrixTools::print(*m);
   delete m;
   ProbabilisticSubstitutionMapping* probMapAna = 
@@ -191,53 +181,22 @@ int main() {
 
   //Check saturation:
   cout << "checking saturation..." << endl;
-  m = sCountUniDet->getAllNumbersOfSubstitutions(0.001,1);
-  cout << "Total count, uniformization method:" << endl;
-  MatrixTools::print(*m);
-  cout << MatrixTools::sumElements(*m) << endl;
-  delete m;
-  m = sCountUniDet->getAllNumbersOfSubstitutions(0.01,1);
-  cout << "Total count, uniformization method:" << endl;
-  MatrixTools::print(*m);
-  cout << MatrixTools::sumElements(*m) << endl;
-  delete m;
-  m = sCountUniDet->getAllNumbersOfSubstitutions(0.1,1);
-  cout << "Total count, uniformization method:" << endl;
-  MatrixTools::print(*m);
-  cout << MatrixTools::sumElements(*m) << endl;
-  delete m;
-  m = sCountUniDet->getAllNumbersOfSubstitutions(1,1);
-  cout << "Total count, uniformization method:" << endl;
-  MatrixTools::print(*m);
-  cout << MatrixTools::sumElements(*m) << endl;
-  delete m;
-  m = sCountUniDet->getAllNumbersOfSubstitutions(2,1);
-  cout << "Total count, uniformization method:" << endl;
-  MatrixTools::print(*m);
-  cout << MatrixTools::sumElements(*m) << endl;
-  delete m;
-  m = sCountUniDet->getAllNumbersOfSubstitutions(3,1);
-  cout << "Total count, uniformization method:" << endl;
-  MatrixTools::print(*m);
-  cout << MatrixTools::sumElements(*m) << endl;
-  delete m;
-  m = sCountUniDet->getAllNumbersOfSubstitutions(4,1);
-  cout << "Total count, uniformization method:" << endl;
-  MatrixTools::print(*m);
-  cout << MatrixTools::sumElements(*m) << endl;
-  delete m;
-  m = sCountUniDet->getAllNumbersOfSubstitutions(10,1);
-  cout << "Total count, uniformization method:" << endl;
-  MatrixTools::print(*m);
-  cout << MatrixTools::sumElements(*m) << endl;
-  delete m;
-
+  double td[] = {0.001, 0.01, 0.1, 1, 2, 3, 4, 10};
+  Vdouble vd(td, td+sizeof(td)/sizeof(double));
 
+  for (auto d : vd)
+  {
+    m = sCountUniDet->getAllNumbersOfSubstitutions(d,1);
+    cout << "Total count, uniformization method for " << d << endl;
+    MatrixTools::print(*m);
+    cout << MatrixTools::sumElements(*m) << endl;
+    delete m;
+  }
 
   //Check per branch:
   
   //1. Total:
-  for (unsigned int j = 0; j < ids.size(); ++j) {
+  for (size_t j = 0; j < ids.size(); ++j) {
     double totalReal = 0;
     double totalObs1 = 0;
     double totalObs2 = 0;
@@ -246,7 +205,7 @@ int main() {
     double totalObs5 = 0;
     double totalObs6 = 0;
     double totalObs7 = 0;
-    for (unsigned int i = 0; i < n; ++i) {
+    for (size_t i = 0; i < n; ++i) {
       totalReal += realMap[i][j];
       totalObs1 += probMapAna->getNumberOfSubstitutions(ids[j], i, 0);
       totalObs2 += probMapTot->getNumberOfSubstitutions(ids[j], i, 0);
@@ -258,21 +217,21 @@ int main() {
     }
     if (tree->isLeaf(ids[j])) cout << tree->getNodeName(ids[j]) << "\t";
     cout << tree->getDistanceToFather(ids[j]) << "\t" << totalReal << "\t" << totalObs1 << "\t" << totalObs2 << "\t" << totalObs3 << "\t" << totalObs4 << "\t" << totalObs5 << "\t" << totalObs6 << "\t" << totalObs7 << endl;
-    if (abs(totalReal - totalObs1) / totalReal > 0.1) return 1;
-    if (abs(totalReal - totalObs2) / totalReal > 0.1) return 1;
-    if (abs(totalReal - totalObs3) / totalReal > 0.1) return 1;
-    if (abs(totalReal - totalObs4) / totalReal > 0.1) return 1;
-    if (abs(totalReal - totalObs5) / totalReal > 0.1) return 1;
-    if (abs(totalReal - totalObs6) / totalReal > 0.1) return 1;
-    if (abs(totalReal - totalObs7) / totalReal > 0.1) return 1;
+    if (abs(totalReal - totalObs1) / totalReal > 0.1) throw Exception("Laplace substitution mapping failed, observed: " + TextTools::toString(totalObs1) + ", expected " + TextTools::toString(totalReal));
+    //if (abs(totalReal - totalObs2) / totalReal > 0.1) return 1; //We do not expect the naive mapping to actually give an accurate result!
+    //if (abs(totalReal - totalObs3) / totalReal > 0.1) return 1;
+    if (abs(totalReal - totalObs4) / totalReal > 0.1) throw Exception("Uniformization (total) substitution mapping failed, observed: " + TextTools::toString(totalObs4) + ", expected " + TextTools::toString(totalReal));
+    if (abs(totalReal - totalObs5) / totalReal > 0.1) throw Exception("Uniformization (detailed) substitution mapping failed, observed: " + TextTools::toString(totalObs5) + ", expected " + TextTools::toString(totalReal));
+    if (abs(totalReal - totalObs6) / totalReal > 0.1) throw Exception("Decomposition (total) substitution mapping failed, observed: " + TextTools::toString(totalObs6) + ", expected " + TextTools::toString(totalReal));
+    if (abs(totalReal - totalObs7) / totalReal > 0.1) throw Exception("Decomposition (detailed) substitution mapping failed, observed: " + TextTools::toString(totalObs7) + ", expected " + TextTools::toString(totalReal));
   }
   //2. Detail:
-  for (unsigned int j = 0; j < ids.size(); ++j) {
+  for (size_t j = 0; j < ids.size(); ++j) {
     vector<double> real(4, 0);
     vector<double> obs1(4, 0);
     vector<double> obs2(4, 0);
     vector<double> obs3(4, 0);
-    for (unsigned int i = 0; i < n; ++i) {
+    for (size_t i = 0; i < n; ++i) {
       real += realMapDetailed[i][j];
       //VectorTools::print(real);
       vector<double> c = probMapDet->getNumberOfSubstitutions(ids[j], i);
@@ -306,5 +265,11 @@ int main() {
   delete probMapUniTot;
   delete probMapUniDet;
   //return (abs(obs - 0.001) < 0.001 ? 0 : 1);
+  } catch (exception& e) {
+    cout << "Test failed. Reason:" << endl;
+    cout << e.what() << endl;
+    return 1;
+  }
+
   return 0;
 }
diff --git a/test/test_mapping_codon.cpp b/test/test_mapping_codon.cpp
index d79e5a0..005caf9 100644
--- a/test/test_mapping_codon.cpp
+++ b/test/test_mapping_codon.cpp
@@ -47,7 +47,6 @@ knowledge of the CeCILL license and that you accept its terms.
 #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>
 #include <Bpp/Phyl/Likelihood/DRHomogeneousTreeLikelihood.h>
@@ -73,11 +72,7 @@ int main() {
   CodonAlphabet* alphabet = new CodonAlphabet(&AlphabetTools::DNA_ALPHABET);
   GeneticCode* gc = new StandardGeneticCode(&AlphabetTools::DNA_ALPHABET);
   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(model);
diff --git a/test/test_models.cpp b/test/test_models.cpp
index da57f5b..cfcfeb3 100644
--- a/test/test_models.cpp
+++ b/test/test_models.cpp
@@ -120,6 +120,7 @@ int main() {
   const CodonAlphabet* codonAlphabet = new CodonAlphabet(&AlphabetTools::DNA_ALPHABET);
   FrequenciesSet* fset = CodonFrequenciesSet::getFrequenciesSetForCodons(CodonFrequenciesSet::F3X4, &gc);
   YN98 yn98(&gc, fset);
+  
   if (!testModel(yn98)) return 1;
 
   delete codonAlphabet;

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