[med-svn] [phyml] 05/07: Imported Upstream version 3.2.20160530+dfsg

Andreas Tille tille at debian.org
Wed Jul 20 09:43:52 UTC 2016


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

tille pushed a commit to branch master
in repository phyml.

commit cf20f11660c8cc2d8b9238ba0b0f4e533eaa4103
Author: Andreas Tille <tille at debian.org>
Date:   Wed Jul 20 09:36:35 2016 +0200

    Imported Upstream version 3.2.20160530+dfsg
---
 NEWS                                      |    0
 README                                    |   30 +-
 autogen.sh                                |    0
 config.h.in                               |    3 +
 configure.ac                              |   24 +-
 doc/fig/phyrexlog.pdf                     |  Bin 0 -> 463638 bytes
 doc/phyml-manual.pdf                      |  Bin 407931 -> 885797 bytes
 doc/phyml-manual.tex                      |  135 +-
 doc/ref.bib                               |   74 +
 examples/phyrex_input_files/h1n1.nxs      |  613 +++++++
 examples/phyrex_input_files/usa_coord.txt |   53 +
 src/Makefile.am                           |   90 +-
 src/alrt.c                                |  262 +--
 src/cl.c                                  |  109 +-
 src/cl.h                                  |    1 +
 src/date.c                                |  789 ++++++++
 src/date.h                                |   41 +
 src/free.c                                |  230 ++-
 src/free.h                                |   12 +-
 src/init.c                                |  300 +--
 src/init.h                                |   10 +-
 src/interface.c                           |   27 +-
 src/invitee.c                             |   60 +-
 src/invitee.h                             |    2 +-
 src/io.c                                  | 1666 ++++-------------
 src/io.h                                  |    7 +
 src/lk.c                                  |  958 +++++-----
 src/m4.c                                  |    6 +-
 src/main.c                                |   29 +-
 src/make.c                                |  143 +-
 src/make.h                                |   12 +-
 src/mcmc.c                                |  370 +++-
 src/mcmc.h                                |    5 +-
 src/mg.c                                  | 2820 -----------------------------
 src/mg.h                                  |   51 -
 src/mixt.c                                |  829 +++++++--
 src/mixt.h                                |   16 +-
 src/models.c                              |   16 +-
 src/mpi_boot.c                            |    2 +-
 src/optimiz.c                             |  221 ++-
 src/pars.c                                |  182 +-
 src/phyrex.c                              |  375 ++--
 src/phyrex.h                              |    4 +-
 src/rates.c                               |    8 +-
 src/simu.c                                |  715 ++++----
 src/spr.c                                 | 1237 +++++++------
 src/spr.h                                 |   14 +-
 src/stats.c                               |   13 +-
 src/stats.h                               |    2 +-
 src/times.c                               |  507 +++++-
 src/times.h                               |    3 +
 src/utilities.c                           | 2358 ++++++++++++++----------
 src/utilities.h                           |  193 +-
 src/xml.c                                 | 1146 +++++++++++-
 src/xml.h                                 |    3 +
 55 files changed, 9228 insertions(+), 7548 deletions(-)

diff --git a/NEWS b/NEWS
deleted file mode 100644
index e69de29..0000000
diff --git a/README b/README
index ee27cf1..6a8d709 100644
--- a/README
+++ b/README
@@ -3,30 +3,40 @@
 // You have downloaded the Stable or the Development version of PhyML   //
 //////////////////////////////////////////////////////////////////////////
 
-To install PhyML, type the following commands:
-./configure;
+To install any program that is part of the PhyML package, type the following commands:
+./configure --enable-XXXX;
 make;
+where XXXX is phyml or phyrex or phytime.
 
-To install PhyML (MPI version_, type the following commands:
-./configure --enable-mpi;
+To install the MPI version of PhyML, type the following commands:
+./configure --enable-mpi --enable-XXXX;
 make;
 
 
-To install PhyTime, type the following commands:
-./configure --enable-phytime;
+To compile a Windows executable, install MinGW and run:
+./configure --enable-win --enable-XXXX;
 make;
 
 
-To compile a Windows executable, install MinGW and run:
-ac_cv_func_malloc_0_nonnull=yes ac_cv_func_realloc_0_nonnull=yes mingw64-configure;
-make;
+If you are using a Mac computer, you will need to install the package pkg-config. The
+following command should set you up (provided Homebrew is installed on your Mac...):
+brew install pkg-config; Next, typing './configure --enable-XXXX; make;' should generate
+the phyml binary in the src/ directory.
+
 
 
 //////////////////////////////////////////////////////////////////////////
 //                    You have cloned PhyML from GitHub                 //
 //////////////////////////////////////////////////////////////////////////
 
-To install PhyML, type the following command:
+To install any program that is part of the PhyML package, type the following command:
 sh ./autogen.sh;
 
+If you are using a Mac computer, you will need to install the packages autoconf automake libtool 
+and pkg-config. The following command should set you up (provided Homebrew is installed on your Mac...):
+brew install pkg-config autoconf automake libtool;
+
+Next, typing './configure --enable-XXXX; make;' should generate the phyml binary in the src/
+directory, where XXXX is phyml or phyrex or phytime.
+
 
diff --git a/autogen.sh b/autogen.sh
old mode 100644
new mode 100755
diff --git a/config.h.in b/config.h.in
index ebe7993..d4d67e7 100644
--- a/config.h.in
+++ b/config.h.in
@@ -6,6 +6,9 @@
 /* CHECKPOINT tag on */
 #undef CHECKPOINT
 
+/* DATE tag on */
+#undef DATE
+
 /* Debug tag on */
 #undef DEBUG
 
diff --git a/configure.ac b/configure.ac
index b5d1d7d..db1ff63 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,9 +1,10 @@
 #                                               -*- Autoconf -*-
 # Process this file with autoconf to produce a configure script.
 
-AC_INIT([PhyML],esyscmd([sh -c "date \"+%Y%m%d\" | tr -d '\n'"]),[s.guindon at auckland.ac.nz])
+AC_INIT([PhyML],esyscmd([sh -c "echo "3.2." | tr -d '\n' ; date \"+%Y%m%d\" | tr -d '\n'"]),[guindon at lirmm.fr])
 AM_INIT_AUTOMAKE([foreign])
 m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES])
+AC_CONFIG_MACRO_DIR([m4])
 
 AC_CONFIG_SRCDIR([src/simu.c],[doc/phyml-manual.tex])
 AC_CONFIG_HEADERS([config.h])
@@ -88,13 +89,14 @@ AC_ARG_ENABLE([mpi],
                               [Compile with mpicc instead of gcc.])])
 AS_IF([test "x$enable_mpi" = "xyes"],[CC="mpicc"])
 AS_IF([test "x$enable_mpi" = "xyes"],AC_DEFINE([MPI],[1],[MPI tag on]))
-AM_CONDITIONAL([WANT_MPI], [test "x$enable_mpi" = "xyes"])
+AM_CONDITIONAL([WANT_MPI], [test "$enable_mpi" = yes])
 
 
 AC_ARG_ENABLE([win],
               [AS_HELP_STRING([--enable-win],
                               [Compile with mingw instead of gcc.])])
 AS_IF([test "x$enable_win" = "xyes"],[CC="i686-w64-mingw32-gcc"])
+AM_CONDITIONAL([WANT_WIN], [test "$enable_win" = yes])
 
 
 AC_ARG_ENABLE([beagle], [AS_HELP_STRING([--enable-beagle], [Compute likelihoods using BEAGLE library.])], [beagle=yes],[beagle=no])
@@ -112,6 +114,13 @@ if test "$phytime" = yes; then
    AC_DEFINE([PHYTIME],[1],[PHYTIME tag on])
 fi
 
+AC_ARG_ENABLE([phyml],[AS_HELP_STRING([--enable-phyml],[Compile PhyML])],[phyml=yes],[phyml=no])
+AM_CONDITIONAL([WANT_PHYML], [test "$phyml" = yes])
+if test "$phyml" = yes; then
+   AC_DEFINE([PHYML],[1],[PHYML tag on])
+fi
+
+
 AC_ARG_ENABLE([tiporder],[AS_HELP_STRING([--enable-tiporder],[Compile tiporder])],[tiporder=yes],[tiporder=no])
 AM_CONDITIONAL([WANT_TIPORDER], [test "$tiporder" = yes])
 if test "$tiporder" = yes; then
@@ -184,6 +193,7 @@ AM_CONDITIONAL([WANT_PHYREX], [test "$phyrex" = yes])
 if test "$phyrex" = yes; then
    AC_DEFINE([PHYREX],[1],[PHYREX tag on])
 fi
+
 dnl AS_IF([test "x$enable_phyrex" = "xyes"],[PKG_CHECK_MODULES([GTK], [gtk+-3.0])])
 dnl AS_IF([test "x$enable_phyrex" = "xyes"],[PKG_CHECK_MODULES([CAIRO], [cairo])])
 dnl AS_IF([test "x$enable_phyrex" = "xyes"],[CFLAGS="${CFLAGS} `pkg-config --cflags --libs gtk+-3.0` ${ARCH_flag}"])
@@ -191,6 +201,14 @@ dnl AS_IF([test "x$enable_phyrex" = "xyes"],[CFLAGS="${CFLAGS} `pkg-config --cfl
 
 dnl AM_PATH_GTK_3_0(,,AC_MSG_ERROR(windoe-default needs GTK+-3))
 
+AC_ARG_ENABLE([date],[AS_HELP_STRING([--enable-date],[Compile date])],[date=yes],[date=no])
+AM_CONDITIONAL([WANT_DATE], [test "$date" = yes])
+if test "$date" = yes; then
+   AC_DEFINE([DATE],[1],[DATE tag on])
+fi
+
+
+
 if test "$phytime" = no; then
 if test "$tiporder" = no; then
 if test "$part" = no; then
@@ -203,6 +221,7 @@ if test "$geo" = no; then
 if test "$evolve" = no; then
 if test "$checkpoint" = no; then
 if test "$phyrex" = no; then
+if test "$date" = no; then
    AC_DEFINE([PHYML],[1],[PHYML tag on])
 fi
 fi
@@ -216,6 +235,7 @@ fi
 fi
 fi
 fi
+fi
 
 AC_CONFIG_FILES([Makefile src/Makefile doc/Makefile])
 AC_OUTPUT
diff --git a/doc/fig/phyrexlog.pdf b/doc/fig/phyrexlog.pdf
new file mode 100644
index 0000000..c09b8d3
Binary files /dev/null and b/doc/fig/phyrexlog.pdf differ
diff --git a/doc/phyml-manual.pdf b/doc/phyml-manual.pdf
index 8fd0374..40ee3e6 100644
Binary files a/doc/phyml-manual.pdf and b/doc/phyml-manual.pdf differ
diff --git a/doc/phyml-manual.tex b/doc/phyml-manual.tex
index 3b42aee..cf687b8 100644
--- a/doc/phyml-manual.tex
+++ b/doc/phyml-manual.tex
@@ -26,6 +26,7 @@
   \psfrag{#2}[c][c][#1]{#3}
 }
 \newcommand{\x}[1]{\texttt{#1}}
+\newcommand{\sfv}{$\Lambda$V}
 
 % \setpapersize{A4}
 % \hypersetup{colorlinks=true,linkcolor=blue,urlcolor=red,linkbordercolor=000}
@@ -580,9 +581,6 @@ correspond to the frequencies of A, C, G and T respectively.
 \item \x{-c} (or \x{--nclasses}) \x{nb\_subst\_cat}\index{gamma distribution (discrete)!number of categories} \index{command-line options!\x{--nclasses}}\\
 \x{nb\_subst\_cat}: number of relative substitution rate categories. Default: \x{nb\_subst\_cat=4}. Must be a positive integer.
 
-\item \x{--freerates} (or \x{--free\_rates} or \x{--free\_rate} or \x{--freerate}) \index{FreeRate} \index{command-line options!\x{--freerates}}\\
-FreeRate model of substitution rate variation across sites.
-
 \item \x{-a} (or \x{--alpha}) \x{gamma} \index{gamma distribution (discrete)!shape parameter}\index{command-line options!\x{--alpha}} \\
 \x{gamma}: value of the gamma shape parameter. Can be a fixed positive value or e to get the maximum
 likelihood estimate. The value of this parameter is estimated in the maximum likelihood framework by default.
@@ -591,13 +589,29 @@ likelihood estimate. The value of this parameter is estimated in the maximum lik
 The middle of each substitution rate class in the discrete gamma distribution is taken as the
 median. The mean is used by default.
 
-\item \x{--free\_rates} \index{command-line options!\x{--free\_rates}}\\
+\item \x{--free\_rates} or \x{--freerates} \index{command-line options!\x{--free\_rates}}\\
 As an alternative to the discrete gamma model, it is possible to estimate the (relative) rate in
 each class of the (mixture) model and the corresponding frequencies directly from the data. This
 model, called the FreeRate model, has more parameters
 than the discrete gamma one but usually provides a significantly better fit to the data. See
 \cite{soubrier12} for more information about this model and an illustration of its use.
 
+\item \x{--il} \index{command-line options!\x{--il}}\\ \x{il} stands here for integrated (branch)
+  length. This model, described in \cite{guindon13} in the context of molecular dating, provides an
+  efficient way to implement the covarion model \index{covarion}. Under the integrated length (IL) model, the length
+  of each edge is described by a distribution of values, instead of a single value corresponding to
+  the expected number of substitutions per position along the sequence. Let $l_{a,s}$ and $l_{b,s}$
+  be the number of substitutions at site $s$ along edges $a$ and $b$, and $l_{a,t}$ and $l_{b,t}$,
+  the number of substitutions at site $t$. Standard models have $l_{a,s}=l_{a,t}$ and $l_{b,s}=l_{b,t}$,
+  or $l_{a,s}=\alpha l_{a,t}$ and $l_{b,s}=\alpha l_{b,t}$ if rates vary across sites. The IL model
+  has instead $l_{a,s}= \alpha l_{a,t}$ and $l_{b,s}= \beta l_{b,t}$ with $\alpha \neq \beta$,
+  i.e. substitution rates vary across sites and edges. The IL approach is somehow an analytical
+  approximation to the covarion model that, unlike the covarion model, does not incur any computational overhead compared to the
+  traditional models. A notable difference with the plain vanilla covarion model and the IL model however is that
+  substitution rates are not autocorrelated along the phylogeny under the IL model.
+
+
+
 \item \x{--codpos} \x{1,2 or 3} \index{command-line options!\x{--codpos}}\\
 When analysing an alignment of coding sequences, use this option to consider only the first, second
 or the third coding position for the estimation.
@@ -639,6 +653,12 @@ Print each phylogeny explored during the tree search process in file *\_phyml\_t
 option can be useful for monitoring the progress of the analysis for very large data sets and have
 an approximate idea of what the final phylogeny will look like.
 
+\item \x{--json\_trace}\index{command-line options!\x{--json\_trace}}\\
+Print each phylogeny explored during the tree search process in file *\_phyml\_json\_trace.txt in
+JSON format (see \url{http://www.json.org/}). This option can be useful for monitoring the progress of the analysis for very large data sets and have
+an approximate idea of what the final phylogeny will look like.
+
+
 \item \x{--run\_id ID\_string}\index{run ID} \index{command-line options!\x{--run\_id}}\\
 Append the string ID\_string at the end of each PhyML output file. This option may be useful when
 running simulations involving PhyML. It can also be used to `tag' multiple analysis of the same data
@@ -1114,7 +1134,7 @@ be considered  as conflicting since  branch lengths depend  on the proportion of
 changing the proportion  of invariants implies that branch lengths are  changing too. More formally,
 let $l$ denote the length of a branch,  i.e., the expected number of substitutions per site, and $p$
 be  the proportion  of invariants.  We have  $l =  (1-p)l'$, where  $l'$ is  the expected  number of
-substitutions per  \_variable\_ sites.  When  asked to optimize  $p$ but leave $l$  unchanged, PhyML
+substitutions {\em at  variable sites}.  When  asked to optimize  $p$ but leave $l$  unchanged, PhyML
 does the following:
 \begin{enumerate}
 \item Calculate $l' = l/(1-p)$ and leave $l'$ unchanged throughout the optimization.
@@ -1122,7 +1142,7 @@ does the following:
 \item Set $l^{*} = (1-p^{*})l'$ and print out the tree with $l^{*}$ (instead of $l$).
 \end{enumerate}
 
-PhyML therefore  assumes that the  users wants  to fix the  branch lengths measured  at \_variable\_
+PhyML therefore  assumes that the  users wants  to fix the  branch lengths measured  at {\em variable}
 sites only  (i.e., $l^{*}$ is  fixed). This is the  reason why the  branch lengths in the  input and
 output trees  do differ  despite the  use of the  the \x{-o  r} option. While  we believe  that this
 approach relies on a sound rationale, it  is not perfect. In particular, the original transformation
@@ -1590,8 +1610,11 @@ Options:
   \x{filename\_phyml\_tree} and \x{filename\_phyml\_stats}.
 \item \x{bootstrap="nreplicates"}. Run \x{nreplicates} replicates for the non-parametric bootstrap analysis.
 \item \x{run.id="idstring"}. PhyML will append the string \x{idstring} to each output file.
+\item \x{print.json.trace="yes|true|no|false"}. PhyML will print the estimated trees, the
+  corresponding loglikelihoods and various model parameters at multiple stages of the estimation process. This option is useful
+  for monitoring the progress of the analysis when processing large data sets.
 \item \x{print.trace="yes|true|no|false"}. PhyML will print the estimated trees (and the
-  corresponding loglikelihoods) at multiple stages of the estimation process. This option is useful
+  corresponding loglikelihoods) at multiple stages of the estimation process. This option is also useful
   for monitoring the progress of the analysis when processing large data sets.
 \item \x{branch.test="aBayes|aLRT|SH|no"}. Calculate fast branch support using the aBayes method
   \cite{anisimova11}, aLRT \cite{anisimova06} or SH \cite{shimodaira99} tests. These branch
@@ -1613,6 +1636,7 @@ PhyML in batch mode.
 Options:
 \begin{itemize}
 \item \x{init.tree="bionj"|"user"|"random"}.  Starting tree. Default is \x{bionj}.
+\item \x{n.rand.starts="X"}.  Number of random starting trees. Default is 5.
 \item \x{file.name="name\_of\_tree\_file"}. In case \x{init.tree="user"}, this
   attribute  is mandatory. \x{name\_of\_tree\_file} is a
   text file containing a tree in NEWICK format.
@@ -1778,6 +1802,8 @@ Options:
   but the corresponding partition elements have different mean rates of substitution.
 \item \x{tree.scale="val"}. \x{val} is the value of the (relative) substitution rate. By default,
   its value is set to 1.0.
+\item \x{print.site.lk="yes|true|no|false"}. The likelihood at each site (and other information)
+  will be written in a file named  \x{inputfilename\_phyml\_lk}.
 \end{itemize}
 
 Each \x{partitionelem} element should include exactly four \x{mixtureelem} elements, corresponding to
@@ -2448,7 +2474,7 @@ make;
 \end{verbatim} } This set of commands generates  a binary file called \x{phylogeo} which can be found
   in the `src/' directory.
 
-\subsubsection{Running PhyloGeo} PhyloGeo takes as input a rooted tree file in Newick format and a tree
+\subsubsection{Running PhyloGeo} PhyloGeo takes as input a rooted tree file in Newick format and a file
 with geographical locations for all the tips of the phylogeny. Here is an example of valid tree and
 the corresponding spatial locations just below:
 
@@ -2503,6 +2529,95 @@ parameters.
 Ranjard, L., Welch D., Paturel M. and Guindon S. ``Modelling competition  and  dispersal in a
 statistical phylogeographic framework''. 2014. Systematic Biology.
 
+
+
+\subsection{PhyREX}\index{PhyRex} PhyREX is a program that implements the spatial
+$\Lambda$-Fleming-Viot model
+\cite{etheridge2008,berestycki2009,barton2010,barton2010b,veber2012,barton2013} or \sfv\ for short. 
+According to this model, the spatial distribution of individuals in a population is uniform and does
+not change during the course of evolution, as opposed to other models such as the very popular
+isolation by distance model proposed by Wright and Mal\'ecot. The \sfv\ model  does not
+suffer from the ``pain in the torus'' \cite{felsenstein1975} and clumps of individuals with
+increasing densities do not arise. Also, estimates of migration parameters are not sensitive to
+variation in sampling intensities across regions, unlike ``mugration'' or ``discrete trait
+analysis'' models \cite{lemey2009}.
+
+PhyREX implements an original data augmentation technique embedded in a Bayesian sampler to
+estimate two important biological parameters: the neighorhood size ($\mathcal{N}$) and the dispersal
+intensity ($\sigma^2$). These two parameters are closely related to the effective size of the
+population of interest per unit area since $\mathcal{N}$ is defined as follows: $\mathcal{N} := 4\pi
+\rho_e \sigma^2$, where $\rho_e$ is the effective population density.
+
+\subsubsection{Installing PhyREX}
+
+Compiling PhyREX is straightforward on Unix-like  machines (i.e., linux and MacOS systems). PhyREX
+is not readily available for Windows machines but  compilation should be easy on this system too. In
+the `phyml' directory, where the `src/'  and `doc/' directories stand, enter the following commands:
+{\setlength{\baselineskip}{0.5\baselineskip}
+\begin{verbatim}
+./configure --enable-phyrex;
+make clean;
+make;
+\end{verbatim} } This set of commands generates  a binary file called \x{phyrex} which can be found
+  in the `src/' directory.
+
+\subsubsection{Running PhyREX}
+
+Example input files for PhyREX can be found in the \x{examples/phyrex\_input\_files/} directory.
+PhyRex takes as input a sequence alignment, in a PhyML-compatible format as well as a text file
+giving the spatial coordinates of each taxon in two dimension. A example of the coordinates file is given
+below:
+\begin{Verbatim}[frame=single, label=Valid PhyRex spatial location file, samepage=true, baselinestretch=0.5]
+# state.name lon lat
+|SouthWest| 0 0
+|NorthEast| 10 10 
+levosl 5.082206 4.133893 
+kmgcwv 5.914294 4.603446 
+uhfwja 4.990937 4.445124 
+ndmwkc 5.178017 4.442268 
+jpadex 3.747484 4.571090 
+lqcdcw 7.081925 5.133123 
+wnsbtg 4.164588 4.720346 
+ptwgnn 5.711159 4.462993 
+jhqdsm 3.539525 4.537706 
+vlnoes 4.613251 4.470530 
+pfrnpk 4.117791 4.489819 
+elwdvr 5.649958 4.824092 
+lptxiv 4.563302 4.005124 
+\end{Verbatim}
+The first row in this file gives the names of the columns. It starts with the `\#' character signaling a
+comment. The second and third rows define the limits of the population's habitat. At the
+moment, this habitat is assumed to be a rectangle. The position in space of that rectangle are
+determined by the coordinates of the bottom-left corner (\x{|SouthWest| 0 0}) and the top-right
+one (\x{|NorthEast| 10 10}). The `\x{|}' characters help  identify the terms in the list of coordinate
+corresponding indeed to these two particular points and should thus not be omitted. The remaining
+row give the coordinates of each taxon. Every taxon in the sequence file should also be listed in
+the coordinate file.
+
+PhyRex uses the same command-line arguments as that used with PhyML. The only exception being the
+mandatory argument corresponding to the coordinate file. A typical command-line will this look as
+follows: \x{./phyrex -i sequence\_file --coord\_file=./spatial\_location\_file -c 3 --freerates
+  --il}. With this particular set of options, the sequence alignment will be analysed under a
+FreeRate  model \cite{soubrier12} with three rate classes and a covarion-like model of rate variation
+across lineaged \cite{guindon13}. Please note that the command-line option \x{--coord\_file} is mandatory.
+
+PhyREX generates correlated samples from the posterior distribution of the \sfv\ model
+parameters. The estimated distributions and related summary statistics can be monitored during the
+analysis using the MCMC vizualization software Icylog. Figure \ref{fig:phyrextrace} shows the traces
+for two parameters after about an hour of calculation on the example data set (36 taxa, 50
+geographic locations).
+
+\begin{figure}
+\begin{center}
+\includegraphics[width=13.8cm]{./fig/phyrexlog}
+\end{center}
+\caption{{\bf Statistics file generated by PhyREX and loaded on Icylog
+    (\url{http://tgvaughan.github.io/icylog/icylog.html}).} The traces for the neighborhood size
+  (top) and
+the dispersal intensity (bottom) are shown here.} 
+\label{fig:phyrextrace}
+\end{figure}
+
 \section{Recommendations on program usage}\label{sec:progusage}
 
 \subsection{PhyML}
@@ -2668,8 +2783,8 @@ algorithms to search the space of tree topologies for this type of data.
 The development of PhyML since 2000 has been supported by the Centre National de la Recherche
 Scientifique (CNRS) and the Minist\`ere de l'\'Education Nationale.
 
-\bibliographystyle{/home/guindon/latex/biblio/nature/naturemag}
-\bibliography{/home/guindon/latex/biblio/ref}
+\bibliographystyle{./naturemag}
+\bibliography{./ref.bib}
 
 \printindex
 \end{document}
diff --git a/doc/ref.bib b/doc/ref.bib
index 3a5f008..94de7a7 100644
--- a/doc/ref.bib
+++ b/doc/ref.bib
@@ -1,3 +1,44 @@
+ at article{etheridge2008,
+  title={Drift, draft and structure: some mathematical models of evolution},
+  author={Etheridge, Alison M},
+  journal={Banach Center Publ},
+  volume={80},
+  pages={121--144},
+  year={2008}
+}
+
+ at inproceedings{berestycki2009,
+  title={Survival, extinction and ergodicity in a spatially continuous population model},
+  author={Berestycki, N and Etheridge, A and Hutzenthaler, M},
+  booktitle={Markov Proc. Rel. Fields},
+  year={2009}
+}
+ at article{barton2010,
+  title={A new model for evolution in a spatial continuum},
+  author={Barton, NH and Etheridge, AM and V{\'e}ber, A},
+  journal={Electronic Journal of Probability},
+  volume={15},
+  number={7},
+  year={2010}
+}
+
+ at article{barton2010b,
+  title={A new model for extinction and recolonization in two dimensions: quantifying phylogeography},
+  author={Barton, Nicholas H and Kelleher, Jerome and Etheridge, Alison M},
+  journal={Evolution},
+  volume={64},
+  number={9},
+  pages={2701--2715},
+  year={2010},
+  publisher={Wiley Online Library}
+}
+ at article{veber2012,
+author = {V{\'e}ber, A and Wakolbinger, A},
+title = {The spatial {L}ambda-{F}leming-{V}iot process: an event-based construction and a lookdown representation},
+year = {2014},
+journal = {Annales de l'Institut Henri Poincar\'e},
+pages={in press}
+}
 
 @article{tilman2011,
   title={Diversification, biotic interchange, and the universal trade-off hypothesis},
@@ -138,6 +179,17 @@ publisher={Wiley},
   year={1964}
 }
 
+ at article{lemey2009,
+  title={Bayesian phylogeography finds its roots},
+  author={Lemey, Philippe and Rambaut, Andrew and Drummond, Alexei J and Suchard, Marc A},
+  journal={PLoS Comput Biol},
+  volume={5},
+  number={9},
+  pages={e1000520},
+  year={2009},
+  publisher={Public Library of Science}
+}
+
 @article{gillespie2011,
   title={Long-distance dispersal: a framework for hypothesis testing},
   author={Gillespie, R.G. and Baldwin, B.G. and Waters, J.M. and Fraser, C.I. and Nikula, R. and Roderick, G.K.},
@@ -579,6 +631,18 @@ Pages = {249,265}
 	Volume = 2,
 	Year = 1987}
 
+ at article{barton2013,
+  title={Modelling evolution in a spatial continuum},
+  author={Barton, NH and Etheridge, AM and V{\'e}ber, A},
+  journal={Journal of Statistical Mechanics: Theory and Experiment},
+  volume={2013},
+  number={01},
+  pages={P01002},
+  year={2013},
+  publisher={IOP Publishing}
+}
+
+
 @inproceedings{barthelemy84,
 	Address = {La Grande-Motte},
 	Author = {J.-P. Barth{\'e}lemy and N.X. Luong},
@@ -3699,6 +3763,16 @@ Pages = {1307-1320},
 	Volume = 18,
 	Year = 2001}
 
+ at article{felsenstein1975,
+  title={A pain in the torus: some difficulties with models of isolation by distance},
+  author={Felsenstein, Joseph},
+  journal={American Naturalist},
+  pages={359--368},
+  year={1975},
+  publisher={JSTOR}
+}
+
+
 @article{ota00b,
 	Author = {R. Ota and P. Waddell and M. Hasegawa and H. Shimodaira and H. Kishino},
 	Journal = {Molecular Biology and Evolution},
diff --git a/examples/phyrex_input_files/h1n1.nxs b/examples/phyrex_input_files/h1n1.nxs
new file mode 100644
index 0000000..c882706
--- /dev/null
+++ b/examples/phyrex_input_files/h1n1.nxs
@@ -0,0 +1,613 @@
+#NEXUS
+
+
+BEGIN DATA;
+ DIMENSIONS NTAX=36 NCHAR=1434;
+ FORMAT DATATYPE=DNA INTERLEAVE;
+MATRIX
+CY130177|South_Carolina|12_13|H1N1 ---------ATGAATCCAAA CCAAAAGATAATAACCATTG GTTCGGTCTGTATGACAATT GGAATGGCTAACTTAATATT ACAAATTGGAAACATAATCT
+KF647978|Idaho|12_13|H1N1 ---------ATGAATCCAAA CCAAAAGATAATAACCATTG GTTCGGTCTGTATGACAATT GGAATGGCTAACTTAATATT ACAAATTGGAAACATAATCT
+KF648268|New_Mexico|12_13|H1N1 ---------ATGAATCCAAA CCAAAAGATAATAACCATTG GTTCGGTCTGTATGACAATT GGAATGGCTAACTTAATATT ACAAATTGGAAACATAATCT
+KF648064|North_Carolina|12_13|H1N1 ---------ATGAATCCAAA CCAAAAGATAATAACCATTG GTTCGGTCTGTATGACAATT GGAATGGCTAACTTAATATT ACAAATTGGAAACATAATCT
+KF647995|New_Hampshire|12_13|H1N1 ---------ATGAATCCAAA CCAAAAGATAATAACCATTG GTTCGGTCTGTATGACAATT GGAATGGCTAACTTAATATT ACAAATTGGAAACATAATCT
+KF648000|Colorado|12_13|H1N1 ---------ATGAATCCAAA CCAAAAGATAATAACCATTG GTTCGGTCTGTATGACAATT GGAATGGCTAACTTAATATT ACAAATTGGAAACATAATCT
+KF648133|Florida|12_13|H1N1 ---------ATGAATCCAAA CCAAAAGATAATAACCATTG GTTCGGTCTGTATGACAATT GGAATGGCTAACTTAATATT ACAAATTGGAAACATAATCT
+KF648145|Georgia|12_13|H1N1 ---------ATGAATCCAAA CCAAAAGATAATAACCATTG GTTCGGTCTGTATGACAATT GGAATGGCTAACTTAATATT ACAAATTGGAAACATAATCT
+KF648155|Vermont|12_13|H1N1 ---------ATGAATCCAAA CCAAAAGATAATAACCATTG GTTCGGTCTGTATGACAATT GGAATGGCTAACTTAATATT ACAAATTGGAAACATAACCT
+KF648158|Utah|12_13|H1N1 ---------ATGAATCCAAA CCAAAAGATAATAACCATTG GTTCGGTCTGTATGACAATT GGAATGGCTAACTTAATATT ACAAATTGGAAACATAATCT
+KF648159|Louisiana|12_13|H1N1 ---------ATGAATCCAAA CCAAAAGATAATAACCATTG GTTCGGTCTGTATGACAATT GGAATGGCTAACTTAATATT ACAAATTGGAAACATAATCT
+KF648008|Rhode_Island|12_13|H1N1 ---------ATGAATCCAAA CCAAAAGATAATAACCATTG GTTCGGTCTGTATGACAATT GGAATGGCTAACTTAATATT ACAAATTGGAAACATAATCT
+KF648011|New_York|12_13|H1N1 ---------ATGAATCCAAA CCGAAAGATAATAACCATTG GTTCGGTCTGCATGACAATT GGAATGGCTAACTTAATATT ACAAATTGGAAACATAATCT
+KF647921|Maryland|12_13|H1N1 ---------ATGAATCCAAA CCAAAAGATAATAACCATTG GTTCGGTCTGTATGACAATT GGAATGGCTAACTTAATATT ACAAATTGGAAACATAATCT
+KF647926|Missouri|12_13|H1N1 ---------ATGAATCCAAA CCAAAAGATAATAACCATTG GTTCGGTCTGTATGACAATT GGAATGGCTAACTTAATATT ACAAATTGGAAACATAATCT
+KF647928|Texas|12_13|H1N1 ---------ATGAATCCAAA CCAAAAGATAATAACCATTG GTTCGGTCTGTATGACAATT GGAATGGCTAACTTAATATT ACAAATTGGAAACATAATCT
+KF647936|Wyoming|12_13|H1N1 ---------ATGAATCCAAA CCAAAAGATAATAACCATTG GTTCGGTCTGTATGACAATT GGAATGGCCAACTTAATATT ACAAATTGGAAACATAATCT
+KF648197|Indiana|12_13|H1N1 ---------ATGAATCCAAA CCAAAAGATAATAACCATTG GTTCGGTCTGTATGACAATT GGAATGGCTAACTTAATATT ACAAATTGGAAATATAACCT
+KF648228|Mississippi|12_13|H1N1 ---------ATGAATCCAAA CCAAAAGATAATAACCATTG GTTCGGTCTGTATGACAATT GGAATGGCTAACTTAATATT ACAAATTGGAAACATAATCT
+KF648239|Tennessee|12_13|H1N1 ---------ATGAATCCAAA CCAAAAGATAATAACCATTG GTTCGGTCTGTATGACAATT GGAATGGCTAACTTAATATT ACAAATTGGAAACATAATCT
+KF648034|Arizona|12_13|H1N1 ---------ATGAATCCAAA CCAAAAGATAATAACCATTG GTTCGGTCTGTATGACAATT GGAATGGCTAACTTAATATT ACAAATTGGAAACATAATCT
+KF648037|Kentucky|12_13|H1N1 ---------ATGAATCCAAA CCAAAAGATAATAACCATTG GTTCGGTCTGTATGACAATT GGAATGGCTAACTTAATATT ACAAATTGGAAACATAATCT
+KF648038|Kansas|12_13|H1N1 ---------ATGAATCCAAA CCAAAAGATAATAACCATTG GTTCGGTCTGTATGACAATT GGAATGGCTAACTTAATATT ACAAATTGGAAACATAATCT
+KF647919|Alabama|12_13|H1N1 ---------ATGAATCCAAA CCAAAAGATAATAACCATTG GTTCGGTCTGTATGACAATT GGAATGGCTAACTTAATATT ACAAATTGGAAACATAATCT
+KF647931|Wisconsin|12_13|H1N1 ---------ATGAATCCAAA CCAAAAGATAATAACCATTG GTTCGGTCTGTATGACAATT GGAATGGCTAACTTAATATT ACAAATTGGAAACATAATCT
+KF647932|Pennsylvania|12_13|H1N1 ---------ATGAATCCAAA CCAAAAGATAATAACCATTG GTTCGGTCTGTATGACAATT GGAATGGCTAACTTAATATT ACAAATTGGAAACATAATCT
+KF647958|Nebraska|12_13|H1N1 ---------ATGAATCCAAA CCAAAAGATAATAACCATTG GTTCGGTCTGTATGACAATT GGAATGGCTAACTTAATATT ACAAATTGGAAACATAATCT
+KF647971|Oklahoma|12_13|H1N1 ---------ATGAATCCAAA CCAAAAGATAATAACCATTG GTTCGGTCTGTATGACAATT GGAATGGCTAACTTAATATT ACAAATTGGAAACATAATCT
+KF647902|Iowa|12_13|H1N1 ---------ATGAATCCAAA CCAAAAGATAATAACCATTG GTTCGGTCTGTATGACAATT GGAATGGCTAACTTAATATT ACAAATTGGAAACATAATCT
+KF648002|Minnesota|12_13|H1N1 ---------ATGAATCCAAA CCAAAAGATAATAACCATTG GTTCGGTCTGTATGACAATT GGAATGGCTAACTTAATATT ACAAATTGGAAACATAATCT
+KF648040|New_Jersey|12_13|H1N1 ---------ATGAATCCAAA CCAAAAGATAATAACCATTG GTTCGGTCTGTATGACAATT GGAATGGCTAACTTAATATT ACAAATTGGAAACATAATCT
+KF648101|Ohio|12_13|H1N1 ---------ATGAATCCAAA CCAAAAGATAATAACCATTG GTTCGGTCTGTATGACAATT GGAATGGCTAACTTAATATT ACAAATTGGAAACATAATCT
+KF648260|Washington|12_13|H1N1 ---------ATGAATCCAAA CCAAAAGATAATAACCATTG GTTCGGTCTGTATGACAATT GGAATGGCTAACTTAATATT ACAAATTGGAAACATAATCT
+CY170697|California|12_13|H1N1 GAGTTTAAAATGAATCCAAA CCAAAAGATAATAACCATTG GTTCGGTCTGTATGACAATT GGAATGGCTAACTTAATATT ACAAATTGGAAACATAATCT
+CY168881|Massachusetts|12_13|H1N1 GAGTTTAAAATGAATCCAAA CCAAAAGATAATAACCATTG GTTCGGTCTGTATGACAATT GGAATGGCTAACTTAATATT ACAAATTGGAAACATAATCT
+CY171161|Illinois|12_13|H1N1 GAGTTTAAAATGAATCCAAA CCAAAAGATAATAACCATTG GTTCGATCTGTATGACAATT GGAATGGCTAACTTAATATT ACAAATTGGAAACATAATCT
+
+CY130177|South_Carolina|12_13|H1N1 CAATATGGATTAGCCACTCA ATTCAACTTAGGAATCAAAA TCAGATTGAAACATGCAATC AAAGCGTCATTACTTATGAA AACAACACTTGGGTAAATCA
+KF647978|Idaho|12_13|H1N1 CAATATGGATTAGCCACTCA ATTCAAGTTGGGAATCAAAG TCAGATTGAAACATGCAATC AAAGCGTCATTACTTATGAA AACAACACTTGGGTAAATCA
+KF648268|New_Mexico|12_13|H1N1 CAATATGGATTAGCCACTCA ATTCAACTTGGGAATCAAAG TCAGATTGAAACATGCAATC AAAGCGTCATTACTTATGAA AACAACACTTGGGTAAATCA
+KF648064|North_Carolina|12_13|H1N1 CAATATGGATTAGCCACTCA ATTCAACTTGGGAATCAAAG TCAGATTGAAACATGCAATC AAAGCGTCATTACTTATGAA AACAACACTTGGGTAAATCA
+KF647995|New_Hampshire|12_13|H1N1 CAATATGGATTAGCCACTCA ATTCAACTTGGGAATCAAAG TCAGATTGAAACATGCAATC AAAGCGTCATTACTTATGAA AACAACACTTGGGTAAATCA
+KF648000|Colorado|12_13|H1N1 CAATATGGATTAGCCACTCA ATTCAACTTGGAAATCAAAG TCAGATTGAAGCATGCAATC AAAGCGTCATTACTTACGAA AACAACACTTGGGTAAATCA
+KF648133|Florida|12_13|H1N1 CAATATGGATTAGCCACTCA ATTCAACTTGGGAATCAAAG TCAGATTGAAACATGCAATC AAAGCGTCATTACTTATGAA AACAACACTTGGGTAAATCA
+KF648145|Georgia|12_13|H1N1 CAATATGGGTTAGCCACTCA ATTCAACTTGGGAATCAAAG TCAGATTGAAGCATGCAATC AAAGCGTCATTACTTATGAA AACAACACTTGGGTAAATCA
+KF648155|Vermont|12_13|H1N1 CAATATGGATTAGCCACTCA ATTCAACTTGGGAATCAAAG TCAGATTGAAGCATGCAATC AAAGCGTCATTACTTATGAA AACAACACTTGGGTAAATCA
+KF648158|Utah|12_13|H1N1 CAATATGGATTAGCCACTCA ATTCAACTTGGGAATCAAAG TCAGATTGAAACATGCAATC AAAGCGTCATTACTTATGAA AACAACACTTGGGTAAATCA
+KF648159|Louisiana|12_13|H1N1 CAATATGGGTTAGCCACTCA ATTCAACTTGGGAATCAAAG TCAGATTGAAACATGCAATC AAAGCGTCATTACTTATGAA AACAACACTTGGGTAAATCA
+KF648008|Rhode_Island|12_13|H1N1 CAATATGGATTAGCCACTCA ATTCAAGTTGGGAATCAAAG TCAGATTGAAACATGCAATC AAAGCGTCATTACTTATGAA AACAACACTTGGGTAAATCA
+KF648011|New_York|12_13|H1N1 CAATATGGATTAGCCACTCA ATTCAAGTTGGGAATCAAAG TCAGATTGAAACATGCAATC AAAGCGTCATTACTTATGAA AACAACACTTGGGTAAATCA
+KF647921|Maryland|12_13|H1N1 CAATATGGATTAGCCACTCA ATTCAACTTGGGAATCAAAG TCAGATTGAAACATGCAATC AAAGCGTCATTACTTATGAA AACAACACTTGGGTAAATCA
+KF647926|Missouri|12_13|H1N1 CAATATGGATTAGCCACTCA ATTCAACTTGGGAATCAAAG TCAGATTGAAACATGCAATC AAAGCGTCATTACTTATGAA AACAACACTTGGGTAAATCA
+KF647928|Texas|12_13|H1N1 CAATATGGATTAGCCACTCA ATTCAACTTGGGAATCAAAA TCAGATTGAAACATGCAATC AAAGCGTCATTACTTATGAA AACAACACTTGGGTAAATCA
+KF647936|Wyoming|12_13|H1N1 CAATATGGATTAGCCACTCA ATTCAACTTATGAATCAAAG TCAGATTGAAACATGCAATC AAAGCGTCATTACTTATGAA AACAACACTTGGGTAAATCA
+KF648197|Indiana|12_13|H1N1 CAATATGGATTAGCCACTCA ATTCAACTTGGGAATCAAAG TCAGATTGAAGCATGCAATC AAAGCGTCATTACTTATGAA AACAACACTTGGGTAAATCA
+KF648228|Mississippi|12_13|H1N1 CAATATGGATTAGCCACTCA ATTCAACTTGGGAATCAAAG TCAGATTGAAACATGCAATC AAAGCGTCATTACTTATGAA AACAACACTTGGGTAAATCA
+KF648239|Tennessee|12_13|H1N1 CAATATGGATTAGCCACTCA ATTCAACTTGGGAATCAAAG TCAGATTGAAACATGCAATC AAAGCGTCATTACTTATGAA AACAACACTTGGGTAAATCA
+KF648034|Arizona|12_13|H1N1 CAATATGGATTAGCCACTCA ATTCAACTTGGGAATCAAAG TCAGATTGAAACATGCAATC AAAGCGTCATTACTTATGAA AACAACACTTGGGTAAATCA
+KF648037|Kentucky|12_13|H1N1 CAATATGGATTAGCCACTCA ATTCAACTTGGGAATCAAAG TCAGATTGAAGCATGCAATC AAAGCGTCATTACTTATGAA AACAACACTTGGGTAAATCA
+KF648038|Kansas|12_13|H1N1 CAATATGGATTAGCCACTCA ATTCAACTTGGGAATCAAAG TCAGATTGAAGCATGCAATC AAAGCGTCATTACTTATGAA AACAACACTTGGGTAAATCA
+KF647919|Alabama|12_13|H1N1 CAATATGGATTAGCCACTCA ATTCAACTTGGGAATCAAAG TCAGATTGAAACATGCAATC AAAGCGTCATTACTTATGAA AACAACACTTGGGTAAATCA
+KF647931|Wisconsin|12_13|H1N1 CAATATGGATTAGCCACTCA ATTCAAGTTGGGAATCAAAG TCAGATTGAAACATGCAATC AAAGCGTCATTACTTATGAA AACAACACTTGGGTAAATCA
+KF647932|Pennsylvania|12_13|H1N1 CAATATGGATTAGCCACTCA ATTCAACTTGGGAATCAAAG TCAGATTGAAGCATGCAATC AAAGCGTCATTACTTATGAA AACAACACTTGGGTAAATCA
+KF647958|Nebraska|12_13|H1N1 CAATATGGATTAGCCACTCA ATTCAACTTGGGAATCAAAG TCAGATTGAAGCATGCAATC AAAGCGTCATTACTTATGAA AACAACACTTGGGTAAATCA
+KF647971|Oklahoma|12_13|H1N1 CAATATGGATTAGCCACTCA ATTCAAGTTGGGAATCAAAG TCAGATTGAAACATGCAATC AAAGCGTCATTACTTATGAA AACAACACTTGGGTAAATCA
+KF647902|Iowa|12_13|H1N1 CAATATGGATTAGCCACTCA ATTCAACTTGGGAATCAAAG TCAGATTGAAACATGCAATC AAAGCGTCATTACTTATGAA AACAACACTTGGGTAAATCA
+KF648002|Minnesota|12_13|H1N1 CAATATGGATTAGCCACTCA ATTCAACTTGGGAATCAAAG TCAGATTGAAACATGCAATC AAAGCGTCATTACTTATGAA AACAACACTTGGGTAAATCA
+KF648040|New_Jersey|12_13|H1N1 CAATATGGGTTAGCCACTCA ATTCAACTTGGGAATCAAAG TCAGATTGAAACATGCAATC AAAACGTCATTACTTATGAA AACAACACTTGGGTAAATCA
+KF648101|Ohio|12_13|H1N1 CAATATGGATTAGCCACTCA ATTCAAGTTGGGAATCAAAG TCAGATTGAAACATGCAATC AAAGCGTCATTACTTATGAA AACAACACTTGGGTAAATCA
+KF648260|Washington|12_13|H1N1 CAATATGGATTAGCCACTCA ATTCAACTTGGGAATCAAAG TCAGATTGAAACATGCAATC AAAGCGTCATTACTTATGAA AACAACACTTGGGTAAATCA
+CY170697|California|12_13|H1N1 CAATATGGATTAGCCACTCA ATTCAAGTTGGGAATCAAAG TCAGATTGAAACATGCAATC AAAGCGTCATTACTTATGAA AACAACACTTGGGTAAATCA
+CY168881|Massachusetts|12_13|H1N1 CAATATGGATTAGCCACTCA ATTCAAGTTGGGAATCAAAG TCAGATTGAAACATGCAATC AAAGCGTCATTACTTATGAA AACAACACTTGGGTAAATCA
+CY171161|Illinois|12_13|H1N1 CAATATGGATTAGCCACTCA ATTCAACTTGGGAATCAAAG TCAGATTGAAACATGCAATC AAAGCGTCATTACTTATGAA AACAACACTTGGGTAAATCA
+
+CY130177|South_Carolina|12_13|H1N1 GACATATGTTAACATCAGCA ACACCAACTTTGCTGCTGGA CAGTCAGTGGTTTCCGTGAA ATTAGCGGGCAATTCCTCTC TCTGCCCTGTTAGTGGATGG
+KF647978|Idaho|12_13|H1N1 GACATATGTTAACATCAGCA ATACCAACTTTGCTGTTGGG CAGTCAGTGGTTTCCGTGAA ATTAGCGGGCAATTCCTCTC TCTGCCCTGTTAGTGGATGG
+KF648268|New_Mexico|12_13|H1N1 GACATATGTTAACATCAGCA ACACCAACTTTGCTGCTGGA CAGTCAGTGGTTTCCGTGAA ATTAGCGGGCAATTCCTCTC TCTGCCCTGTTAGTGGATGG
+KF648064|North_Carolina|12_13|H1N1 GACATATGTTAACATCAGCA ACACCAACTTTGCTGCTGGA CAGTCAGTGGTTTCCGTGAA ATTAGCGGGCAATTCCTCTC TCTGCCCTGTTAGTGGATGG
+KF647995|New_Hampshire|12_13|H1N1 GACATATGTTAACATCAGCA ACACCAACTTTGCTGCTGGA CAGTCAGTGGTTTCCGTGAA ATTAGCGGGCAATTCCTCTC TCTGCCCTGTTAGTGGATGG
+KF648000|Colorado|12_13|H1N1 GACATATGTTAACATCAGCA ACACCAACTTTGCTGCTGGA CAGTCAGTGGTTTCCGTGAA ATTAGCGGGCAATTCCTCTC TCTGCCCTGTTAGTGGATGG
+KF648133|Florida|12_13|H1N1 GACATATGTTAACATCAGCA ACACCAACTTTGCTGCTGGA CAGTCAGTGGTTTCCGTGAA ATTAGCGGGCAATTCCTCTC TCTGCCCTGTTAGTGGATGG
+KF648145|Georgia|12_13|H1N1 GACATATGTTAACATCAGCA ACACCAACTTTGCTGCTGGA CAGTCAGTGGTTTCCGTGAA ATTAGCGGGCAATTCCTCTC TCTGCCCTGTTAGTGGATGG
+KF648155|Vermont|12_13|H1N1 GACATATGTTAACATCAGCA ACACCAACTTTGCTGCTGGA CAGTCAGTGGTTTCCGTGAA ATTAGCGGGCAATTCCTCTC TCTGCCCTGTTAGTGGATGG
+KF648158|Utah|12_13|H1N1 GACATATGTTAACATCAGCA ACACCAACTTTGCTGCTGGA CAGTCAGTGGTTTCCGTGAA ATTAGCGGGCAATTCCTCTC TCTGCCCTGTTAGTGGATGG
+KF648159|Louisiana|12_13|H1N1 GACATATGTTAACATCAGCA ACACCAACTTTGCTGCTGGA CAGTCAGTGGTTTCCGTGAA ATTAGCGGGCAATTCCTCTC TCTGCCCTGTTAGTGGATGG
+KF648008|Rhode_Island|12_13|H1N1 GACATATGTTAACATCAGCA ACACCAACTTTGCTGCTGGG CAGTCAGTGGTTTCCGTGAA ATTAGCGGGCAATTCCTCTC TCTGCCCTGTTAGTGGATGG
+KF648011|New_York|12_13|H1N1 GACATATGTTAACATCAGCA ACACCAACTTTGCTGCTGGG CAGTCAGTGGTTTCCGTGAA ATTAGCGGGCAATTCCTCTC TCTGCCCTGTTAGTGGATGG
+KF647921|Maryland|12_13|H1N1 GACATATGTTAACATCAGTA ACACCAACTTTGCTGCTGGA CAGTCAGTGGTTTCCGTGAA ATTAGCGGGCAATTCCTCTC TCTGCCCTGTTAGTGGATGG
+KF647926|Missouri|12_13|H1N1 GACATATGTTAACATCAGCA ACACCAATTTTGCTGCTGGA CAGTCAGTGGTTTCCGTGAA ATTAGCGGGCAATTCCTCTC TCTGCCCTGTTAGTGGATGG
+KF647928|Texas|12_13|H1N1 GACATATGTTAACATCAGCA ACACCAACTTTGCTGCTGGA CAGTCAGTGGTTTCCGTGAA ATTAGCGGGCAATTCCTCTC TCTGCCCTGTTAGTGGATGG
+KF647936|Wyoming|12_13|H1N1 GACATATGTTAACATCAGCA ACACCAACTTTGCTGCTGGA CAGTCAGTGGTTTCCGTGAA ATTAGCGGGCAATTCCTCTC TCTGCCCTGTTAGTGGATGG
+KF648197|Indiana|12_13|H1N1 GACATATGTTAACATCAGCA ACACCAACTTTGCTGCTGGA CAGTCAGTGGTTTCCGTGAA ATTAGCGGGCAATTCCTCTC TCTGCCCTGTTAGTGGATGG
+KF648228|Mississippi|12_13|H1N1 GACATATGTTAACATCAGCA ACACCAACTTTGCTGCTGGA CAGTCAGTGGTTTCCGTGAA ATTAGCGGGCAATTCCTCTC TCTGCCCTGTTAGTGGATGG
+KF648239|Tennessee|12_13|H1N1 GACATATGTTAACATCAGCA ACACCAACTTTGCTGCTGGG CAGTCAGTGGTTTCCGTGAA ATTAGCGGGCAATTCCTCTC TCTGCCCTGTTAGTGGATGG
+KF648034|Arizona|12_13|H1N1 GACATATGTTAACATCAGCA ACACCAACTTTGCTGCTGGA CAGTCAGTGGTTTCCGTGAA ATTAGCGGGCAATTCCTCTC TCTGCCCTGTTAGTGGATGG
+KF648037|Kentucky|12_13|H1N1 GACATATGTTAACATCAGCA ACACCAACTTTGCTGCTGGA CAGTCAGTGGTTTCCGTGAA ATTAGCGGGCAATTCCTCTC TCTGCCCTGTTAGTGGATGG
+KF648038|Kansas|12_13|H1N1 GACATATGTTAACATCAGCA ACACCAACTTTGCTGCTGGA CAGTCAGTGGTTTCCGTGAA ATTAGCGGGCAATTCCTCTC TCTGCCCTGTTAGTGGATGG
+KF647919|Alabama|12_13|H1N1 GACATATGTTAACATCAGCA ACACCAACTTTGCTGCTGGA CAGTCAGTGGTTTCCGTGAA ATTAGCGGGCAATTCCTCTC TCTGCCCTGTTAGTGGATGG
+KF647931|Wisconsin|12_13|H1N1 GACATATGTTAACATCAGCA ACACCAACTTTGCTGCTGGG CAGTCAGTGGTTTCCGTGAA ATTAGCGGGCAATTCCTCTC TCTGCCCTGTTAGTGGATGG
+KF647932|Pennsylvania|12_13|H1N1 GACATATGTTAACATCAGCA ACACCAACTTTGCTGCTGGA CAGTCAGTGGTTTCCGTGAA ATTAGCGGGCAATTCCTCTC TCTGCCCTGTTAGTGGATGG
+KF647958|Nebraska|12_13|H1N1 GACATATGTTAACATCAGCA ACACCAACTTTGCTGCTGGA CAGTCAGTGGTTTCCGTGAA ATTAGCGGGCAATTCCTCTC TCTGCCCTGTTAGTGGATGG
+KF647971|Oklahoma|12_13|H1N1 GACATATGTTAACATCAGCA ACACCAACTTTGCTGCTGGG CAGCCAGTGGTTTCCGTGAA ATTAGCGGGCAATTCCTCTC TCTGCCCTGTTAGTGGATGG
+KF647902|Iowa|12_13|H1N1 GACATATGTTAACATCAGCA ACACCAACTTTGCTGCTGGA CAGTCAGTGGTTTCCGTGAA ATTAGCGGGCAATTCCTCTC TCTGCCCTGTTAGTGGATGG
+KF648002|Minnesota|12_13|H1N1 GACATATGTTAACATCAGCA ACACCAACTTTGCTGCTGGA CAGTCAGTGGTTTCCGTGAA ATTAGCGGGCAATTCCTCTC TCTGCCCTGTTAGTGGATGG
+KF648040|New_Jersey|12_13|H1N1 GACATATGTTAACATCAGCA ACACCAACTTTGCTGCTGGA CAGTCAGTGGTTTCCGTGAA ATTAGTGGGCAATTCCTCTC TCTGCCCTGTTAGTGGATGG
+KF648101|Ohio|12_13|H1N1 GACATATGTTAACATCAGCA ACACCAACTTTGCTGCTGGG CAGCCAGTGGTTTCCGTGAA ATTAGCGGGCAATTCCTCTC TCTGCCCTGTTAGTGGATGG
+KF648260|Washington|12_13|H1N1 GACATATGTTAACATCAGCA ACACCAACTTTGCTGCTGGA CAGTCAGTGGTTTCCGTGAA ATTAGCGGGCAATTCCTCTC TCTGCCCTGTTAGTGGATGG
+CY170697|California|12_13|H1N1 GACATATGTTAACATCAGCA ACACCAACTTTGCTGCTGGG CAGCCAGTGGTTTCCGTGAA ATTAGCGGGCAATTCCTCTC TCTGCCCTGTTAGTGGATGG
+CY168881|Massachusetts|12_13|H1N1 GACATATGTTAACATCAGCA ACACCAACTTTGCTGCTGGG CAGTCAGTGGTTTCCGTGAA ATTAGCGGGCAATTCCTCTC TCTGCCCTGTTAGTGGATGG
+CY171161|Illinois|12_13|H1N1 GACATATGTTAACATCAGCA ACACCAACTTTGCAGCTGGA CAGTCAGTGGTTTCTGTGAA ATTAGCGGGCAATTCCTCTC TCTGCCCTGTTAGTGGGTGG
+
+CY130177|South_Carolina|12_13|H1N1 GCTATATACAGTAAAGACAA CAGTATAAGAATCGGTTCCA AGGGGGATGTGTTTGTCATA AGGGAACCATTCATATCATG CTCCCCCTTGGAATGCAGAA
+KF647978|Idaho|12_13|H1N1 GCTATATACAGTAAAGACAA CAGTGTAAGAATCGGTTCCA AGGGGGATGTGTTTGTCATA AGGGAACCATTCATATCATG CTCCCCCTTGGAATGCAGAA
+KF648268|New_Mexico|12_13|H1N1 GCTATATACAGTAAAGACAA CAGTGTAAGAATCGGTTCCA AGGGGGATGTGTTTGTCATA AGGGAACCATTCATATCATG CTCCCCCTTGGAATGCAGAA
+KF648064|North_Carolina|12_13|H1N1 GCTATATACAGTAAAGACAA CAGTGTAAGAATCGGTTCCA AGGGGGATGTGTTTGTCATA AGGGAACCATTCATATCATG CTCCCCCTTGGAATGCAGAA
+KF647995|New_Hampshire|12_13|H1N1 GCTATATACAGTAAAGACAA CAGTGTAAGAATCGGTTCCA AGGGGGATGTGTTTGTCATA AGGGAACCATTCATATCATG CTCCCCCTTGGAATGCAGAA
+KF648000|Colorado|12_13|H1N1 GCTATATACAGCAAAGACAA CAGTGTAAGAATCGGTTCCA AGGGGGATGTGTTTGTCATA AGGGAACCATTCATATCATG CTCCCCCTTGGAATGCAGAA
+KF648133|Florida|12_13|H1N1 GCTATATACAGTAAAGACAA CAGTGTAAGAATCGGTTCCA AGGGGGATGTGTTTGTCATA AGGGAACCATTCATATCATG CTCCCCCTTGGAATGCAGAA
+KF648145|Georgia|12_13|H1N1 GCTATATACAGTAAAGACAA CAGTGTAAGAATCGGTTCCA AGGGGGATGTGTTTGTCATA AGGGAACCATTCATATCATG CTCCCCCTTGGAATGCAGAA
+KF648155|Vermont|12_13|H1N1 GCTATATACAGTAAAGACAA CAGTGTAAGAATCGGTTCCA AGGGGGATGTGTTTGTCATA AGGGAACCATTCATATCATG CTCCCCCTTGGAATGCAGAA
+KF648158|Utah|12_13|H1N1 GCTATATACAGTAAAGACAA CAGTGTAAGAATCGGTTCCA AGGGGGATGTGTTTGTCATA AGGGAACCATTCATATCATG CTCCCCCTTGGAATGCAGAA
+KF648159|Louisiana|12_13|H1N1 GCTATATACAGTAAAGACAA CAGTGTAAGAATCGGTTCCA AGGGGGATGTGTTTGTCATA AGGGAACCATTCATATCATG CTCCCCCTTGGAATGCAGAA
+KF648008|Rhode_Island|12_13|H1N1 GCTATATACAGTAAAGACAA CAGTGTAAGAATCGGTTCCA AGGGGGATGTGTTTGTCATA AGGGAACCATTCATATCATG CTCCCCCTTGGAATGCAGAA
+KF648011|New_York|12_13|H1N1 GCTATATACAGTAAAGACAA CAGTGTAAGAATCGGTTCCA AGGGGGATGTGTTTGTCATA AGGGAACCATTCATATCATG CTCCCCCTTGGAATGCAGAA
+KF647921|Maryland|12_13|H1N1 GCTATATACAGTAAAGACAA CAGTGTAAGAATCGGTTCCA AGGGGGATGTGTTTGTCATA AGGGAACCATTCATATCATG CTCCCCCTTGGAATGCAGAA
+KF647926|Missouri|12_13|H1N1 GCTATATACAGTAAAGACAA CAGTGTAAGAATCGGTTCCA AGGGGGATGTGTTTGTCATA AGGGAACCATTCATATCATG CTCCCCCTTGGAATGCAGAA
+KF647928|Texas|12_13|H1N1 GCTATATACAGTAAAGACAA CAGTATAAGAATCGGTTCCA AGGGGGATGTGTTTGTCATA AGGGAACCATTCATATCATG CTCCCCCTTGGAATGCAGAA
+KF647936|Wyoming|12_13|H1N1 GCTATATACAGTAAAGACAA CAGTATAAGAATCGGTTCCA AGGGGGATGTGTTTGTCATA AGGGAACCATTCATATCATG CTCCCCCTTGGAATGCAGAA
+KF648197|Indiana|12_13|H1N1 GCTATATACAGTAAAGACAA CAGTGTAAGAATCGGTTCCA AGGGGGATGTGTTTGTCATA AGGGAACCATTCATATCATG CTCCCCCTTGGAATGCAGAA
+KF648228|Mississippi|12_13|H1N1 GCTATATACAGTAAAGACAA CAGTGTAAGAATCGGTTCCA AGGGGGATGTGTTTGTCATA AGGGAACCATTCATATCATG CTCCCCCTTGGAATGCAGAA
+KF648239|Tennessee|12_13|H1N1 GCTATATACAGTAAAGACAA CAGTGTAAGAATCGGTTCCA AGGGGGATGTGTTTGTCATA AGGGAACCATTCATATCATG CTCCCCCTTGGAATGCAGAA
+KF648034|Arizona|12_13|H1N1 GCTATATACAGTAAAGACAA CAGTGTAAGAATCGGTTCCA AGGGGGATGTGTTTGTCATA AGGGAACCATTCATATCATG CTCCCCCTTGGAATGCAGAA
+KF648037|Kentucky|12_13|H1N1 GCTATATACAGTAAAGACAA CAGTGTAAGAATCGGTTCCA AGGGGGATGTGTTTGTCATA AGGGAACCATTCATATCATG CTCCCCCTTGGAATGCAGAA
+KF648038|Kansas|12_13|H1N1 GCTATATACAGTAAAGACAA CAGTGTAAGAATCGGTTCCA AGGGGGATGTGTTTGTCATA AGGGAACCATTCATATCATG CTCCCCCTTGGAATGCAGAA
+KF647919|Alabama|12_13|H1N1 GCTATATACAGTAAAGACAA CAGTGTAAGAATCGGTTCCA AGGGGGATGTGTTTGTCATA AGGGAACCATTCATATCATG CTCCCCCTTGGAATGCAGAA
+KF647931|Wisconsin|12_13|H1N1 GCTATATACAGTAAAGACAA CAGTGTAAGAATCGGTTCCA AGGGGGATGTGTTTGTCATA AGGGAACCATTCATATCATG CTCCCCCTTGGAATGCAGAA
+KF647932|Pennsylvania|12_13|H1N1 GCTATATACAGTAAAGACAA CAGTGTAAGAATCGGTTCCA AGGGGGATGTGTTTGTCATA AGGGAACCATTCATATCATG CTCCCCCTTGGAATGCAGAA
+KF647958|Nebraska|12_13|H1N1 GCTATATACAGTAAAGACAA CAGTGTAAGAATCGGTTCCA AGGGGGATGTGTTTGTCATA AGGGAACCATTCATATCATG CTCCCCCTTGGAATGCAGAA
+KF647971|Oklahoma|12_13|H1N1 GCTATATACAGTAAAGACAA CAGTGTAAGAATCGGTTCCA AGGGGGATGTGTTTGTCATA AGGGAACCATTCATATCATG CTCCCCCTTGGAATGCAGAA
+KF647902|Iowa|12_13|H1N1 GCTATATACAGTAAAGACAA CAGTGTAAGAATCGGTTCCA AGGGGGATGTGTTTGTCATA AGGGAACCATTCATATCATG CTCCCCCTTGGAATGCAGAA
+KF648002|Minnesota|12_13|H1N1 GCTATATACAGTAAAGACAA CAGTGTAAGAATCGGTTCCA AGGGGGATGTGTTTGTCATA AGGGAACCATTCATATCATG CTCCCCCTTGGAATGCAGAA
+KF648040|New_Jersey|12_13|H1N1 GCTATATACAGTAAAGACAA CAGTGTAAGAATCGGTTCCA AGGGGGATGTGTTTGTCATA AGGGAACCATTCATATCATG CTCCCCCTTGGAATGCAGAA
+KF648101|Ohio|12_13|H1N1 GCTATATACAGTAAAGACAA CAGTGTAAGAATCGGTTCCA AGGGGGATGTGTTTGTCATA AGGGAACCATTCATATCATG CTCCCCCTTGGAATGCAGAA
+KF648260|Washington|12_13|H1N1 GCTATATACAGTAAAGACAA CAGTGTAAGAATCGGTTCCA AGGGGGATGTGTTTGTCATA AGGGAACCATTCATATCATG CTCCCCCTTGGAATGCAGAA
+CY170697|California|12_13|H1N1 GCTATATACAGTAAAGACAA CAGTGTAAGAATCGGTTCCA AGGGGGATGTGTTTGTCATA AGGGAACCATTCATATCATG CTCCCCCTTGGAATGCAGAA
+CY168881|Massachusetts|12_13|H1N1 GCTATATACAGTAAAGACAA CAGTGTAAGAATCGGTTCCA AGGGGGATGTGTTTGTCATA AGGGAACCATTCATATCATG CTCCCCCTTGGAATGCAGAA
+CY171161|Illinois|12_13|H1N1 GCTATATACAGTAAAGACAA CAGTATAAGAATCGGTTCCA AGGGGGATGTGTTTGTCATA AGGGAACCATTCATATCATG CTCCCCCTTGGAATGCAGAA
+
+CY130177|South_Carolina|12_13|H1N1 CCTTCTTCTTGACCCAAGGG GCCTTGCTAAATGACAAACA TTCCAATGGAACCATTAAAG ACAGGAGCCCATATCGAACC CTAATGAGCTGTCCTATTGG
+KF647978|Idaho|12_13|H1N1 CCTTCTTCTTGACTCAAGGG GCCTTGCTAAATGACAAACA TTCCAATGGAACCATTAAAG ACAGGAGCCCATATCGAACC CTAATGAGCTGTCCTATTGG
+KF648268|New_Mexico|12_13|H1N1 CCTTCTTCTTGACTCAAGGG GCCTTGCTAAATGACAAACA TTCCAATGGAACCATTAAAG ACAGGAGCCCATATCGAACC CTAATGAGCTGTCCTATTGG
+KF648064|North_Carolina|12_13|H1N1 CCTTCTTCTTGACTCAAGGG GCCTTGCTAAATGACAAACA TTCCAATGGAACCATTAAAG ACAGGAGCCCATATCGAACC CTAATGAGCTGTCCTATTGG
+KF647995|New_Hampshire|12_13|H1N1 CCTTCTTCTTGACTCAAGGG GCATTGCTAAATGACAAACA TTCCAATGGAACCATTAAAG ACAGGAGCCCATATCGAACC CTAATGAGCTGTCCTATTGG
+KF648000|Colorado|12_13|H1N1 CCTTCTTCTTGACTCAAGGG GCCTTGCTAAATGACAAACA TTCCAATGGAACCATTAAAG ACAGGAGCCCATATCGAACC CTAATGAGCTGTCCTATTGG
+KF648133|Florida|12_13|H1N1 CCTTCTTCTTGACTCAAGGG GCCTTGCTAAATGACAAACA TTCCAATGGAACCATTAAAG ACAGGAGCCCATATCGAACC CTAATGAGCTGTCCTATTGG
+KF648145|Georgia|12_13|H1N1 CCTTCTTCTTGACTCAAGGG GCCTTGCTAAATGACAAACA TTCCAATGGAACCATTAAAG ACAGGAGCCCATATCGAACC CTAATGAGCTGTCCTATTGG
+KF648155|Vermont|12_13|H1N1 CCTTCTTCTTGACTCAAGGG GCCTTGCTAAATGACAAACA TTCCAATGGAACCATTAAAG ACAGGAGCCCATATCGAACC CTAATGAGCTGTCCTATTGG
+KF648158|Utah|12_13|H1N1 CCTTCTTCTTGACTCAAGGG GCCTTGCTAAATGACAAACA TTCCAATGGAACCATTAAAG ACAGGAGCCCATATCGAACC CTAATGAGCTGTCCTATTGG
+KF648159|Louisiana|12_13|H1N1 CCTTCTTCTTGACTCAAGGG GCCTTGCTAAATGACAAACA TTCCAATGGAACCATTAAAG ACAGGAGCCCATATCGAACC CTAATGAGCTGTCCTATTGG
+KF648008|Rhode_Island|12_13|H1N1 CCTTCTTCTTGACTCAAGGG GCCTTGCTAAATGACAAACA TTCCAATGGAACCATTAAAG ACAGGAGCCCATATCGAACC CTAATGAGCTGTCCTATTGG
+KF648011|New_York|12_13|H1N1 CCTTCTTCTTGACTCAAGGG GCCTTGCTAAATGACAAACA TTCCAATGGAACCATTAAGG ACAGGAGCCCATATCGAACC CTAATGAGCTGTCCTATTGG
+KF647921|Maryland|12_13|H1N1 CCTTCTTCTTGACTCAAGGG GCCTTGCTAAATGACAAACA TTCCAATGGAACCATTAAAG ACAGGAGCCCATATCGAACC CTAATGAGCTGTCCTATTGG
+KF647926|Missouri|12_13|H1N1 CCTTCTTCTTGACTCAAGGG GCCTTGCTAAATGACAAACA TTCCAATGGAACCATTAAAG ACAGGAGCCCATATCGAACC CTAATGAGCTGTCCTATTGG
+KF647928|Texas|12_13|H1N1 CCTTCTTCTTGACTCAAGGG GCCTTGCTAAATGACAAACA TTCCAATGGAACCATTAAAG ACAGGAGCCCATATCGAACC TTAATGAGCTGTCCTATTGG
+KF647936|Wyoming|12_13|H1N1 CCTTCTTCTTGACTCAAGGG GCCTTGCTAAATGACAAACA TTCCAATGGAACCATTAAAG ACAGGAGCCCATATCGAACC CTAATGAGCTGTCCTATTGG
+KF648197|Indiana|12_13|H1N1 CCTTCTTCTTGACTCAAGGG GCCTTGCTAAATGACAAACA TTCCAATGGAACCATTAAAG ACAGGAGCCCATATCGAACC CTAATGAGCTGTCCTATTGG
+KF648228|Mississippi|12_13|H1N1 CCTTCTTCTTGACTCAAGGG GCCTTGCTAAATGACAAACA TTCCAATGGAACCATTAAAG ACAGGAGCCCATATCGAACC CTAATGAGCTGTCCTATTGG
+KF648239|Tennessee|12_13|H1N1 CCTTCTTCTTGACTCAAGGG GCCTTGCTAAATGACAAACA TTCCAATGGAACCATTAAAG ACAGGAGCCCATATCGAACC CTAATGAGCTGTCCTATTGG
+KF648034|Arizona|12_13|H1N1 CCTTCTTCTTGACTCAAGGG GCCTTGCTAAATGACAAACA TTCCAATGGAACCATTAAAG ACAGGAGCCCATATCGAACC CTAATGAGCTGTCCTATTGG
+KF648037|Kentucky|12_13|H1N1 CCTTCTTCTTGACTCAAGGG GCCTTGCTAAATGACAAACA TTCCAATGGAACCATTAAAG ACAGGAGCCCATATCGAACC CTAATGAGCTGTCCTATTGG
+KF648038|Kansas|12_13|H1N1 CCTTCTTCTTGACTCAAGGG GCCTTGCTAAATGACAAACA TTCCAATGGAACCATTAAAG ACAGGAGCCCATATCGAACC CTAATGAGCTGTCTTATTGG
+KF647919|Alabama|12_13|H1N1 CCTTCTTCTTGACTCAAGGG GCCTTGCTAAATGACAAACA TTCCAATGGAACCATTAAAG ACAGGAGCCCATATCGAACC CTAATGAGCTGTCCTATTGG
+KF647931|Wisconsin|12_13|H1N1 CCTTCTTCTTGACTCAAGGG GCCTTGCTAAATGACAAACA TTCCAATGGAACCATTAAAG ACAGGAGCCCATATCGAACC CTAATGAGCTGTCCTATTGG
+KF647932|Pennsylvania|12_13|H1N1 CCTTCTTCTTGACTCAAGGG GCCTTGCTAAATGACAAACA TTCCAATGGAACCATTAAAG ACAGGAGCCCATATCGAACC CTAATGAGCTGTCCTATTGG
+KF647958|Nebraska|12_13|H1N1 CCTTCTTCTTGACTCAAGGG GCCTTGCTAAATGACAAACA TTCCAATGGAACCATTAAAG ACAGGAGCCCATATCGAACC CTAATGAGCTGTCCTATTGG
+KF647971|Oklahoma|12_13|H1N1 CCTTCTTCTTGACTCAAGGG GCCTTGCTAAATGACAAACA TTCCAATGGAACCATTAAAG ACAGGAGCCCATATCGAACC CTAATGAGCTGTCCTATTGG
+KF647902|Iowa|12_13|H1N1 CCTTCTTCTTGACTCAAGGG GCCTTGCTAAATGACAAACA TTCCAATGGAACCATTAAAG ACAGGAGCCCATATCGAACC CTAATGAGCTGTCCTATTGG
+KF648002|Minnesota|12_13|H1N1 CCTTCTTCTTGACTCAAGGG GCCTTGCTAAATGACAAACA TTCCAATGGAACCATTAAAG ACAGGAGCCCATATCGAACC CTAATGAGCTGTCCTATTGG
+KF648040|New_Jersey|12_13|H1N1 CCTTCTTCTTGACTCAAGGG GCCTTGCTAAATGACAAACA TTCCAATGGAACCATTAAAG ACAGGAGCCCATATCGAACC CTAATGAGCTGTCCTATTGG
+KF648101|Ohio|12_13|H1N1 CCTTCTTCTTGACTCAAGGG GCCTTGCTAAATGACAAACA TTCCAATGGAACCATTAAAG ACAGGAGCCCATATCGAACC CTAATGAGCTGTCCTATTGG
+KF648260|Washington|12_13|H1N1 CCTTCTTCTTGACTCAAGGG GCCTTGCTAAATGACAAACA TTCCAATGGAACCATTAAAG ACAGGAGCCCATATCGAACC CTAATGAGCTGTCCTATTGG
+CY170697|California|12_13|H1N1 CCTTTTTCTTGACTCAAGGG GCCTTGCTAAATGACAAACA TTCCAATGGAACCATTAAAG ACAGGAGCCCATATCGAACC CTAATGAGCTGTCCTATTGG
+CY168881|Massachusetts|12_13|H1N1 CCTTCTTCTTGACTCAAGGG GCCTTGCTAAATGACAAACA TTCCAATGGAACCATTAAAG ACAGGAGCCCATATCGAACC CTAATGAGCTGTCCTATTGG
+CY171161|Illinois|12_13|H1N1 CCTTCTTCTTGACTCAAGGG GCCTTGCTAAATGACAAACA TTCCAATGGAACCATTAAAG ACAGGAGCCCATATCGAACC CTAATGAGCTGTCCTATTGG
+
+CY130177|South_Carolina|12_13|H1N1 TGAAGTTCCCTCTCCATACA ACTCAAGATTTGAGTCAGTC GCTTGGTCAGCAAGTGCTTG TCATGATGGCATCAATTGGC TAACAATTGGAATTTCTGGC
+KF647978|Idaho|12_13|H1N1 TGAAGTTCCCTCTCCATACA ACTCAAGATTTGAGTCAGTC GCTTGGTCAGCAAGTGCTTG TCATGATGGCATCAATTGGC TAACAATTGGAATTTCTGGC
+KF648268|New_Mexico|12_13|H1N1 TGAAGTTCCCTCTCCATACA ACTCAAGATTTGAGTCGGTC GCTTGGTCAGCAAGTGCTTG TCATGATGGCATCAATTGGC TAACAATTGGAATTTCTGGC
+KF648064|North_Carolina|12_13|H1N1 TGAAGTTCCCTCTCCATACA ACTCAAGATTTGAGTCGGTC GCTTGGTCAGCAAGTGCTTG TCATGATGGCATCAATTGGC TAACAATTGGAATTTCTGGC
+KF647995|New_Hampshire|12_13|H1N1 TGAAGTTCCCTCTCCATACA ACTCAAGATTTGAGTCGGTC GCTTGGTCAGCAAGTGCTTG TCATGATGGCATCAATTGGC TAACAATTGGAATTTCTGGC
+KF648000|Colorado|12_13|H1N1 TGAAGTTCCCTCTCCATACA ACTCAAGATTTGAGTCGGTC GCTTGGTCAGCAAGTGCTTG TCATGATGGCATTAATTGGC TAACAATTGGAATTTCTGGC
+KF648133|Florida|12_13|H1N1 TGAAGTTCCCTCTCCATACA ACTCAAGATTTGAGTCGGTC GCTTGGTCAGCAAGTGCTTG TCATGATGGCATCAATTGGC TAACAATTGGAATTTCTGGC
+KF648145|Georgia|12_13|H1N1 TGAAGTTCCCTCTCCATACA ACTCAAGATTTGAGTCAGTC GCTTGGTCAGCAAGTGCTTG TCATGATGGCATCAATTGGC TAACAATTGGAATTTCTGGC
+KF648155|Vermont|12_13|H1N1 TGAAGTTCCCTCTCCATACA ACTCAAGATTTGAGTCAGTC GCTTGGTCAGCAAGTGCTTG TCATGATGGCATCAATTGGC TAACAATTGGAATTTCTGGC
+KF648158|Utah|12_13|H1N1 TGAAGTTCCCTCTCCATACA ACTCAAGATTTGAGTCGGTC GCTTGGTCAGCAAGTGCTTG TCATGATGGCATCAATTGGC TAACAATTGGAATTTCTGGC
+KF648159|Louisiana|12_13|H1N1 TGAAGTTCCCTCTCCATACA ACTCAAGATTTGAGTCAGTC GCTTGGTCAGCAAGTGCTTG TCATGATGGCATCAATTGGC TAACAATTGGAATTTCTGGC
+KF648008|Rhode_Island|12_13|H1N1 TGAAGTTCCCTCTCCATACA ACTCAAGATTTGAGTCAGTC GCTTGGTCAGCAAGTGCTTG TCATGATGGCATCAATTGGC TAACAATTGGAATTTCTGGC
+KF648011|New_York|12_13|H1N1 TGAAGTTCCCTCTCCATACA ACTCAAGATTTGAGTCAGTC GCTTGGTCAGCAAGTGCTTG TCATGATGGCATCAATTGGC TAACAATTGGAATTTCTGGC
+KF647921|Maryland|12_13|H1N1 TGAAGTTCCCTCTCCATACA ACTCAAGATTTGAGTCGGTC GCTTGGTCAGCAAGTGCTTG TCATGATGGCATCAATTGGC TAACAATTGGAATTTCTGGC
+KF647926|Missouri|12_13|H1N1 TGAAGTTCCCTCTCCATACA ACTCAAGATTTGAGTCGGTC GCTTGGTCAGCAAGTGCTTG TCATGATGGCATCAATTGGC TAACAATTGGAATTTCTGGC
+KF647928|Texas|12_13|H1N1 TGAAGTTCCCTCTCCATACA ACTCAAGATTTGAGTCAGTC GCTTGGTCAGCAAGTGCTTG TCATGATGGCATCAATTGGC TAACAATTGGAATTTCTGGC
+KF647936|Wyoming|12_13|H1N1 TGAAGTTCCCTCCCCATACA ACTCAAGATTTGAGTCAGTC GCTTGGTCAGCAAGTGCTTG TCATGATGGCATCAATTGGC TAACAATTGGAATTTCTGGC
+KF648197|Indiana|12_13|H1N1 TGAAGTTCCCTCTCCATACA ACTCAAGATTTGAGTCAGTC GCTTGGTCAGCAAGTGCTTG TCATGATGGCATCAATTGGC TAACAATTGGAATTTCTGGC
+KF648228|Mississippi|12_13|H1N1 TGAAGTTCCCTCTCCATACA ACTCAAGATTTGAGTCGGTC GCTTGGTCAGCAAGTGCTTG TCATGATGGCATCAATTGGC TAACAATTGGAATTTCTGGC
+KF648239|Tennessee|12_13|H1N1 TGAAGTTCCCTCTCCATACA ACTCAAGATTTGAGTCGGTC GCTTGGTCAGCAAGTGCTTG TCATGATGGCATCAATTGGC TAACAATTGGAATTTCTGGC
+KF648034|Arizona|12_13|H1N1 TGAAGTTCCCTCTCCATACA ACTCAAGATTTGAGTCGGTC GCTTGGTCAGCAAGTGCTTG TCATGATGGCATCAATTGGC TAACAATTGGAATTTCTGGC
+KF648037|Kentucky|12_13|H1N1 TGAAGTTCCCTCTCCATACA ACTCAAGATTTGAGTCAGTC GCTTGGTCAGCAAGTGCTTG TCATGATGGCATCAATTGGC TAACAATTGGAATTTCTGGC
+KF648038|Kansas|12_13|H1N1 TGAAGTTCCCTCTCCATACA ACTCAAGATTTGAGTCAGTC GCTTGGTCAGCAAGTGCTTG TCATGATGGCATCAATTGGC TAACAATTGGAATTTCTGGC
+KF647919|Alabama|12_13|H1N1 TGAAGTTCCCTCTCCATACA ACTCAAGATTTGAGTCGGTC GCTTGGTCAGCAAGTGCTTG TCATGATGGCATCAATTGGC TAACAATTGGAATTTCTGGC
+KF647931|Wisconsin|12_13|H1N1 TGAAGTTCCCTCTCCATACA ACTCAAGATTTGAGTCAGTC GCTTGGTCAGCAAGTGCTTG TCATGATGGCATCAATTGGC TAACAATTGGAATTTCTGGC
+KF647932|Pennsylvania|12_13|H1N1 TGAAGTTCCCTCTCCATACA ACTCAAGATTTGAGTCAGTC GCTTGGTCAGCAAGTGCTTG TCATGATGGCATCAATTGGC TAACAATTGGAATTTCTGGC
+KF647958|Nebraska|12_13|H1N1 TGAAGTTCCCTCTCCATACA ACTCAAGATTTGAGTCAGTC GCTTGGTCAGCAAGTGCTTG TCATGATGGCATCAATTGGC TAACAATTGGAATTTCTGGC
+KF647971|Oklahoma|12_13|H1N1 TGAAGTTCCCTCTCCATACA ACTCAAGATTTGAGTCAGTC GCTTGGTCAGCAAGTGCTTG TCATGATGGCATCAATTGGC TAACAATTGGAATTTCTGGC
+KF647902|Iowa|12_13|H1N1 TGAAGTTCCCTCTCCATACA ACTCAAGATTTGAGTCGGTC GCTTGGTCAGCAAGTGCTTG TCATGATGGCATCAATTGGC TAACAATTGGAATTTCTGGC
+KF648002|Minnesota|12_13|H1N1 TGAAGTTCCCTCTCCATACA ACTCAAGATTTGAGTCGGTC GCTTGGTCAGCAAGTGCTTG TCATGATGGCATCAATTGGC TAACAATTGGAATTTCTGGC
+KF648040|New_Jersey|12_13|H1N1 TGAAGTTCCCTCTCCATACA ACTCAAGATTTGAGTCAGTC GCTTGGTCAGCAAGTGCTTG TCATGATGGCATCAATTGGC TAACAATTGGAATTTCTGGC
+KF648101|Ohio|12_13|H1N1 TGAAGTTCCCTCTCCATACA ACTCAAGATTTGAGTCAGTC GCTTGGTCAGCAAGTGCTTG TCATGATGGCATCAATTGGC TAACAATTGGAATTTCTGGC
+KF648260|Washington|12_13|H1N1 TGAAGTTCCCTCTCCATACA ACTCAAGATTTGAGTCGGTC GCTTGGTCAGCAAGTGCTTG TCATGATGGCATCAATTGGC TAACAATTGGAATTTCTGGC
+CY170697|California|12_13|H1N1 TGAAGTTCCCTCTCCATACA ACTCAAGATTTGAGTCAGTC GCTTGGTCAGCAAGTGCTTG TCATGATGGCATCAATTGGC TAACAATTGGAATTTCTGGC
+CY168881|Massachusetts|12_13|H1N1 TGAAGTTCCCTCTCCATACA ACTCAAGATTTGAGTCAGTC GCTTGGTCAGCAAGTGCTTG TCATGATGGCATCAATTGGC TAACAATTGGAATTTCTGGC
+CY171161|Illinois|12_13|H1N1 TGAAGTTCCCTCTCCATACA ACTCAAGATTTGAGTCAGTC GCTTGGTCAGCAAGTGCTTG TCATGATGGCATCAATTGGC TAACAATTGGAATTTCTGGC
+
+CY130177|South_Carolina|12_13|H1N1 CCAGACAATGGGGCAGTGGC TGTGTTAAAGTACAACGGCA TAATAACAGACACTATCAAG AGTTGGAGAAATAATATATT GAGAACACAAGAATCTGAAT
+KF647978|Idaho|12_13|H1N1 CCAGACAGTGGGGCAGTGGC TGTGTTAAAGTACAACGGCA TAATAACAGACACTATCAAG AGTTGGAGAAACGATATATT GAGAACACAAGAGTCTGAAT
+KF648268|New_Mexico|12_13|H1N1 CCAGACAGTGGGGCAGTGGC TGTATTAAAGTACAATGGCA TAATAACAGACACTATCAAG AGTTGGAGAAACAATATAGT GAGAACACAAGAGTCTGAAT
+KF648064|North_Carolina|12_13|H1N1 CCAGACAGTGGGGCAGTGGC TGTATTAAAGTACAATGGCA TAATAACAGACACTATCAAG AGTTGGAGAAACAATATATT GAGAACACAAGAGTCTGAAT
+KF647995|New_Hampshire|12_13|H1N1 CCAGACAGTGGGGCAGTGGC TGTATTAAAGTACAATGGCA TAATAACAGACACTATCAAG AGTTGGAGAAACAATATATT GAGAACACAAGAGTCTGAAT
+KF648000|Colorado|12_13|H1N1 CCAGACAGTGGGGCAGTGGC TGTATTAAAGTACAATGGCA TAATAACAGACACTATCAAG AGTTGGAGAAACAATATATT GAGAACACAAGAATCTGAAT
+KF648133|Florida|12_13|H1N1 CCAGACAGTGGGGCAGTGGC TGTATTAAAGTACAATGGCA TAATAACAGACACTATCAAG AGTTGGAGAAACAATATATT GAGAACACAAGAGTCTGAAT
+KF648145|Georgia|12_13|H1N1 CCAGACAGTGGGGCAGTGGC TGTGTTAAAGTACAATGGCA TAATAACAGACACTATCAAG AGTTGGRAAAATAATATATT GAGAACACAAGAGTCTGAAT
+KF648155|Vermont|12_13|H1N1 CCAGACAGTGGGGCAGTGGC TGTGTTAAAGTACAATGGCA TAATAACAGACACTATCAAG AGTTGGAAAAATAATATATT GAGAACACAAGAGTCTGAAT
+KF648158|Utah|12_13|H1N1 CCAGACAGTGGGGCAGTGGC TGTATTAAAGTACAATGGCA TAATAACAGACACTATCAAG AGTTGGAGAAACAATATATT GAGAACACAAGAGTCTGAAT
+KF648159|Louisiana|12_13|H1N1 CCAGACAGTGGGGCAGTGGC TGTGTTAAAGTACAATGGCA TAATAACAGACACTATCAAG AGTTGGAGAAACAATATATT GAGAACACAAGAGTCTGAAT
+KF648008|Rhode_Island|12_13|H1N1 CCAGACAGTGGGGCAGTGGC TGTGTTAAAGTACAACGGCA TAATAACAGACACTATCAAG AGTTGGAGAAACAATATATT GAGAACACAAGAGTCTGAAT
+KF648011|New_York|12_13|H1N1 CCAGACAGTGGGGCAGTGGC TGTGTTAAAGTACAACGGCA TAATAACAGACACTATCAAG AGTTGGAGAAACAATATATT GAGAACACAAGAGTCTGAAT
+KF647921|Maryland|12_13|H1N1 CCAGACAGTGGGGCAGTGGC TGTATTAAAGTACAATGGCA TAATAACAGACACTATCAAG AGTTGGAGAAACAATATATT GAGAACACAAGAGTCTGAAT
+KF647926|Missouri|12_13|H1N1 CCAGACAGTGGGGCAGTGGC TGTATTAAAGTACAATGGCA TAATAACAGACACTATCAAG AGTTGGAGAAACAATATATT GAGAACACAAGAGTCTGAAT
+KF647928|Texas|12_13|H1N1 CCAGACAATGGGGCAGTTGC TGTGTTAAAGTACAACGGCA TAATAACAGACACTATCAAG AGTTGGAGAAACAATATATT GAGAACACAAGAGTCTGAAT
+KF647936|Wyoming|12_13|H1N1 CCAGACAATGGGGCAGTGGC TGTGTTAAAGTACAACGGCA TAATAACAGACACTATCAAG AGTTGGAGAAATAATATATT GAGAACACAAGAATCTGAAT
+KF648197|Indiana|12_13|H1N1 CCAGACAGTGGGGCAGTGGC TGTGTTAAAGTACAATGGCA TAATAACAGACACTATCAAG AGTTGGAAAAATAATATATT GAGAACACAAGAGTCTGAAT
+KF648228|Mississippi|12_13|H1N1 CCAGACAGTGGGGCAGTGGC TGTATTAAAGTACAATGGCA TAATAACAGACACTATCAAG AGTTGGAGAAACAATATATT GAGAACACAAGAGTCTGAAT
+KF648239|Tennessee|12_13|H1N1 CCAGACAGTGGGGCAGTTGC TGTATTAAAGTACAATGGCA TAATAACAGACACTATCAAG AGTTGGAGAAACAATATATT GAGAACACAAGAGTCTGAAT
+KF648034|Arizona|12_13|H1N1 CCAGACAGTGGGGCAGTGGC TGTATTAAAGTACAATGGCA TAATAACAGACACTATCAAG AGTTGGAGAAACAATATATT GAGAACACAAGAGTCTGAAT
+KF648037|Kentucky|12_13|H1N1 CCAGACAGTGGGGCAGTGGC TGTGTTAAAGTACAATGGCA TAATAACAGACACTATCAAG AGTTGGAAAAATAATATATT GAGAACACAAGAGTCTGAAT
+KF648038|Kansas|12_13|H1N1 CCAGACAGTGGGGCAGTGGC TGTGTTAAAGTACAATGGCA TAATAACAGACACTATCAAG AGTTGGAAAAATAATATATT GAGAACACAAGAGTCTGAAT
+KF647919|Alabama|12_13|H1N1 CCAGACAGTGGGGCAGTGGC TGTATTAAAGTACAATGGCA TAATAACAGACACTATCAAG AGTTGGAGAAACAATATATT GAGAACACAAGAGTCTGAAT
+KF647931|Wisconsin|12_13|H1N1 CCAGACAGTGGGGCAGTGGC TGTGTTAAAGTACAACGGCA TAATAACAGACACTATCAAG AGTTGGAGAAACAATATATT GAGAACACAAGAGTCTGAAT
+KF647932|Pennsylvania|12_13|H1N1 CCAGACAGTGGGGCAGTGGC TGTGTTAAAGTACAATGGCA TAATAACAGACACTATCAAG AGTTGGAAAAATAATATATT GAGAACACAAGAGTCTGAAT
+KF647958|Nebraska|12_13|H1N1 CCAGACAGTGGGGCAGTGGC TGTGTTAAAGTACAATGGCA TAATAACAGACACTATCAAG AGTTGGAAAAATAATATATT GAGAACACAAGAGTCTGAAT
+KF647971|Oklahoma|12_13|H1N1 CCAGACAGTGGGGCAGTGGC TGTGTTAAAGTACAACGGCA TAATAACAGACACTATCAAG AGTTGGAGAAACGATATATT GAGAACACAAGAGTCTGAAT
+KF647902|Iowa|12_13|H1N1 CCAGACAGTGGGGCAGTGGC TGTATTAAAGTACAATGGCA TAATAACAGACACTATCAAG AGTTGGAGAAACAATATATT GAGAACACAAGAGTCTGAAT
+KF648002|Minnesota|12_13|H1N1 CCAGACAGTGGGGCAGTGGC TGTATTAAAGTACAATGGCA TAATAACAGACACTATCAAG AGTTGGAGAAACAATATATT GAGAACACAAGAGTCTGAAT
+KF648040|New_Jersey|12_13|H1N1 CCAGACAGTGGGGCAGTGGC TGTGTTAAAGTACAATGGCA TAATAACAGACACTATCAAG AGTTGGAGAAACAATATATT GAGAACACAAGAGTCTGAAT
+KF648101|Ohio|12_13|H1N1 CCAGACAGTGGGGCAGTGGC TGTGTTAAAGTACAACGGCA TAATAACAGACACTATCAAG AGTTGGAGAAACGATATATT GAGAACACAAGAGTCTGAAT
+KF648260|Washington|12_13|H1N1 CCAGACAGTGGGGCAGTGGC TGTATTAAAGTACAATGGCA TAATAACAGACACTATCAAG AGTTGGAGAAACAATATATT GAGAACACAAGAGTCTGAAT
+CY170697|California|12_13|H1N1 CCAGACAGTGGGGCAGTGGC TGTGTTAAAGTACAACGGCA TAATAACAGACACTATCAAG AGTTGGAGAAACGATATATT GAGAACACAAGAGTCTGAAT
+CY168881|Massachusetts|12_13|H1N1 CCAGACAGTGGGGCAGTGGC TGTGTTAAAGTACAACGGCA TAATAACAGACACTATCAAG AGTTGGAGAAACAATATATT GAGAACACAAGAGTCTGAAT
+CY171161|Illinois|12_13|H1N1 CCAGACAATGGGGCAGTGGC TGTGTTAAAGTACAACGGCG TAATAACAGACACTATCAAG AGTTGGAGAAACAATATATT GAGAACACAAGAGTCTGAAT
+
+CY130177|South_Carolina|12_13|H1N1 GTGCATGTGTAAATGGTTCT TGCTTTACCATAATGACCGA TGGACCAAGTGATGGACAGG CCTCATACAAGATCTTCAGA ATAGAAAAGGGAAAGATAGT
+KF647978|Idaho|12_13|H1N1 GTGCATGTGTAAATGGTTCT TGCTTTACCATAATGACCGA TGGACCAAGTGATGGACAGG CCTCATACAAGATCTTCAGA ATAGAAAAGGGAAAGATAGT
+KF648268|New_Mexico|12_13|H1N1 GTGCATGTGTAAATGGTTCT TGCTTTACCATAATGACCGA TGGACCAAGTGATGGACAGG CCTCATACAAGATCTTCAGA ATAGAAAAGGGAAAGATAGT
+KF648064|North_Carolina|12_13|H1N1 GTGCATGTGTAAATGGTTCT TGCTTTACCATAATGACCGA TGGACCAAGTGATGGACAGG CCTCATACAAGATCTTCAGA ATAGAAAAGGGAAAGATAGT
+KF647995|New_Hampshire|12_13|H1N1 GTGCATGTGTAAATGGTTCT TGCTTTACCATAATGACCGA TGGACCAAGTGATGGACAGG CCTCATACAAGATCTTCAGA ATAGAAAAGGGAAAGATAGT
+KF648000|Colorado|12_13|H1N1 GTGCATGTGTAAATGGTTCT TGCTTTACCATAATGACCGA TGGACCAAGTGATGGACAGG CCTCATACAAGATCTTCAGA ATAGAAAAGGGAAAGATAGT
+KF648133|Florida|12_13|H1N1 GTGCATGTGTAAATGGTTCT TGCTTTACCATAATGACCGA TGGACCAAGTGATGGACAGG CCTCATACAAGATCTTCAGA ATAGAAAAGGGAAAGATAGT
+KF648145|Georgia|12_13|H1N1 GTGCATGTGTAAATGGTTCT TGCTTTACCATAATGACCGA TGGACCAAGTGACGGACAGG CCTCATACAAGATCTTCCGA ATAGAAAAGGGAAAGATAGT
+KF648155|Vermont|12_13|H1N1 GTGCATGTGTAAATGGTTCT TGCTTTACCATAATGACCGA TGGACCAAGTGACGGACAGG CCTCATACAAGATCTTCCGA ATAGAAAAGGGAAAGATAGT
+KF648158|Utah|12_13|H1N1 GTGCATGTGTAAATGGTTCT TGCTTTACCATAATGACCGA TGGACCAAGTGATGGACAGG CCTCATACAAGATCTTCAGA ATAGAAAAGGGAAAGATAGT
+KF648159|Louisiana|12_13|H1N1 GTGCATGTGTAAATGGTTCT TGCTTTACCATAATGACCGA TGGACCAAGTGATGGACAGG CCTCATACAAGATCTTCAGA ATAGAAAAGGGAAAGATAGT
+KF648008|Rhode_Island|12_13|H1N1 GTGCATGTGTAAATGGTTCT TGCTTTACCATAATGACCGA TGGACCAAGTGATGGACAGG CCTCATACAAGATCTTCAGA ATAGAAAAGGGAAAGATAGT
+KF648011|New_York|12_13|H1N1 GTGCATGTGTAAATGGTTCT TGCTTTACCATAATGACCGA TGGACCAAGTGATGGACAGG CCTCATACAAGATCTTCAGA ATAGAAAAGGGAAAGATAGT
+KF647921|Maryland|12_13|H1N1 GTGCATGTGTAAATGGTTCT TGCTTTACCATAATGACCGA TGGACCAAGTGATGGACAGG CCTCATACAAGATCTTCAGA ATAGAAAAGGGAAAGATAGT
+KF647926|Missouri|12_13|H1N1 GTGCATGTGTAAATGGTTCT TGCTTTACCATAATGACCGA TGGACCAAGTGATGGACAGG CCTCATACAAGATCTTCAGA ATAGAAAAGGGAAAGATAGT
+KF647928|Texas|12_13|H1N1 GTGCATGTGTAAATGGTTCT TGCTTTACCATAATGACCGA TGGACCAAGTGATGGACAGG CCTCATACAAGATCTTCAAA ATAGAAAAGGGAAAGATAGT
+KF647936|Wyoming|12_13|H1N1 GTGCATGTGTAAATGGTTCT TGCTTTACCATAATGACCGA TGGACCAAGTGATGGACAGG CCTCATACAAGATCTTCAGA ATAGAAAAGGGAAAGATAGT
+KF648197|Indiana|12_13|H1N1 GTGCATGTGTAAATGGTTCT TGCTTTACCATAATGACCGA TGGACCAAGTGACGGACAGG CCTCATACAAGATCTTCCGA ATAGAAAAGGGAAAGATAGT
+KF648228|Mississippi|12_13|H1N1 GTGCATGTGTAAATGGTTCT TGCTTTACCATAATGACCGA TGGACCAAGTGATGGACAGG CCTCATACAAGATCTTCAGA ATAGAAAAGGGAAAGATAGT
+KF648239|Tennessee|12_13|H1N1 GTGCATGTGTAAATGGTTCT TGCTTTACCATAATGACCGA TGGACCAAGTGATGGACAGG CCTCATACAAGATCTTCAGA ATAGAAAAGGGAAAGATAGT
+KF648034|Arizona|12_13|H1N1 GTGCATGTGTAAATGGTTCT TGCTTTACCATAATGACCGA TGGACCAAGTGATGGACAGG CCTCATACAAGATCTTCAGA ATAGAAAAGGGAAAGATAGT
+KF648037|Kentucky|12_13|H1N1 GTGCATGTGTAAATGGTTCT TGCTTTACCATAATGACCGA TGGACCAAGTGACGGACAGG CCTCATACAAGATCTTCCGA ATAGAAAAGGGAAAGATAGT
+KF648038|Kansas|12_13|H1N1 GTGCATGTGTAAATGGTTCT TGCTTTACCATAATGACCGA TGGACCAAGTGACGGACAGG CCTCATACAAGATCTTCCGA ATAGAAAAGGGAAAGATAGT
+KF647919|Alabama|12_13|H1N1 GTGCATGTGTAAATGGTTCT TGCTTTACCATAATGACCGA TGGACCAAGTGATGGACAGG CCTCATACAAGATCTTCAGA ATAGAAAAGGGAAAGATAGT
+KF647931|Wisconsin|12_13|H1N1 GTGCATGTGTAAATGGTTCT TGCTTTACCATAATGACCGA TGGACCAAGTGATGGACAGG CCTCATACAAGATCTTCAGA ATAGAAAAGGGAAAGATAGT
+KF647932|Pennsylvania|12_13|H1N1 GTGCATGTGTAAATGGTTCT TGCTTTACCATAATGACCGA TGGACCAAGTGACGGACAGG CCTCATACAAGATCTTCCGA ATAGAAAAGGGAAAGATAGT
+KF647958|Nebraska|12_13|H1N1 GTGCATGTGTAAATGGTTCT TGCTTTACCATAATGACCGA TGGACCAAGTGACGGACAGG CCTCATACAAGATCTTCCGA ATAGAAAAGGGAAAGATAGT
+KF647971|Oklahoma|12_13|H1N1 GTGCATGTGTAAATGGTTCT TGCTTTACCATAATGACCGA TGGACCAAGTGATGGACAGG CCTCATACAAGATCTTCAGA ATAGAAAAGGGAAAGATAGT
+KF647902|Iowa|12_13|H1N1 GTGCATGTGTAAATGGTTCT TGCTTTACCATAATGACCGA TGGACCAAGTGATGGACAGG CCTCATACAAGATCTTCAGA ATAGAAAAGGGAAAGATAGT
+KF648002|Minnesota|12_13|H1N1 GTGCATGTGTAAATGGTTCT TGCTTTACCATAATGACCGA TGGACCAAGTGATGGACAGG CCTCATACAAGATCTTCAGA ATAGAAAAGGGAAAGATAGT
+KF648040|New_Jersey|12_13|H1N1 GTGCATGTGTAAATGGTTCT TGCTTTACCATAATGACCGA TGGACCAAGTGATGGACAGG CCTCATACAAGATCTTCAGA ATAGAAAAGGGAAAGATAGT
+KF648101|Ohio|12_13|H1N1 GTGCATGTGTAAATGGTTCT TGCTTTACCATAATGACCGA TGGACCAAGTGATGGACAGG CCTCATACAAGATCTTCAGA ATAGAAAAGGGAAAGATAGT
+KF648260|Washington|12_13|H1N1 GTGCATGTGTAAATGGTTCT TGCTTTACCATAATGACCGA TGGACCAAGTGATGGACAGG CCTCATACAAGATCTTCAGA ATAGAAAAGGGAAAGATAGT
+CY170697|California|12_13|H1N1 GTGCATGTGTAAATGGTTCT TGCTTTACCATAATGACTGA TGGACCAAGTGATGGACAGG CCTCATACAAGATCTTCAGA ATAGAAAAGGGAAAGATAGT
+CY168881|Massachusetts|12_13|H1N1 GTGCATGTGTAAATGGTTCT TGCTTTACCATAATGACCGA TGGACCAAGTGATGGACAGG CCTCATACAAGATCTTCAGA ATAGAAAAGGGAAAGATAGT
+CY171161|Illinois|12_13|H1N1 GTGCATGTGTAAATGGTTCA TGCTTTACCATAATGACCGA TGGACCAAGTGATGGACAGG CCTCATACAAGATCTTCAGA ATAGAAAAGGGAAAGATAGT
+
+CY130177|South_Carolina|12_13|H1N1 CAAATCAGTCGAAATGAATG CCCCTAATTATCACTATGAG GAATGCTCCTGTTATCCTGA TTCTAGTGAAATCACATGTG TGTGCAGGGATAACTGGCAT
+KF647978|Idaho|12_13|H1N1 CAAATCAGTCGAAATGAATG CCCCTAATTATCACTATGAG GAATGCTCCTGTTATCCTGA TTCTAGTGAAATCACATGTG TGTGCAGGGATAACTGGCAT
+KF648268|New_Mexico|12_13|H1N1 CAAATCAGTCGAAATGAATG CCCCTAATTACCACTATGAG GAATGCTCCTGTTATCCTGA TTCTAGTGAAATCACATGTG TGTGCAGGGATAACTGGCAT
+KF648064|North_Carolina|12_13|H1N1 CAAATCAGTCGAAATGAATG CCCCTAATTATCACTATGAG GAATGCTCCTGTTATCCTGA TTCTAGTGAAATCACATGTG TGTGCAGGGATAACTGGCAT
+KF647995|New_Hampshire|12_13|H1N1 CAAATCAGTCGAAATGAATG CCCCTAATTATCACTATGAG GAATGCTCCTGTTATCCTGA TTCTAGTGAAATCACATGTG TGTGCAGGGATAACTGGCAT
+KF648000|Colorado|12_13|H1N1 CAAATCAGTCGAAATGAATG CCCCTAATTATCACTATGAG GAATGCTCCTGTTATCCTGA TTCTAGTGAAATCACATGTG TGTGCAGGGATAACTGGCAT
+KF648133|Florida|12_13|H1N1 CAAATCAGTCGAAATGAATG CCCCTAATTATCACTATGAG GAATGCTCCTGTTATCCTGA TTCTAGTGAAATCACATGTG TGTGCAGGGATAACTGGCAT
+KF648145|Georgia|12_13|H1N1 CAAATCAGTCGAAATGAATG CCCCTAATTATCACTATGAG GAATGCTCCTGTTATCCTGA TTCTAGTGAAATCACATGTG TGTGCAGGGATAACTGGCAT
+KF648155|Vermont|12_13|H1N1 CAAATCAGTCGAAATGAATG CCCCTAATTATCACTATGAG GAATGCTCCTGTTATCCTGA TTCTAGTGAAATCATATGTG TGTGCAGGGATAACTGGCAT
+KF648158|Utah|12_13|H1N1 CAAATCAGTCGAAATGAATG CCCCTAATTATCACTATGAG GAATGCTCCTGTTATCCTGA TTCTAGTGAAATCACATGTG TGTGCAGGGATAACTGGCAT
+KF648159|Louisiana|12_13|H1N1 CAAATCAGTCGAAATGAATG CCCCTAATTATCACTATGAG GAATGCTCCTGTTATCCTGA TTCTAGTGAAATCACATGTG TGTGCAGGGATAACTGGCAT
+KF648008|Rhode_Island|12_13|H1N1 CAAATCAGTCGAAATGAATG CCCCTAATTATCACTATGAG GAATGCTCCTGTTATCCTGA TTCTAGTGAAATCACATGTG TGTGCAGGGATAATTGGCAT
+KF648011|New_York|12_13|H1N1 CAAATCAGTCGAAATGAATG CCCCAAATTATCACTATGAG GAATGCTCCTGTTATCCTGA TTCTAGTGAAATCACATGTG TGTGCAGGGATAACTGGCAT
+KF647921|Maryland|12_13|H1N1 CAAATCAGTCGAAATGAATG CCCCTAATTATCACTATGAG GAATGCTCCTGTTATCCTGA TTCTAGTGAAATCACATGTG TGTGCAGGGATAACTGGCAT
+KF647926|Missouri|12_13|H1N1 CAAATCAGTCGAAATGAATG CCCCTAATTATCACTATGAG GAATGCTCCTGTTATCCTGA TTCTAGTGAAATCACATGTG TGTGCAGGGATAACTGGCAT
+KF647928|Texas|12_13|H1N1 CAAATCAGTCGAAATGAATG CCCCTAATTATCACTATGAG GAATGCTCCTGTTATCCTGA TTCTAGTGAAATCACATGTG TGTGCAGGGATAACTGGCAT
+KF647936|Wyoming|12_13|H1N1 CAAATCAGTCGAAATGAATG CCCCTAATTATCACTATGAG GAATGCTCCTGTTATCCTGA TTCTAGTGAAATCACATGTG TGTGCAGGGATAACTGGCAT
+KF648197|Indiana|12_13|H1N1 CAAATCAGTCGAAATGAATG CCCCTAATTATCACTATGAG GAATGCTCCTGTTATCCTGA TTCTAGTGAAATCACATGTG TGTGCAGGGATAACTGGCAT
+KF648228|Mississippi|12_13|H1N1 CAAATCAGTCGAAATGAATG CCCCTAATTATCACTATGAG GAATGCTCCTGTTATCCTGA TTCTAGTGAAATCACATGTG TGTGCAGGGATAACTGGCAT
+KF648239|Tennessee|12_13|H1N1 CAAATCAGTCGAAATGAATG CCCCTAATTATCACTATGAG GAATGCTCCTGTTATCCTGA TTCTAGTGAAATCACATGTG TGTGCAGGGATAACTGGCAT
+KF648034|Arizona|12_13|H1N1 CAAATCAGTCGAAATGAATG CCCCTAATTATCACTATGAG GAATGCTCCTGTTATCCTGA TTCTAGTGAAATCACATGTG TGTGCAGGGATAACTGGCAT
+KF648037|Kentucky|12_13|H1N1 CAAATCAGTCGAAATGAATG CCCCTAATTATCACTATGAG GAATGCTCCTGTTATCCTGA TTCTAGTGAAATCACATGTG TGTGCAGGGATAACTGGCAT
+KF648038|Kansas|12_13|H1N1 CAAATCAGTCGAAATGAATG CCCCTAATTATCACTATGAG GAATGCTCCTGTTATCCTGA TTCTAGTGAAATCACATGTG TGTGCAGGGATAACTGGCAT
+KF647919|Alabama|12_13|H1N1 CAAATCAGTCGAAATGAATG CCCCTAATTATCACTATGAG GAATGCTCCTGTTATCCTGA TTCTAGTGAAATCACATGTG TGTGCAGGGATAACTGGCAT
+KF647931|Wisconsin|12_13|H1N1 CAAATCAGTCGAAATGAATG CCCCTAATTATCACTATGAG GAATGCTCCTGTTATCCTGA TTCTAGTGAAATCACATGTG TGTGCAGGGATAACTGGCAT
+KF647932|Pennsylvania|12_13|H1N1 CAAATCAGTCGAAATGAATG CCCCTAATTATCACTATGAG GAATGCTCCTGTTATCCTGA TTCTAGTGAAATCACATGTG TGTGCAGGGATAACTGGCAT
+KF647958|Nebraska|12_13|H1N1 CAAATCAGTCGAAATGAATG CCCCTAATTATCACTATGAG GAATGCTCCTGTTATCCTGA TTCTAGTGAAATCACATGTG TGTGCAGGGATAACTGGCAT
+KF647971|Oklahoma|12_13|H1N1 CAAATCAGTCGAAATGAATG CCCCTAATTATCACTATGAG GAATGCTCCTGTTATCCTGA TTCTAGTGAAATCACATGTG TGTGCAGGGATAACTGGCAT
+KF647902|Iowa|12_13|H1N1 CAAATCAGTCGAAATGAATG CCCCTAATTATCACTATGAG GAATGCTCCTGTTATCCTGA TTCTAGTGAAATCACATGTG TGTGCAGGGATAACTGGCAT
+KF648002|Minnesota|12_13|H1N1 CAAATCAGTCGAAATGAATG CCCCTAATTATCACTATGAG GAATGCTCCTGTTATCCTGA TTCTAGTGAAATCACATGTG TGTGCAGGGATAACTGGCAT
+KF648040|New_Jersey|12_13|H1N1 CAAATCAGTCGAAATGAATG CCCCTAATTATCACTATGAG GAATGCTCCTGTTATCCTGA TTCTAGTGAAATCACATGTG TGTGCAGGGATAACTGGCAT
+KF648101|Ohio|12_13|H1N1 CAAATCAGTCGAAATGAATG CCCCTAATTATCACTATGAG GAATGCTCCTGTTATCCTGA TTCTAGTGAAATCACATGTG TGTGCAGGGATAACTGGCAT
+KF648260|Washington|12_13|H1N1 CAAATCAGTCGAAATGAATG CCCCTAATTATCACTATGAG GAATGCTCCTGTTATCCTGA TTCTAGTGAAATCACATGTG TGTGCAGGGATAACTGGCAT
+CY170697|California|12_13|H1N1 CAAATCAGTCGAAATGAATG CCCCTAATTATCACTATGAG GAATGCTCCTGTTATCCTGA TTCTAGTGAAATCACATGTG TGTGCAGGGATAACTGGCAT
+CY168881|Massachusetts|12_13|H1N1 CAAATCAGTCGAAATGAATG CCCCTAATTATCACTATGAG GAATGCTCCTGTTATCCTGA TTCTAGTGAAATCACATGTG TGTGCAGGGATAATTGGCAT
+CY171161|Illinois|12_13|H1N1 CAAATCAGTCGAAATGAATG CCCCTAATTATCACTATGAG GAATGCTCCTGTTATCCTGA TTCTAGTGAAATCACATGTG TGTGCAGGGATAACTGGCAT
+
+CY130177|South_Carolina|12_13|H1N1 GGCTCGAATCGACCGTGGGT GTCTTTCAACCAGAATCTGG AATATCAGATAGGATACATA TGCAGTGGGATTTTCGGAGA CAATCCACGCCCCAATGATA
+KF647978|Idaho|12_13|H1N1 GGCTCGAATCGACCGTGGGT GTCTTTCAACCAGAATCTGG AATATCAGATAGGATACATA TGCAGTGGGATTTTCGGAGA CAATCCACGCCCTAATGATA
+KF648268|New_Mexico|12_13|H1N1 GGCTCGAATCGACCGTGGGT GTCTTTCAACCAGAATCTGG AATATCAGATAGGATACATA TGCAGTGGGATTTTCGGAGA CAATCCACGCCCTAATGATA
+KF648064|North_Carolina|12_13|H1N1 GGCTCGAATCGACCGTGGGT GTCTTTCAACCAGAATCTGG AATATCAGATAGGATACATA TGCAGTGGGATTTTCGGAGA CAATCCACGCCCTAATGATA
+KF647995|New_Hampshire|12_13|H1N1 GGCTCGAATCGACCGTGGGT GTCTTTCAACCAGAATCTGG AATATCAGATAGGATACATA TGCAGTGGGATTTTCGGAGA CAATCCACGCCCTAATGATA
+KF648000|Colorado|12_13|H1N1 GGCTCGAATCGACCGTGGGT GTCTTTCAACCAGAATCTGG AATATCAGATAGGATACATA TGCAGTGGGATTTTCGGAGA CAATCCACGCCCTAATGATA
+KF648133|Florida|12_13|H1N1 GGCTCGAATCGACCGTGGGT GTCTTTCAACCAGAATCTGG AATATCAGATAGGATACATA TGCAGTGGGATTTTCGGAGA CAATCCACGCCCTAATGATA
+KF648145|Georgia|12_13|H1N1 GGCTCGAATCGACCGTGGGT GTCTTTCAACCAGAATCTGG AATATCAGATAGGATACATA TGCAGTGGGGTTTTCGGAGA CAATCCACGCCCTAATGATA
+KF648155|Vermont|12_13|H1N1 GGCTCGAATCGACCGTGGGT GTCTTTCAACCAGAATCTGG AATATCAGATAGGATACATA TGCAGTGGGGTTTTCGGAGA CAATCCACGCCCTAATGATA
+KF648158|Utah|12_13|H1N1 GGCTCGAATCGACCGTGGGT GTCTTTCAACCAGAATCTGG AATATCAGATAGGATACATA TGCAGTGGGATTTTCGGAGA CAATCCACGCCCTAATGATA
+KF648159|Louisiana|12_13|H1N1 GGCTCGAATCGACCGTGGGT GTCTTTCAACCAGAATCTGG AATATCAGATAGGATACATA TGCAGTGGGGTTTTCGGAGA CAATCCACGCCCTAATGATA
+KF648008|Rhode_Island|12_13|H1N1 GGCTCGAATCGACCGTGGGT GTCTTTCAACCAGAATCTGG AATATCAGATAGGATACATA TGCAGTGGGATTTTCGGAGA CAATCCACGCCCTAATGATA
+KF648011|New_York|12_13|H1N1 GGCTCGAATCGACCGTGGGT GTCTTTCAACCAGAATCTGG AATATCAGAAAGGATACATA TGCAGTGGGATTTTCGGAGA CAATCCACGCCCTAATGATA
+KF647921|Maryland|12_13|H1N1 GGCTCGAATCGACCGTGGGT GTCTTTCAACCAGAATCTGG AATATCAGATAGGATACATA TGCAGTGGGATTTTCGGAGA CAATCCACGCCCTAATGATA
+KF647926|Missouri|12_13|H1N1 GGCTCGAATCGACCGTGGGT GTCTTTCAACCAGAATCTGG AATATCAGATAGGATACATA TGCAGTGGGATTTTCGGAGA CAATCCACGCCCTAATGATA
+KF647928|Texas|12_13|H1N1 GGCTCGAATCGACCGTGGGT GTCTTTCAACCAGAATCTGG AATATCAGATAGGATACATA TGCAGTGGGATTTTCGGAGA CAATCCACGCCCTAATGATA
+KF647936|Wyoming|12_13|H1N1 GGCTCGAATCGACCGTGGGT TTCTTTCAACCAGAATCTGG AATATCAGATAGGATACATA TGCAGTGGGATTTTCGGAGA CAATCCACGTCCTAATGATA
+KF648197|Indiana|12_13|H1N1 GGCTCGAATCGACCGTGGGT GTCTTTCAACCAGAATCTGG AATATCAGATAGGATACATA TGCAGTGGGGTTTTCGGAGA CAATCCACGCCCTAATGATA
+KF648228|Mississippi|12_13|H1N1 GGCTCGAATCGACCGTGGGT GTCTTTCAACCAGAATCTGG AATATCAGATAGGATACATA TGCAGTGGGATTTTCGGAGA CAATCCACGCCCTAATGATA
+KF648239|Tennessee|12_13|H1N1 GGCTCGAATCGACCGTGGGT GTCTTTCAACCAGAATCTGG AATATAAGATAGGATACATA TGCAGTGGGATTTTCGGAGA CAATCCACGCCCTAATGATA
+KF648034|Arizona|12_13|H1N1 GGCTCGAATCGACCGTGGGT GTCTTTCAACCAGAATCTGG AATATCAGATAGGATACATA TGCAGTGGGATTTTCGGAGA CAATCCACGCCCTAATGATA
+KF648037|Kentucky|12_13|H1N1 GGCTCGAATCGACCGTGGGT GTCTTTCAACCAGAATCTGG AATATCAGATAGGATACATA TGCAGTGGGGTTTTCGGAGA CAATCCACGCCCTAATGATA
+KF648038|Kansas|12_13|H1N1 GGCTCGAATCGACCGTGGGT GTCTTTCAACCAGAATCTGG AATATCAGATAGGATACATA TGCAGTGGGGTTTTCGGAGA CAATCCACGCCCTAATGATA
+KF647919|Alabama|12_13|H1N1 GGCTCGAATCGACCGTGGGT GTCTTTCAACCAGAATCTGG AATATCAGATAGGATACATA TGCAGTGGGATTTTCGGAGA CAATCCACGCCCTAATGATA
+KF647931|Wisconsin|12_13|H1N1 GGCTCGAATCGACCGTGGGT GTCTTTCAACCAGAATCTGG AATATCAGATAGGATACATA TGCAGTGGGATTTTCGGAGA CAATCCACGCCCTAATGATA
+KF647932|Pennsylvania|12_13|H1N1 GGCTCGAATCGACCGTGGGT GTCTTTCAACCAGAATCTGG AATATCAGATAGGATACATA TGCAGTGGGGTTTTCGGAGA CAATCCACGCCCTAATGATA
+KF647958|Nebraska|12_13|H1N1 GGCTCGAATCGACCGTGGGT GTCTTTCAACCAGAATCTGG AATATCAGATAGGATACATA TGCAGTGGGGTTTTCGGAGA CAATCCACGCCCTAATGATA
+KF647971|Oklahoma|12_13|H1N1 GGCTCGAATCGACCGTGGGT GTCTTTCAACCAGAATCTGG AATATCAGATAGGATACATA TGCAGTGGGATTTTCGGAGA CAATCCACGCCCTAATGATA
+KF647902|Iowa|12_13|H1N1 GGCTCGAATCGACCGTGGGT GTCTTTCAATCAGAATCTGG AATATCAGATAGGATACATA TGCAGTGGGATTTTCGGAGA CAATCCACGCCCTAATGATA
+KF648002|Minnesota|12_13|H1N1 GGCTCGAATCGACCGTGGGT GTCTTTCAACCAGAATCTGG AATATCAGATAGGATACATR TGCAGTGGGATTTTCGGAGA CAATCCACGCCCTAATGATA
+KF648040|New_Jersey|12_13|H1N1 GGCTCGAATCGACCGTGGGT GTCTTTCAACCAGAATCTGG AATATCAGATAGGATACATA TGCAGTGGGGTTTTCGGAGA CAATCCACGCCCTAATGATA
+KF648101|Ohio|12_13|H1N1 GGCTCGAATCGACCGTGGGT GTCTTTCAACCAGAATCTGG AATATCAGATAGGATACATA TGCAGTGGGATTTTCGGAGA CAATCCACGCCCTAATGATA
+KF648260|Washington|12_13|H1N1 GGCTCGAATCGACCGTGGGT GTCTTTCAACCAGAATCTGG AATATCAGATAGGATACATA TGCAGTGGGATTTTCGGAGA CAATCCACGCCCTAATGATA
+CY170697|California|12_13|H1N1 GGCTCGAATCGACCGTGGGT GTCTTTCAACCAGAATCTGG AATATCAGATAGGATACATA TGCAGTGGGATTTTCGGAGA CAATCCACGCCCTAATGATA
+CY168881|Massachusetts|12_13|H1N1 GGCTCGAATCGACCGTGGGT GTCTTTCAACCAGAATCTGG AATATCAGATAGGATACATA TGCAGTGGGATTTTCGGAGA CAATCCACGCCCTAATGATA
+CY171161|Illinois|12_13|H1N1 GGCTCGAATCGACCGTGGGT GTCTTTCAACCAGAATCTGG AATATCAGATAGGATACATA TGCAGTGGGATTTTCGGAGA CAATCCACGCCCTAATGATA
+
+CY130177|South_Carolina|12_13|H1N1 AGACAGGCAGTTGTGGTCCA GTATCGTCTAATGGAGCAAA TGGAGTAAAAGGATTTTCAT TCAAATACGGCAATGGTGTT TGGATAGGGAGAACTAAAAG
+KF647978|Idaho|12_13|H1N1 AGACAGGCAGTTGTGGTCCA GTATCGTCTAATGGAGCAAA TGGAGTAAAAGGATTTTCAT TCAAATACGGCAATGGTGTT TGGATAGGGAGAACTAAAAG
+KF648268|New_Mexico|12_13|H1N1 AGACAGGCAGTTGTGGTCCA GTATCGTCTAATGGAGCAAA TGGAGTAAAAGGATTTTCAT TCAAATACGGCAATGGTGTT TGGATAGGGAGAACTAAAAG
+KF648064|North_Carolina|12_13|H1N1 AGACAGGCAGTTGTGGTCCA GTATCGTCTAATGGAGCAAA TGGAGTAAAAGGATTTTCAT TCAAATACGGCAATGGTGTT TGGATAGGGAGAACTAAAAG
+KF647995|New_Hampshire|12_13|H1N1 AGACAGGCAGTTGTGGTCCA GTATCGTCTAATGGAGCAAA TGGAGTAAAAGGATTTTCAT TCAAATACGGCAATGGTGTT TGGATAGGGAGAACTAAAAG
+KF648000|Colorado|12_13|H1N1 AGACAGGCAGTTGTGGTCCA GTATCGTCTAATGGAGCAAA TGGAGTAAAAGGATTTTCAT TCAAATACGGCAATGGTGTT TGGATAGGGAGAACTAAAAG
+KF648133|Florida|12_13|H1N1 AGACAGGCAGTTGTGGTCCA GTATCGTCTAATGGAGCAAA TGGAGTAAAAGGATTTTCAT TCAAATACGGCAATGGTGTT TGGATAGGGAGAACTAAAAG
+KF648145|Georgia|12_13|H1N1 AGACAGGCAGTTGTGGTCCA GTATCGTCTAATGGAGCAAA TGGAGTAAAAGGATTTTCAT TCAAATACGGCAATGGTGTT TGGATAGGGAGAACTAAAAG
+KF648155|Vermont|12_13|H1N1 AGACAGGCAGTTGTGGTCCA GTATCGTCTAATGGAGCAAA TGGAGTAAAAGGATTTTCAT TCAAATACGGCAATGGTGTT TGGATAGGGAGAACTAAAAG
+KF648158|Utah|12_13|H1N1 AGACAGGCAGTTGTGGTCCA GTATCGTCTAATGGAGCAAA TGGAGTAAAAGGATTTTCAT TCAAATACGGCAATGGTGTT TGGATAGGGAGAACTAAAAG
+KF648159|Louisiana|12_13|H1N1 AGACAGGCAGTTGTGGTCCA GTATCGTCTAATGGAGCAAA TGGAGTAAAAGGATTTTCAT TCAAATACGGCAATGGTGTT TGGATAGGGAGAACTAAAAG
+KF648008|Rhode_Island|12_13|H1N1 AGACAGGCAGTTGTGGTCCA GTATCGTCTAATGGAGCAAA TGGAGTAAAAGGATTTTCAT TCAAATACGGCAATGGTGTT TGGATAGGGAGAACTAAAAG
+KF648011|New_York|12_13|H1N1 AGACAGGCAGTTGTGGTCCA GTATCGTCTAATGGAGCAAA TGGAGTAAAAGGATTTTCAT TCAAATACGGCAATGGTGTT TGGATAGGGAGAACTAAAAG
+KF647921|Maryland|12_13|H1N1 AGACAGGCAGTTGTGGTCCA GTATCGTCTAATGGAGCAAA TGGAGTAAAAGGATTTTCAT TCAAATACGGCAATGGTGTT TGGATAGGGAGAACTAAAAG
+KF647926|Missouri|12_13|H1N1 AGACAGGCAGTTGTGGTCCA GTATCGTCTAATGGAGCAAA TGGAGTAAAAGGATTTTCAT TCAAATACGGCAATGGTGTT TGGATAGGGAGAACTAAAAG
+KF647928|Texas|12_13|H1N1 AGACAGGCAGTTGTGGTCCA GTGTCGTCTAATGGAGCAAA TGGAGTAAAAGGATTTTCAT TCAAATACGGCAATGGTGTT TGGATAGGGAGAACTAAAAG
+KF647936|Wyoming|12_13|H1N1 AGACAGGCAGTTGTGGTCCA GTATCGTCTAATGGAGCAAA TGGAGTAAAAGGATTTTCAT TCAAATACGGCAATGGTGTT TGGATAGGGAGAACTAAAAG
+KF648197|Indiana|12_13|H1N1 AGACAGGCAGTTGTGGTCCA GTATCGTCTAATGGAGCAAA TGGAGTAAAAGGATTTTCAT TCAAATACGGCAATGGTGTT TGGATAGGGAGAACTAAAAG
+KF648228|Mississippi|12_13|H1N1 AGACAGGCAGTTGTGGTCCA GTATCGTCTAATGGAGCAAA TGGAGTAAAAGGATTTTCAT TCAAATACGGCAATGGTGTT TGGATAGGGAGAACTAAAAG
+KF648239|Tennessee|12_13|H1N1 AGACAGGTAGTTGTGGTCCA GTATCGTCTAATGGAGCAAA TGGAGTAAAAGGATTTTCAT TCAAATACGGCAATGGTGTT TGGATAGGGAGAACTAAAAG
+KF648034|Arizona|12_13|H1N1 AGACAGGCAGTTGTGGTCCA GTATCGTCTAATGGAGCAAA TGGAGTAAAAGGATTCTCAT TCAAATACGGCAATGGTGTT TGGATAGGGAGAACTAAAAG
+KF648037|Kentucky|12_13|H1N1 AGACAGGCAGTTGTGGTCCA GTATCGTCTAATGGAGCAAA TGGAGTAAAAGGATTTTCAT TCAAATACGGCAATGGTGTT TGGATAGGGAGAACTAAAAG
+KF648038|Kansas|12_13|H1N1 AGACAGGCAGTTGTGGTCCA GTATCGTCTAATGGAGCAAA TGGAGTAAAAGGATTTTCAT TCAAATACGGCAATGGTGTT TGGATAGGGAGAACTAAAAG
+KF647919|Alabama|12_13|H1N1 AGACAGGCAGTTGTGGTCCA GTATCGTCTAATGGAGCAAA TGGAGTAAAAGGATTCTCAT TCAAATACGGCAATGGTGTT TGGATAGGGAGAACTAAAAG
+KF647931|Wisconsin|12_13|H1N1 AGACAGGCAGTTGTGGTCCA GTATCGTCTAATGGAGCAAA TGGAGTAAAAGGATTTTCAT TCAAATACGGCAATGGTGTT TGGATAGGGAGAACTAAAAG
+KF647932|Pennsylvania|12_13|H1N1 AGACAGGCAGTTGTGGTCCA GTATCGTCTAATGGAGCAAA TGGAGTAAAAGGATTTTCAT TCAAATACGGCAATGGTGTT TGGATAGGGAGAACTAAAAG
+KF647958|Nebraska|12_13|H1N1 AGACAGGCAGTTGTGGTCCA GTATCGTCTAATGGAGCAAA TGGAGTAAAAGGATTTTCAT TCAAATACGGCAATGGTGTT TGGATAGGGAGAACTAAAAG
+KF647971|Oklahoma|12_13|H1N1 AGACAGGCAGTTGTGGTCCA GTATCGTCTAATGGAGCAAA TGGAGTAAAAGGATTTTCAT TCAAATACGGCAATGGTGTT TGGATAGGGAGAACTAAAAG
+KF647902|Iowa|12_13|H1N1 AGACAGGCAGTTGTGGTCCA GTATCGTCTAATGGAGCAAA TGGAGTAAAAGGATTTTCAT TCAAATACGGCAATGGTGTT TGGATAGGGAGAACTAAAAG
+KF648002|Minnesota|12_13|H1N1 AGACAGGCAGTTGTGGTCCA GTATCGTCTAATGGAGCAAA TGGAGTAAAAGGATTTTCAT TCAAATACGGCAATGGTGTT TGGATAGGGAGAACTAAAAG
+KF648040|New_Jersey|12_13|H1N1 AGACAGGCAGTTGTGGTCCA GTATCGTCTAATGGAGCAAA TGGAGTAAAAGGATTTTCAT TCAAATACGGCAATGGTGTT TGGATAGGGAGAACTAAAAG
+KF648101|Ohio|12_13|H1N1 AGACAGGCAGTTGTGGTCCA GTATCGTCTAATGGAGCAAA TGGAGTAAAAGGATTTTCAT TCAAATACGGCAATGGTGTT TGGATAGGGAGAACTAAAAG
+KF648260|Washington|12_13|H1N1 AGACAGGCAGTTGTGGTCCA GTATCGTCTAATGGAGCAAA TGGAGTAAAAGGATTTTCAT TCAAATACGGCAATGGTGTT TGGATAGGGAGAACTAAAAG
+CY170697|California|12_13|H1N1 AGACAGGCAGTTGTGGTCCA GTATCGTCTAATGGAGCAAA TGGAGTAAAAGGATTTTCAT TCAAATACGGCAATGGTGTT TGGATAGGGAGAACTAAAAG
+CY168881|Massachusetts|12_13|H1N1 AGACAGGCAGTTGTGGTCCA GTATCGTCTAATGGAGCAAA TGGAGTAAAAGGATTTTCAT TCAAATACGGCAATGGTGTT TGGATAGGGAGAACTAAAAG
+CY171161|Illinois|12_13|H1N1 AGACAGGCAGTTGTGGTCCA GTATCGTCTAATGGAGCAAA TGGAGTAAAAGGATTTTCAT TCAAATACGGCAATGGTGTT TGGATAGGGAGAACTAAAAG
+
+CY130177|South_Carolina|12_13|H1N1 CATTAGTTCAAGAAAAGGTT TTGAGATGATTTGGGATCCA AACGGATGGACTGGGACAGA CAATAACTTCTCAATAAAGC AAGATATCGTAGGAATAAAT
+KF647978|Idaho|12_13|H1N1 CATTAGTTCAAGAAAAGGTT TTGAGATGATTTGGGATCCA AATGGATGGACTGGGACAGA CAATAACTTCTCAATAAAGC AAGATATCGTAGGAATAAAT
+KF648268|New_Mexico|12_13|H1N1 CATTAGTTCAAGAAAAGGTT TTGAGATGATTTGGGATCCA AATGGATGGACTGGGACAGA CAATAACTTCTCAATAAAGC AAGATATCGTAGGAATAAAT
+KF648064|North_Carolina|12_13|H1N1 CATTAGTTCAAGAAAAGGTT TTGAGATGATTTGGGATCCA AATGGATGGACTGGGACAGA CAATAACTTCTCAATAAAGC AAGATATCGTAGGAATAAAT
+KF647995|New_Hampshire|12_13|H1N1 CATTAGTTCAAGAAAAGGTT TTGAGATGATTTGGGATCCA AATGGATGGACTGGGACAGA CAATAACTTCTCAATAAAGC AAGATATCGTAGGAATAAAT
+KF648000|Colorado|12_13|H1N1 CATTAGTTCAAGAAAAGGTT TTGAGATGATTTGGGATCCA AATGGATGGACTGGGACAGA CAATAACTTCTCAATAAAGC AAGATATCGTAGGAATAAAT
+KF648133|Florida|12_13|H1N1 CATTAGTTCAAGAAAAGGTT TTGAGATGATTTGGGATCCA AATGGATGGACTGGGACAGA CAATAACTTCTCAATAAAGC AAGATATCGTAGGAATAAAT
+KF648145|Georgia|12_13|H1N1 CATTAGTTCAAGAAAAGGTT TTGAGATGATTTGGGATCCA AATGGATGGACTGGGACAGA CAATAACTTCTCAATAAAGC AAGATATCGTAGGAATAAAT
+KF648155|Vermont|12_13|H1N1 CATTAGTTCAAGAAAAGGTT TTGAGATGATTTGGGATCCA AATGGATGGACTGGGACAGA CAATAACTTCTCAATAAAGC AAGATATCGTAGGAATAAAT
+KF648158|Utah|12_13|H1N1 CATTAGTTCAAGAAAAGGTT TTGAGATGATTTGGGATCCA AATGGATGGACTGGGACAGA CAATAACTTCTCAATAAAGC AAGATATCGTAGGAATAAAT
+KF648159|Louisiana|12_13|H1N1 CATTAGTTCAAGAAAAGGTT TTGAGATGATTTGGGATCCG AATGGATGGACTGGGACAGA CAATAACTTCTCAATAAAGC AAGATATCGTAGGAATAAAT
+KF648008|Rhode_Island|12_13|H1N1 CATTAGTTCAAGAAAAGGTT TTGAGATGATTTGGGATCCA AATGGATGGACTGGGACAGA CAATAACTTCTCAATAAAGC AAGATATCGTAGGAATAAAT
+KF648011|New_York|12_13|H1N1 CATTAGTTCAAGAAAAGGTT TTGAGATGATTTGGGATCCA AATGGATGGACTGGGACAGA CAATAACTTCTCAATAAAGC AAGATATCGTAGGAATAAAT
+KF647921|Maryland|12_13|H1N1 CATTAGTTCAAGAAAAGGTT TTGAGATGATTTGGGATCCA AATGGATGGACTGGGACAGA CAATAACTTCTCAATAAAGC AAGATATCGTAGGAATAAAT
+KF647926|Missouri|12_13|H1N1 CATTAGTTCAAGAAAAGGTT TTGAGATGATTTGGGATCCA AATGGATGGACTGGGACAGA CAATAACTTCTCAATAAAGC AAGATATCGTAGGAATAAAT
+KF647928|Texas|12_13|H1N1 CATTAGTTCAAGAAAAGGTT TTGAGATGATTTGGGATCCA AACGGATGGACTGGGACAGA CAATAGCTTCTCAATAAAGC AAGATATCGTAGGAATAAAT
+KF647936|Wyoming|12_13|H1N1 CATTAGTTCAAGAAAAGGTT TTGAGATGATTTGGGATCCA AACGGATGGACTGGGACAGA CAATAACTTCTCAATAAAGC AAGATATCGTAGGAATAAAT
+KF648197|Indiana|12_13|H1N1 CATTAGTTCAAGAAAAGGTT TTGAGATGATTTGGGATCCA AATGGATGGACTGGGACAGA CAATAACTTCTCAATAAAGC AAGATATCGTAGGAATAAAT
+KF648228|Mississippi|12_13|H1N1 CATTAGTTCAAGAAAAGGTT TTGAGATGATTTGGGATCCA AATGGATGGACTGGGACAGA CAATAACTTCTCAATAAAGC AAGATATCGTAGGAATGAAT
+KF648239|Tennessee|12_13|H1N1 CATTAGTTCAAGAAAAGGTT TTGAGATGATTTGGGATCCA AATGGATGGACTGGGACAGA CAATAACTTCTCAATAAAGC AAGATATCGTAGGAATAAAT
+KF648034|Arizona|12_13|H1N1 CATTAGTTCAAGAAAAGGTT TTGAGATGATTTGGGATCCA AATGGATGGACTGGGACAGA CAATAACTTCTCAATAAAGC AAGATATCGTAGGAATAAAT
+KF648037|Kentucky|12_13|H1N1 CATTAGTTCAAGAAAAGGTT TTGAGATGATTTGGGATCCA AATGGATGGACTGGGACAGA CAATAACTTCTCAATAAAGC AAGATATCGTAGGAATAAAT
+KF648038|Kansas|12_13|H1N1 CATTGGTTCAAGAAAAGGTT TTGAGATGATTTGGGATCCA AATGGATGGACTGGGACAGA CAATAACTTCTCAATAAAGC AAGATATCGTAGGAATAAAT
+KF647919|Alabama|12_13|H1N1 CATTAGTTCAAGAAAAGGTT TTGAGATGATTTGGGATCCA AATGGATGGACTGGGACAGA CAATAACTTCTCAATAAAGC AAGATATCGTAGGAATAAAT
+KF647931|Wisconsin|12_13|H1N1 CATTAGTTCAAGAAAAGGTT TTGAGATGATTTGGGATCCA AATGGATGGACTGGGACAGA CAATAACTTCTCAATAAAGC AAGATATCGTAGGAATAAAT
+KF647932|Pennsylvania|12_13|H1N1 CATTAGTTCAAGAAAAGGTT TTGAGATGATTTGGGATCCA AATGGATGGACTGGGACAGA CAATAACTTCTCAATAAAGC AAGATATCGTAGGAATAAAT
+KF647958|Nebraska|12_13|H1N1 CATTAGTTCAAGAAAAGGTT TTGAGATGATTTGGGATCCA AATGGATGGACTGGGACAGA CAATAACTTCTCAATAAAGC AAGATATCGTAGGAATAAAT
+KF647971|Oklahoma|12_13|H1N1 CATTAGTTCAAGAAAAGGTT TTGAGATGATTTGGGATCCA AATGGATGGACTGGGACAGA CAATAACTTCTCAATAAAGC AAGATATCGTAGGAATAAAT
+KF647902|Iowa|12_13|H1N1 CATTAGTTCAAGAAAAGGTT TTGAGATGATTTGGGATCCA AATGGATGGACTGGGACAGA CAATAACTTCTCAATAAAGC AAGATATCGTAGGAATAAAT
+KF648002|Minnesota|12_13|H1N1 CATTAGTTCAAGAAAAGGTT TTGAGATGATTTGGGATCCA AATGGATGGACTGGGACAGA CAATAACTTCTCAATAAAGC AAGATATCGTAGGAATAAAT
+KF648040|New_Jersey|12_13|H1N1 CATTAGTTCAAGAAAAGGTT TTGAGATGATTTGGGATCCG AATGGATGGACTGGGACAGA CAATAACTTCTCAATAAAGC AAGATATCGTAGGAATAAAT
+KF648101|Ohio|12_13|H1N1 CATTAGTTCAAGAAAAGGTT TTGAGATGATTTGGGATCCA AATGGATGGACTGGGACAGA CAATAACTTCTCAATAAAGC AAGATATCGTAGGAATAAAT
+KF648260|Washington|12_13|H1N1 CATTAGTTCAAGAAAAGGTT TTGAGATGATTTGGGATCCA AATGGATGGACTGGGACAGA CAATAACTTCTCAATAAAGC AAGATATCGTAGGAATAAAT
+CY170697|California|12_13|H1N1 CATTAGTTCAAGAAAAGGTT TTGAGATGATTTGGGATCCA AATGGATGGACTGGGACAGA CAATAACTTCTCAATAAAGC AAGATATCGTAGGAATAAAT
+CY168881|Massachusetts|12_13|H1N1 CATTAGTTCAAGAAAAGGTT TTGAGATGATTTGGGATCCA AATGGATGGACTGGGACAGA CAATAACTTCTCAATAAAGC AAGATATCGTAGGAATAAAT
+CY171161|Illinois|12_13|H1N1 CATTAGTTCAAGAAAAGGTT TTGAGATGATTTGGGATCCA AACGGATGGACTGGGACAGA CAATAACTTCTCAACAAAGC AAGATATCGTAGGAATAAAT
+
+CY130177|South_Carolina|12_13|H1N1 GAGTGGTCAGGATACAGCGG GAGTTTTGTTCAGCATCCAG AACTAACAGGGCTGGATTGT ATAAGACCTTGCTTCTGGGT TGAACTAATCAGAGGACGAC
+KF647978|Idaho|12_13|H1N1 GAGTGGACAGGATATAGCGG GAGTTTTGTTCAGCATCCAG AACTAACAGGGCTGGATTGT ATAAGACCTTGCTTCTGGGT TGAATTAATCAGAGGGCGAC
+KF648268|New_Mexico|12_13|H1N1 GAGTGGTCAGGATATAGCGG GAGTTTTGTTCAGCATCCAG AACTAACAGGGCTGGATTGT ATAAGACCTTGCTTCTGGGT TGAACTAATCAGAGGGCGAC
+KF648064|North_Carolina|12_13|H1N1 GAGTGGTCAGGATATAGCGG GAGTTTTGTTCAGCATCCAG AACTAACAGGGCTGGATTGT ATAAGACCTTGCTTCTGGGT TGAACTAATCAGAGGGCGAC
+KF647995|New_Hampshire|12_13|H1N1 GAGTGGTCAGGATATAGCGG GAGTTTTGTTCAGCATCCAG AACTAACAGGGCTGGATTGT ATAAGACCTTGCTTCTGGGT TGAACTAATCAGAGGGCGAC
+KF648000|Colorado|12_13|H1N1 GAGTGGTCAGGATATAGCGG GAGTTTTGTTCAGCATCCAG AACTAACAGGGCTGGATTGT ATAAGACCTTGCTTCTGGGT TGAACTAATCAGAGGGCGAC
+KF648133|Florida|12_13|H1N1 GAGTGGTCAGGATATAGCGG GAGTTTTGTTCAGCATCCAG AACTAACAGGGCTGGATTGT ATAAGACCTTGCTTCTGGGT TGAACTAATCAGAGGGCGAC
+KF648145|Georgia|12_13|H1N1 GAGTGGTCAGGATATAGCGG GAGTTTTGTTCAGCATCCAG AACTAACAGGGCTGGATTGT ATAAGACCTTGCTTCTGGGT TGAACTAATCAGAGGGCGAC
+KF648155|Vermont|12_13|H1N1 GAATGGTCAGGATATAGCGG GAGTTTTGTTCAGCATCCAG AACTAACAGGGCTGGATTGT ATAAGACCTTGCTTCTGGGT TGAACTAATCAGAGGGCGAC
+KF648158|Utah|12_13|H1N1 GAGTGGTCAGGATATAGCGG GAGTTTTGTTCAGCATCCAG AACTAACAGGGCTGGATTGT ATAAGACCTTGCTTCTGGGT TGAACTAATCAGAGGGCGAC
+KF648159|Louisiana|12_13|H1N1 GAGTGGTCAGGATATAGCGG GAGTTTTGTTCAGCATCCAG AACTAACAGGGCTGGATTGT ATAAGACCTTGCTTCTGGGT TGAACTAATCAGAGGGCGAC
+KF648008|Rhode_Island|12_13|H1N1 GAGTGGTCAGGATATAGCGG GAGTTTTGTTCAGCATCCAG AACTAACAGGGCTGGATTGT ATAAGACCTTGCTTCTGGGT TGAACTAATCAGAGGGCGAC
+KF648011|New_York|12_13|H1N1 GAGTGGTCAGGATATAGCGG GAGTTTTGTTCAGCATCCAG AACTAACAGGGCTGGATTGT ATAAGACCTTGCTTCTGGGT TGAACTAATCAGAGGGCGAC
+KF647921|Maryland|12_13|H1N1 GAGTGGTCAGGATATAGCGG GAGTTTTGTTCAGCATCCAG AACTAACAGGGCTGGATTGT ATAAGACCTTGCTTCTGGGT TGAACTAATCAGAGGGCGAC
+KF647926|Missouri|12_13|H1N1 GAGTGGTCAGGATATAGCGG GAGTTTTGTTCAGCATCCAG AACTAACAGGGCTGGATTGT ATAAGACCTTGCTTCTGGGT TGAACTAATCAGAGGGCGAC
+KF647928|Texas|12_13|H1N1 GAGTGGTCAGGATATAGCGG GAGTTTTGTTCAGCATCCAG AACTAACAGGGCTGGACTGT ATAAGACCTTGTTTCTGGGT TGAACTAATCAGAGGGCGAC
+KF647936|Wyoming|12_13|H1N1 GAGTGGTCAGGATACAGCGG GAGTTTTGTTCAGCATCCAG AACTAACAGGGCTGGATTGT ATAAGACCTTGCTTCTGGGT TGAACTAATCAGAGGACGAC
+KF648197|Indiana|12_13|H1N1 GAGTGGTCAGGATATAGCGG GAGTTTTGTTCAGCATCCAG AACTAACAGGGCTGGATTGT ATAAGACCTTGCTTCTGGGT TGAACTAATCAGAGGGCGAC
+KF648228|Mississippi|12_13|H1N1 GAGTGGTCAGGATATAGCGG GAGTTTTGTTCAGCATCCAG AACTAACAGGGCTGGATTGT ATAAGACCTTGCTTCTGGGT TGAACTAATCAGAGGGCGAC
+KF648239|Tennessee|12_13|H1N1 GAGTGGTCAGGATATAGCGG GAGTTTTGTTCAGCATCCAG AACTAACAGGGCTGGATTGT ATAAGACCTTGCTTCTGGGT TGAACTAATCAGAGGGCGAC
+KF648034|Arizona|12_13|H1N1 GAGTGGTCAGGATATAGCGG GAGTTTTGTTCAGCATCCAG AACTAACAGGGCTGGATTGT ATAAGACCTTGCTTCTGGGT TGAACTAATCAGAGGGCGAC
+KF648037|Kentucky|12_13|H1N1 GAGTGGTCAGGATATAGCGG GAGTTTTGTTCAGCATCCAG AACTAACAGGGCTGGATTGT ATAAGACCTTGCTTCTGGGT TGAACTAATCAGAGGGCGAC
+KF648038|Kansas|12_13|H1N1 GAGTGGTCAGGATATAGCGG GAGTTTTGTTCAGCATCCAG AACTAACAGGGCTGGATTGT ATAAGACCTTGCTTCTGGGT TGAACTAATCAGAGGGCGAC
+KF647919|Alabama|12_13|H1N1 GAGTGGTCAGGATATAGCGG GAGTTTTGTTCAGCATCCAG AACTAACAGGGCTGGATTGT ATAAGACCTTGCTTCTGGGT TGAACTAATCAGAGGGCGAC
+KF647931|Wisconsin|12_13|H1N1 GAGTGGTCAGGATATAGCGG GAGTTTTGTTCAGCATCCAG AACTAACAGGGCTGGATTGT ATAAGACCTTGCTTCTGGGT TGAATTAATCAGAGGGCGAC
+KF647932|Pennsylvania|12_13|H1N1 GAGTGGTCAGGATATAGCGG GAGTTTTGTTCAGCATCCAG AACTAACAGGGCTGGATTGT ATAAGACCTTGCTTCTGGGT TGAACTAATCAGAGGGCGAC
+KF647958|Nebraska|12_13|H1N1 GAGTGGTCAGGATATAGCGG GAGTTTTGTTCAGCATCCAG AACTAACAGGGCTGGATTGT ATAAGACCTTGCTTCTGGGT TGAACTAATCAGAGGGCGAC
+KF647971|Oklahoma|12_13|H1N1 GAGTGGTCAGGATATAGCGG GAGTTTTGTTCAGCATCCAG AACTAACAGGGCTGGATTGT ATAAGACCTTGCTTCTGGGT TGAACTAATCAGAGGGCGAC
+KF647902|Iowa|12_13|H1N1 GAGTGGTCAGGATATAGCGG GAGTTTTGTTCAGCATCCAG AACTAACAGGGCTGGATTGT ATAAGACCTTGCTTCTGGGT TGAACTAATCAGAGGGCGAC
+KF648002|Minnesota|12_13|H1N1 GAGTGGTCAGGATATAGCGG GAGTTTTGTTCAGCATCCAG AACTAACAGGGCTGGATTGT ATAAGACCTTGCTTCTGGGT TGAACTAATCAGAGGGCGAC
+KF648040|New_Jersey|12_13|H1N1 GAGTGGTCAGGATATAGCGG GAGTTTTGTTCAGCATCCAG AACTAACAGGGCTGGATTGT ATAAGACCTTGCTTCTGGGT TGAACTAATCAGAGGGCGAC
+KF648101|Ohio|12_13|H1N1 GAGTGGTCAGGATATAGCGG GAGTTTTGTTCAGCATCCAG AACTAACAGGGCTGGATTGT ATAAGACCTTGCTTCTGGGT TGAACTAATCAGAGGGCGAC
+KF648260|Washington|12_13|H1N1 GAGTGGTCAGGATATAGCGG GAGTTTTGTTCAGCATCCAG AACTAACAGGGCTGGATTGT ATAAGACCTTGCTTCTGGGT TGAACTAATCAGAGGGCGAC
+CY170697|California|12_13|H1N1 GAGTGGTCAGGATATAGCGG GAGTTTTGTTCAGCATCCAG AACTAACAGGGCTGGATTGT ATAAGACCTTGCTTCTGGGT TGAACTAATCAGAGGGCGAC
+CY168881|Massachusetts|12_13|H1N1 GAGTGGTCAGGATATAGCGG GAGTTTTGTTCAGCATCCAG AACTAACAGGGCTGGATTGT ATAAGACCTTGCTTCTGGGT TGAACTAATCAGAGGGCGAC
+CY171161|Illinois|12_13|H1N1 GAGTGGTCAGGATATAGCGG GAGTTTTGTTCAGCATCCAG AACTAACAGGGCTGGATTGT ATAAGACCTTGCTTCTGGGT TGAACTAATCAGAGGGAGAC
+
+CY130177|South_Carolina|12_13|H1N1 CCAAAGAGAACACAATCTGG ACTAGCGGGAGCAGCATATC CTTTTGTGGTGTAAACAGTG ACACTGTGGGTTGGTCTTGG CCAGACGGTGCTGAGTTGCC
+KF647978|Idaho|12_13|H1N1 CCAAAGAGAACACAATCTGG ACTAGTGGGAGCAGCATATC CTTTTGTGGTGTAAACAGTG ACACTGTGGGTTGGTCTTGG CCAGACGGTGCTGAGTTGCC
+KF648268|New_Mexico|12_13|H1N1 CCAAAGAGAACACAATCTGG ACTAGCGGGAGCAGCATATC CTTTTGTGGTGTAAACAGTG ACACTGTGGGTTGGTCTTGG CCAGACGGTGCTGAGTTGCC
+KF648064|North_Carolina|12_13|H1N1 CCAAAGAGAACACAATCTGG ACTAGCGGGAGCAGCATATC CTTTTGTGGTGTAAACAGTG ACACTGTGGGTTGGTCTTGG CCAGACGGTGCTGAGTTGCC
+KF647995|New_Hampshire|12_13|H1N1 CCAAAGAGAACACAATCTGG ACTAGCGGGAGCAGCATATC CTTTTGTGGTGTAAACAGTG ACACTGTGGGTTGGTCTTGG CCAGACGGTGCTGAGTTGCC
+KF648000|Colorado|12_13|H1N1 CCAAAGAGAACACAATCTGG ACTAGCGGGAGCAGCATATC CTTTTGTGGTGTAAACAGTG ACACTGTGGGTTGGTCTTGG CCAGACGGTGCTGAGTTGCC
+KF648133|Florida|12_13|H1N1 CCAAAGAGAACACAATCTGG ACTAGCGGGAGCAGCATATC CTTTTGTGGTGTAAACAGTG ACACTGTGGGTTGGTCTTGG CCAGACGGTGCTGAGTTGCC
+KF648145|Georgia|12_13|H1N1 CCAAAGAGAACACAATCTGG ACTAGCGGGAGCAGCATATC CTTTTGTGGTGTAAACAGTG ACACTGTGGGTTGGTCTTGG CCAGACGGTGCTGAGTTGCC
+KF648155|Vermont|12_13|H1N1 CCAAAGAGAACACAATCTGG ACTAGCGGGAGCAGCATATC CTTTTGTGGTGTAAACAGTG ACACTGTGGGTTGGTCTTGG CCAGACGGTGCTGAGTTGCC
+KF648158|Utah|12_13|H1N1 CCAAAGAGAACACAATCTGG ACTAGTGGGAGCAGCATATC CTTTTGTGGTGTAAACAGTG ACACTGTGGGTTGGTCTTGG CCAGACGGTGCTGAGTTGCC
+KF648159|Louisiana|12_13|H1N1 CCGAAGAGAACACAATCTGG ACTAGCGGGAGCAGCATATC CTTTTGTGGTGTAAACAGTG ACACTGTGGGTTGGTCTTGG CCAGACGGTGCTGAGTTGCC
+KF648008|Rhode_Island|12_13|H1N1 CCAAAGAGAACACAATCTGG ACTAGTGGGAGCAGCATATC CTTTTGTGGTGTAAACAGTG ACACTGTGGGTTGGTCTTGG CCAGACGGTGCTGAGTTGCC
+KF648011|New_York|12_13|H1N1 CCAAAGAGAACACAATCTGG ACTAGTGGGAGCAGCATATC CTTTTGTGGTGTAAACAGTG ACACTGTGGGTTGGTCTTGG CCAGACGGTGCTGAGTTGCC
+KF647921|Maryland|12_13|H1N1 CCAAAGAGAACACAATCTGG ACTAGCGGGAGCAGCATATC CTTTTGTGGTGTAAACAGTG ACACTGTGGGTTGGTCTTGG CCAGACGGTGCTGAGTTGCC
+KF647926|Missouri|12_13|H1N1 CCAAAGAGAACACAATCTGG ACTAGCGGGAGCAGCATATC CTTTTGTGGTGTAAACAGTG ACACTGTGGGTTGGTCTTGG CCAGACGGTGCTGAGTTGCC
+KF647928|Texas|12_13|H1N1 CCAAAGAGAACACAATCTGG ACTAGTGGGAGCAGCATATC CTTTTGTGGTGTAAACAGTG GCACTGTGGGTTGGTCTTGG CCAGACGGTGCTGAGTTGCC
+KF647936|Wyoming|12_13|H1N1 CCAAAGAGAACACAATCTGG ACTAGCGGGAGCAGCATATC TTTTTGTGGTGTAAACAGTG ACACTGTGGGTTGGTCTTGG CCAGACGGTGCTGAGTTGCC
+KF648197|Indiana|12_13|H1N1 CCAAAGAGAACACAATCTGG ACTAGCGGGAGCAGCATATC CTTTTGTGGTGTAAACAGTG ACACTGTGGGTTGGTCTTGG CCAGACGGTGCTGAGTTGCC
+KF648228|Mississippi|12_13|H1N1 CCAAAGAGAACACAATCTGG ACTAGCGGGAGCAGCATATC CTTTTGTGGTGTAAACAGTG ACACTGTGGGTTGGTCTTGG CCAGACGGTGCTGAGTTGCC
+KF648239|Tennessee|12_13|H1N1 CCAAAGAGAACACAATCTGG ACTAGCGGGAGCAGCATATC CTTTTGTGGTGTAAACAGTG ACACTGTGGGTTGGTCTTGG CCAGACGGTGCTGAGTTGCC
+KF648034|Arizona|12_13|H1N1 CCAAAGAGAACACAATCTGG ACTAGCGGGAGCAGCATATC CTTTTGTGGTGTAAACAGTG ACACTGTGGGTTGGTCTTGG CCAGACGGTGCTGAGTTGCC
+KF648037|Kentucky|12_13|H1N1 CCAAAGAGAACACAATCTGG ACTAGCGGGAGCAGCATATC CTTTTGTGGTGTAAACAGTG ACACTGTGGGTTGGTCTTGG CCAGACGGTGCTGAGTTGCC
+KF648038|Kansas|12_13|H1N1 CCAAAGAGAACACAATCTGG ACTAGCGGGAGCAGCATATC CTTTTGTGGTGTAAACAGTG ACACTGTGGGTTGGTCTTGG CCAGACGGTGCTGAGTTGCC
+KF647919|Alabama|12_13|H1N1 CCAAAGAGAACACAATCTGG ACTAGCGGGAGCAGCATATC CTTTTGTGGTGTAAACAGTG ACACTGTGGGTTGGTCTTGG CCAGACGGTGCTGAGTTGCC
+KF647931|Wisconsin|12_13|H1N1 CCAAAGAGAACACAATCTGG ACTAGTGGGAGCAGCATATC CTTTTGTGGTGTAAACAGTG ACACTGTGGGTTGGTCTTGG CCAGACGGTGCTGAGTTGCC
+KF647932|Pennsylvania|12_13|H1N1 CCAAAGAGAACACAATCTGG ACTAGCGGGAGCAGCATATC CTTTTGTGGTGTAAACAGTG ACACTGTGGGTTGGTCTTGG CCAGACGGTGCTGAGTTGCC
+KF647958|Nebraska|12_13|H1N1 CCAAAGAGAACACAATCTGG ACTAGCGGGAGCAGCATATC CTTTTGTGGTGTAAACAGTG ACACTGTGGGTTGGTCCTGG CCAGACGGTGCTGAGTTGCC
+KF647971|Oklahoma|12_13|H1N1 CCAAAGAGAACACAATCTGG ACTAGTGGGAGCAGCATATC CTTTTGTGGTGTAAACAGTG ACACTGTGGGTTGGTCTTGG CCAGACGGTGCTGAGTTGCC
+KF647902|Iowa|12_13|H1N1 CCAAAGAGAACACAATCTGG ACTAGCGGGAGCAGCATATC CTTTTGTGGTGTAAACAGTG ACACTGTGGGTTGGTCTTGG CCAGACGGTGCTGAGTTGCC
+KF648002|Minnesota|12_13|H1N1 CCAAAGAGAACACAATCTGG ACTAGCGGGAGCAGCATATC CTTTTGTGGTGTAAACAGTG ACACTGTGGGTTGGTCTTGG CCAGACGGTGCTGAGTTGCC
+KF648040|New_Jersey|12_13|H1N1 CCGAAGAGAACACAATCTGG ACTAGCGGGAGCAGCATATC CTTTTGTGGTGTAAACAGTG ACACTGTTGGTTGGTCTTGG CCAGACGGTGCTGAGTTGCC
+KF648101|Ohio|12_13|H1N1 CCAAAGAGAACACAATCTGG ACTAGTGGGAGCAGCATATC CTTTTGTGGTGTAAACAGTG ACACTGTGGGTTGGTCTTGG CCAGACGGTGCTGAGTTGCC
+KF648260|Washington|12_13|H1N1 CCAAAGAGAACACAATCTGG ACTAGCGGGAGCAGCATATC CTTTTGTGGTGTAAACAGTG ACACTGTGGGTTGGTCTTGG CCAGACGGTGCTGAGTTGCC
+CY170697|California|12_13|H1N1 CCAAAGAGAACACAATCTGG ACTAGTGGGAGCAGCATATC CTTTTGTGGTGTAAACAGTG ACACTGTGGGTTGGTCTTGG CCAGACGGTGCTGAGTTGCC
+CY168881|Massachusetts|12_13|H1N1 CCAAAGAGAACACAATCTGG ACTAGTGGGAGCAGCATATC CTTTTGTGGTGTAAACAGTG ACACTGTGGGTTGGTCTTGG CCAGACGGTGCTGAGTTGCC
+CY171161|Illinois|12_13|H1N1 CCAAAGAGAACACAATCTGG ACTAGCGGGAGCAGCATATC CTTTTGTGGTGTAAACAGTG ACACTGTGGGTTGGTCTTGG CCAGACGGTGCTGAGTTGCC
+
+CY130177|South_Carolina|12_13|H1N1 ATTTACCATTGACAAGTAA- --------------
+KF647978|Idaho|12_13|H1N1 ATTTACCATTGACAAGTAA- --------------
+KF648268|New_Mexico|12_13|H1N1 ATTTACCATTGACAAGTAA- --------------
+KF648064|North_Carolina|12_13|H1N1 ATTTACCATTGACAAGTAA- --------------
+KF647995|New_Hampshire|12_13|H1N1 ATTTACCATTGACAAGTAA- --------------
+KF648000|Colorado|12_13|H1N1 ATTTGCCATTGACAAGTAA- --------------
+KF648133|Florida|12_13|H1N1 ATTTACCATTGACAAGTAA- --------------
+KF648145|Georgia|12_13|H1N1 ATTTACCATTGACAAGTAA- --------------
+KF648155|Vermont|12_13|H1N1 ATTTACCATTGACAAGTAA- --------------
+KF648158|Utah|12_13|H1N1 ATTTACCATTGACAAGTAA- --------------
+KF648159|Louisiana|12_13|H1N1 ATTTACCATTGACAAGTAA- --------------
+KF648008|Rhode_Island|12_13|H1N1 ATTTACCATTGACAAGTAA- --------------
+KF648011|New_York|12_13|H1N1 ATTTACCATTGACAAGTAA- --------------
+KF647921|Maryland|12_13|H1N1 ATTTACCATTGACAAGTAA- --------------
+KF647926|Missouri|12_13|H1N1 ATTTACCATTGACAAGTAA- --------------
+KF647928|Texas|12_13|H1N1 ATTTACCATTGACAAGTAA- --------------
+KF647936|Wyoming|12_13|H1N1 ATTTATCATTGACAAGTAA- --------------
+KF648197|Indiana|12_13|H1N1 ATTTACCATTGACAAGTAA- --------------
+KF648228|Mississippi|12_13|H1N1 ATTTACCATTGACAAGTAA- --------------
+KF648239|Tennessee|12_13|H1N1 ATTTACCATTGACAAGTAA- --------------
+KF648034|Arizona|12_13|H1N1 ATTTACCATTGACAAGTAA- --------------
+KF648037|Kentucky|12_13|H1N1 ATTTACCATTGACAAGTAA- --------------
+KF648038|Kansas|12_13|H1N1 ATTTACCATTGACAAGTAA- --------------
+KF647919|Alabama|12_13|H1N1 ATTTACCATTGACAAGTAA- --------------
+KF647931|Wisconsin|12_13|H1N1 ATTTACCATTGACAAGTAA- --------------
+KF647932|Pennsylvania|12_13|H1N1 ATTTACCATTGACAAGTAA- --------------
+KF647958|Nebraska|12_13|H1N1 ATTTACCATTGACAAGTAA- --------------
+KF647971|Oklahoma|12_13|H1N1 ATTTACCATTGACAAGTAA- --------------
+KF647902|Iowa|12_13|H1N1 ATTTACCATTGACAAGTAA- --------------
+KF648002|Minnesota|12_13|H1N1 ATTTACCATTGACAAGTAA- --------------
+KF648040|New_Jersey|12_13|H1N1 ATTTACCATTGACAAGTAA- --------------
+KF648101|Ohio|12_13|H1N1 ATTTACCATTGACAAGTAA- --------------
+KF648260|Washington|12_13|H1N1 ATTTACCATTGACAAGTAA- --------------
+CY170697|California|12_13|H1N1 ATTTACCATTGACAAGTAAT TTGTTCA-------
+CY168881|Massachusetts|12_13|H1N1 ATTTACCATTGACAAGTAAT TTGTTCAAAAAACT
+CY171161|Illinois|12_13|H1N1 ATTTACCATTGACAATTAAT TTGTTCAAAAAACT
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+;
+END;
diff --git a/examples/phyrex_input_files/usa_coord.txt b/examples/phyrex_input_files/usa_coord.txt
new file mode 100644
index 0000000..2a4697c
--- /dev/null
+++ b/examples/phyrex_input_files/usa_coord.txt
@@ -0,0 +1,53 @@
+# state.name lon lat
+|SouthWest| -122 25
+|NorthEast| -66 49 
+|Alabama| -86.902298 32.3182314
+|Alaska| -149.4936733 64.2008413
+|Arizona| -111.0937311 34.0489281
+|Arkansas| -91.8318334 35.20105
+|California| -119.4179324 36.778261
+|Colorado| -105.7820674 39.5500507
+|Connecticut| -73.087749 41.6032207
+|Delaware| -75.5276699 38.9108325
+|Florida| -81.5157535 27.6648274
+|Georgia| -82.9000751 32.1656221
+|Hawaii| -155.5827818 19.8967662
+|Idaho| -114.7420408 44.0682019
+|Illinois| -89.3985283 40.6331249
+|Indiana| -86.1349019 40.2671941
+|Iowa| -93.097702 41.8780025
+|Kansas| -98.4842465 39.011902
+|Kentucky| -84.2700179 37.8393332
+|Louisiana| -91.9623327 30.9842977
+|Maine| -69.4454689 45.253783
+|Maryland| -76.6412712 39.0457549
+|Massachusetts| -71.3824374 42.4072107
+|Michigan| -85.6023643 44.3148443
+|Minnesota| -94.6858998 46.729553
+|Mississippi| -89.3985283 32.3546679
+|Missouri| -91.8318334 37.9642529
+|Montana| -110.3625658 46.8796822
+|Nebraska| -99.9018131 41.4925374
+|Nevada| -116.419389 38.8026097
+|New_Hampshire| -71.5723953 43.1938516
+|New_Jersey| -74.4056612 40.0583238
+|New_Mexico| -105.8700901 34.5199402
+|New_York| -74.0059413 40.7127837
+|North_Carolina| -79.0192997 35.7595731
+|North_Dakota| -101.0020119 47.5514926
+|Ohio| -82.907123 40.4172871
+|Oklahoma| -97.5164276 35.4675602
+|Oregon| -120.5542012 43.8041334
+|Pennsylvania| -77.1945247 41.2033216
+|Rhode_Island| -71.4774291 41.5800945
+|South_Carolina| -81.1637245 33.836081
+|South_Dakota| -99.9018131 43.9695148
+|Tennessee| -86.5804473 35.5174913
+|Texas| -99.9018131 31.9685988
+|Utah| -111.0937311 39.3209801
+|Vermont| -72.5778415 44.5588028
+|Virginia| -78.6568942 37.4315734
+|Washington| -77.0368707 38.9071923
+|West_Virginia| -80.4549026 38.5976262
+|Wisconsin| -88.7878678 43.7844397
+|Wyoming| -107.2902839 43.0759678
diff --git a/src/Makefile.am b/src/Makefile.am
index 79155d6..6c021b4 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -7,6 +7,10 @@ if WANT_PHYTIME
 bin_PROGRAMS = phytime
 PROG = PHYTIME
 else
+if WANT_PHYTIME
+bin_PROGRAMS = phyml
+PROG = PHYML
+else
 if WANT_PHYCONT
 bin_PROGRAMS = phycont
 PROG = PHYCONT
@@ -34,6 +38,10 @@ if WANT_MPI
 bin_PROGRAMS = phyml-mpi
 PROG = PHYML
 else
+if WANT_WIN
+bin_PROGRAMS = phyml-windows
+PROG = PHYML
+else
 if WANT_TEST
 bin_PROGRAMS = test
 PROG = TEST
@@ -62,6 +70,10 @@ if WANT_PHYREX
 bin_PROGRAMS = phyrex
 PROG = PHYREX
 else
+if WANT_DATE
+bin_PROGRAMS = date
+PROG = DATE
+else
 bin_PROGRAMS = phyml
 PROG = PHYML
 endif
@@ -79,6 +91,9 @@ endif
 endif
 endif
 endif
+endif
+endif
+endif
 
 if WANT_PHYTIME
 phytime_SOURCES = main.c \
@@ -109,8 +124,8 @@ make.c make.h\
 mixt.c mixt.h\
 init.c init.h\
 nexus.c nexus.h\
-xml.c xml.h\
-phyrex.c phyrex.h
+date.c date.h\
+xml.c xml.h
 phytime_LDADD = -lm
 else 
 if WANT_PHYCONT
@@ -307,9 +322,43 @@ nexus.c nexus.h\
 init.c init.h\
 xml.c xml.h\
 mixt.c mixt.h\
+date.c date.h\
 mpi_boot.c mpi_boot.h
 phyml_mpi_LDADD = -lm
 else
+if WANT_WIN
+phyml_windows_SOURCES = main.c \
+utilities.c  utilities.h\
+optimiz.c  optimiz.h\
+lk.c  lk.h\
+bionj.c bionj.h\
+models.c  models.h\
+free.c  free.h\
+help.c  help.h\
+simu.c  simu.h\
+eigen.c  eigen.h\
+pars.c  pars.h\
+alrt.c  alrt.h\
+interface.c  interface.h\
+cl.c  cl.h\
+spr.c spr.h\
+draw.c  draw.h\
+stats.c stats.h\
+rates.c rates.h\
+mcmc.c mcmc.h\
+times.c times.h\
+tiporder.c tiporder.h\
+mg.c mg.h\
+m4.c m4.h\
+io.c io.h\
+make.c make.h\
+nexus.c nexus.h\
+init.c init.h\
+xml.c xml.h\
+mixt.c mixt.h\
+date.c date.h
+phyml_windows_LDADD = -lm
+else
 if WANT_TEST
 test_SOURCES = main.c \
 utilities.c  utilities.h\
@@ -503,6 +552,7 @@ nexus.c nexus.h\
 init.c init.h\
 xml.c xml.h\
 mixt.c mixt.h\
+date.c date.h\
 phyrex.c phyrex.h
 else
 if WANT_BEAGLE
@@ -538,6 +588,39 @@ mixt.c mixt.h\
 beagle_utils.c beagle_utils.h
 phyml_beagle_LDADD = -lm -lhmsbeagle
 else
+if WANT_DATE
+date_SOURCES = main.c \
+utilities.c  utilities.h\
+optimiz.c  optimiz.h\
+lk.c  lk.h\
+bionj.c bionj.h\
+models.c  models.h\
+free.c  free.h\
+help.c  help.h\
+simu.c  simu.h\
+eigen.c  eigen.h\
+pars.c  pars.h\
+alrt.c  alrt.h\
+interface.c  interface.h\
+cl.c  cl.h\
+spr.c spr.h\
+draw.c  draw.h\
+stats.c stats.h\
+rates.c rates.h\
+mcmc.c mcmc.h\
+times.c times.h\
+tiporder.c tiporder.h\
+mg.c mg.h\
+m4.c m4.h\
+io.c io.h\
+make.c make.h\
+nexus.c nexus.h\
+init.c init.h\
+xml.c xml.h\
+mixt.c mixt.h\
+date.c date.h
+date_LDADD = -lm
+else
 phyml_SOURCES = main.c \
 utilities.c  utilities.h\
 optimiz.c  optimiz.h\
@@ -566,6 +649,7 @@ make.c make.h\
 nexus.c nexus.h\
 init.c init.h\
 xml.c xml.h\
+date.c date.h\
 mixt.c mixt.h
 phyml_LDADD = -lm
 endif
@@ -583,6 +667,8 @@ endif
 endif
 endif
 endif
+endif
+endif
 
 
 all-am:	intro $(bin_PROGRAMS)
diff --git a/src/alrt.c b/src/alrt.c
index e8ed543..89926f7 100644
--- a/src/alrt.c
+++ b/src/alrt.c
@@ -41,10 +41,10 @@ int Check_NNI_Five_Branches(t_tree *tree)
   phydbl init_lnL;
 
   init_lnL     = UNLIKELY;
-  better_found = 1;
+  better_found = YES;
   
   //While there is at least one NNI to do...
-  while(better_found)
+  while(better_found == YES)
     {
       Update_Dirs(tree);
       
@@ -80,7 +80,7 @@ int Check_NNI_Five_Branches(t_tree *tree)
                   {
                     if((tree->a_edges[i]->nni->lk0 - tree->a_edges[i]->nni->lk1) < best_gain)
                       {
-                        better_found = 1;
+                        better_found = YES;
                         best_edge    = i;
                         best_gain    = tree->a_edges[i]->nni->lk0-tree->a_edges[i]->nni->lk1;
                         best_config  = 1;
@@ -91,7 +91,7 @@ int Check_NNI_Five_Branches(t_tree *tree)
                   {
                     if((tree->a_edges[i]->nni->lk0 - tree->a_edges[i]->nni->lk2) < best_gain)
                       {
-                        better_found = 1;
+                        better_found = YES;
                         best_edge    = i;
                         best_gain    = tree->a_edges[i]->nni->lk0-tree->a_edges[i]->nni->lk2;
                         best_config  = 2;
@@ -102,7 +102,7 @@ int Check_NNI_Five_Branches(t_tree *tree)
                   {
                     if((tree->a_edges[i]->nni->lk2 - tree->a_edges[i]->nni->lk1) < best_gain)
                       {
-                        better_found = 1;
+                        better_found = YES;
                         best_edge    = i;
                         best_gain    = tree->a_edges[i]->nni->lk2-tree->a_edges[i]->nni->lk1;
                         best_config  = 1;
@@ -113,7 +113,7 @@ int Check_NNI_Five_Branches(t_tree *tree)
                   {
                     if((tree->a_edges[i]->nni->lk1 - tree->a_edges[i]->nni->lk2) < best_gain)
                       {
-                        better_found = 1;
+                        better_found = YES;
                         best_edge    = i;
                         best_gain    = tree->a_edges[i]->nni->lk1-tree->a_edges[i]->nni->lk2;
                         best_config  = 2;
@@ -137,7 +137,7 @@ int Check_NNI_Five_Branches(t_tree *tree)
         }
       
       //Don't do any NNI if the user doesn't want to optimize topology
-      if(!tree->mod->s_opt->opt_topo) better_found = 0;
+      if(!tree->mod->s_opt->opt_topo) better_found = NO;
 /*       if(FABS(best_gain) <= tree->mod->s_opt->min_diff_lk_move) better_found = 0; */
 
       //If there is one swap to do, make the best one.
@@ -205,6 +205,7 @@ void aLRT(t_tree *tree)
   Lk(NULL,tree);
   //  Print_All_Edge_Likelihoods(tree);
   MIXT_Set_Alias_Subpatt(NO,tree);
+  Update_Dirs(tree);
   
   For(i,2*tree->n_otu-3)
     if((!tree->a_edges[i]->left->tax) && (!tree->a_edges[i]->rght->tax))
@@ -347,19 +348,21 @@ int NNI_Neigh_BL(t_edge *b_fcus, t_tree *tree)
   int site;
   t_node *v1,*v2,*v3,*v4;
   t_edge *e1,*e2,*e3,*e4;
-  phydbl *len_e1,*len_e2,*len_e3,*len_e4;
+  scalar_dbl *len_e1,*len_e2,*len_e3,*len_e4;
+  scalar_dbl *var_e1,*var_e2,*var_e3,*var_e4;
   phydbl lk0, lk1, lk2;
-  phydbl *bl_init;
+  scalar_dbl *l_init,*v_init;
   phydbl l_infa, l_infb;
   phydbl lk_init, lk_temp;
   int i;
-  int result,counter,wei;
+  int result;
   void *buff;
 
   result = 0;
 
   /*! Initialization */
-  bl_init            = MIXT_Get_Lengths_Of_This_Edge(b_fcus,tree);
+  l_init             = Duplicate_Scalar_Dbl(b_fcus->l);
+  v_init             = Duplicate_Scalar_Dbl(b_fcus->l_var);
   lk_init            = tree->c_lnL;
   lk_temp            = UNLIKELY;
   b_fcus->nni->score = .0;
@@ -377,6 +380,7 @@ int NNI_Neigh_BL(t_edge *b_fcus, t_tree *tree)
       PhyML_Printf("\n== Err. in file %s at line %d\n\n",__FILE__,__LINE__);
       Exit("");
     }
+
   if(v3->num < v4->num)
     {
       PhyML_Printf("\n== Err. in file %s at line %d\n\n",__FILE__,__LINE__);
@@ -390,10 +394,14 @@ int NNI_Neigh_BL(t_edge *b_fcus, t_tree *tree)
   e4 = b_fcus->rght->b[b_fcus->r_v2];
 
   /*! record initial branch lengths */
-  len_e1 = MIXT_Get_Lengths_Of_This_Edge(e1,tree);
-  len_e2 = MIXT_Get_Lengths_Of_This_Edge(e2,tree);
-  len_e3 = MIXT_Get_Lengths_Of_This_Edge(e3,tree);
-  len_e4 = MIXT_Get_Lengths_Of_This_Edge(e4,tree);
+  len_e1 = Duplicate_Scalar_Dbl(e1->l);
+  len_e2 = Duplicate_Scalar_Dbl(e2->l);
+  len_e3 = Duplicate_Scalar_Dbl(e3->l);
+  len_e4 = Duplicate_Scalar_Dbl(e4->l);
+  var_e1 = Duplicate_Scalar_Dbl(e1->l_var);
+  var_e2 = Duplicate_Scalar_Dbl(e2->l_var);
+  var_e3 = Duplicate_Scalar_Dbl(e3->l_var);
+  var_e4 = Duplicate_Scalar_Dbl(e4->l_var);
 
   /*! Optimize branch lengths and update likelihoods for
     the original configuration.
@@ -406,23 +414,23 @@ int NNI_Neigh_BL(t_edge *b_fcus, t_tree *tree)
         if(b_fcus->left->v[i] != b_fcus->rght)//Only consider left_1 and left_2
           {
             Update_P_Lk(tree,b_fcus->left->b[i],b_fcus->left);
-            l_infa  = 10.;
-            l_infb  = MAX(0.0,tree->mod->l_min/b_fcus->left->b[i]->l->v);
+            l_infa  = 2.;
+            l_infb  = 1.E-4;
             lk_temp = Br_Len_Brent(l_infb,l_infa,b_fcus->left->b[i],tree);
           }
 
       Update_P_Lk(tree,b_fcus,b_fcus->left);
 
-      l_infa  = 10.;
-      l_infb  = MAX(0.0,tree->mod->l_min/b_fcus->l->v);
+      l_infa  = 2.;
+      l_infb  = 1.E-4;
       lk_temp = Br_Len_Brent(l_infb,l_infa,b_fcus,tree);
 
       For(i,3)
         if(b_fcus->rght->v[i] != b_fcus->left)//Only consider right_1 and right_2
           {
             Update_P_Lk(tree,b_fcus->rght->b[i],b_fcus->rght);
-            l_infa  = 10.;
-            l_infb  = MAX(0.0,tree->mod->l_min/b_fcus->rght->b[i]->l->v);
+            l_infa  = 2.;
+            l_infb  = 1.E-4;
             lk_temp = Br_Len_Brent(l_infb,l_infa,b_fcus->rght->b[i],tree);
           }
       Update_P_Lk(tree,b_fcus,b_fcus->rght);
@@ -438,31 +446,29 @@ int NNI_Neigh_BL(t_edge *b_fcus, t_tree *tree)
   //until no significative improvement is detected
   
   lk0 = tree->c_lnL;
-
+ 
   buff = (t_tree *)tree;
   do
     {
-      counter=0;
-      For(site,tree->n_pattern)
-        {
-          wei=0;
-          For(wei,tree->data->wght[site])
-            {
-              tree->log_lks_aLRT[0][counter]= tree->c_lnL_sorted[site] / tree->data->wght[site];
-              counter++;
-            }
-        }
+      For(site,tree->n_pattern) tree->log_lks_aLRT[0][site] = tree->c_lnL_sorted[site];
       tree = tree->next_mixt;
     }
   while(tree);
 
   tree = (t_tree *)buff;
+
   /*! Go back to initial branch lengths */
-  MIXT_Set_Lengths_Of_This_Edge(len_e1,e1,tree);
-  MIXT_Set_Lengths_Of_This_Edge(len_e2,e2,tree);
-  MIXT_Set_Lengths_Of_This_Edge(len_e3,e3,tree);
-  MIXT_Set_Lengths_Of_This_Edge(len_e4,e4,tree);
-  MIXT_Set_Lengths_Of_This_Edge(bl_init,b_fcus,tree);
+  Copy_Scalar_Dbl(len_e1,e1->l);
+  Copy_Scalar_Dbl(len_e2,e2->l);
+  Copy_Scalar_Dbl(len_e3,e3->l);
+  Copy_Scalar_Dbl(len_e4,e4->l);
+  Copy_Scalar_Dbl(l_init,b_fcus->l);
+  Copy_Scalar_Dbl(var_e1,e1->l_var);
+  Copy_Scalar_Dbl(var_e2,e2->l_var);
+  Copy_Scalar_Dbl(var_e3,e3->l_var);
+  Copy_Scalar_Dbl(var_e4,e4->l_var);
+  Copy_Scalar_Dbl(v_init,b_fcus->l_var);
+
   Update_PMat_At_Given_Edge(e1,tree);
   Update_PMat_At_Given_Edge(e2,tree);
   Update_PMat_At_Given_Edge(e3,tree);
@@ -513,15 +519,15 @@ int NNI_Neigh_BL(t_edge *b_fcus, t_tree *tree)
           {
             Update_P_Lk(tree,b_fcus->left->b[i],b_fcus->left);
             
-            l_infa  = 10.;
-            l_infb  = MAX(0.0,tree->mod->l_min/b_fcus->left->b[i]->l->v);
+            l_infa  = 2.;
+            l_infb  = 1.E-4;
             lk_temp = Br_Len_Brent(l_infb,l_infa,b_fcus->left->b[i],tree);
           }
       
       Update_P_Lk(tree,b_fcus,b_fcus->left);
       
-      l_infa  = 10.;
-      l_infb  = MAX(0.0,tree->mod->l_min/b_fcus->l->v);
+      l_infa  = 2.;
+      l_infb  = 1.E-4;
       lk_temp = Br_Len_Brent(l_infb,l_infa,b_fcus,tree);
       
       For(i,3)
@@ -529,8 +535,8 @@ int NNI_Neigh_BL(t_edge *b_fcus, t_tree *tree)
           {
             Update_P_Lk(tree,b_fcus->rght->b[i],b_fcus->rght);
             
-            l_infa  = 10.;
-            l_infb  = MAX(0.0,tree->mod->l_min/b_fcus->rght->b[i]->l->v);
+            l_infa  = 2;
+            l_infb  = 1.E-4;
             lk_temp = Br_Len_Brent(l_infb,l_infa,b_fcus->rght->b[i],tree);
           }
       
@@ -553,29 +559,25 @@ int NNI_Neigh_BL(t_edge *b_fcus, t_tree *tree)
   buff = (t_tree *)tree;
   do
     {
-      counter=0;
-      For(site,tree->n_pattern)
-        {
-          wei=0;
-          For(wei,tree->data->wght[site])
-            {
-              tree->log_lks_aLRT[1][counter]= tree->c_lnL_sorted[site] / tree->data->wght[site];
-              counter++;
-            }
-        }
+      For(site,tree->n_pattern) tree->log_lks_aLRT[1][site]= tree->c_lnL_sorted[site];
       tree = tree->next_mixt;
     }
   while(tree);
   tree = (t_tree *)buff;
       
-
   Swap(v3,b_fcus->left,b_fcus->rght,v2,tree);
+
   /*! Go back to initial branch lengths */
-  MIXT_Set_Lengths_Of_This_Edge(len_e1,e1,tree);
-  MIXT_Set_Lengths_Of_This_Edge(len_e2,e2,tree);
-  MIXT_Set_Lengths_Of_This_Edge(len_e3,e3,tree);
-  MIXT_Set_Lengths_Of_This_Edge(len_e4,e4,tree);
-  MIXT_Set_Lengths_Of_This_Edge(bl_init,b_fcus,tree);
+  Copy_Scalar_Dbl(len_e1,e1->l);
+  Copy_Scalar_Dbl(len_e2,e2->l);
+  Copy_Scalar_Dbl(len_e3,e3->l);
+  Copy_Scalar_Dbl(len_e4,e4->l);
+  Copy_Scalar_Dbl(l_init,b_fcus->l);
+  Copy_Scalar_Dbl(var_e1,e1->l_var);
+  Copy_Scalar_Dbl(var_e2,e2->l_var);
+  Copy_Scalar_Dbl(var_e3,e3->l_var);
+  Copy_Scalar_Dbl(var_e4,e4->l_var);
+  Copy_Scalar_Dbl(v_init,b_fcus->l_var);
   
   Update_PMat_At_Given_Edge(e1,tree);
   Update_PMat_At_Given_Edge(e2,tree);
@@ -625,8 +627,8 @@ int NNI_Neigh_BL(t_edge *b_fcus, t_tree *tree)
           {
             Update_P_Lk(tree,b_fcus->left->b[i],b_fcus->left);
             
-            l_infa  = 10.;
-            l_infb  = MAX(0.0,tree->mod->l_min/b_fcus->left->b[i]->l->v);
+            l_infa  = 2.;
+            l_infb  = 1.E-4;
             lk_temp = Br_Len_Brent(l_infb,l_infa,b_fcus->left->b[i],tree);
             
             if(lk_temp < lk2 - tree->mod->s_opt->min_diff_lk_local)
@@ -639,8 +641,8 @@ int NNI_Neigh_BL(t_edge *b_fcus, t_tree *tree)
           }
       Update_P_Lk(tree,b_fcus,b_fcus->left);
       
-      l_infa  = 10.;
-      l_infb  = MAX(0.0,tree->mod->l_min/b_fcus->l->v);
+      l_infa  = 2.;
+      l_infb  = 1.E-4;
       lk_temp = Br_Len_Brent(l_infb,l_infa,b_fcus,tree);
       
       if(lk_temp < lk2 - tree->mod->s_opt->min_diff_lk_local)
@@ -656,8 +658,8 @@ int NNI_Neigh_BL(t_edge *b_fcus, t_tree *tree)
           {
             Update_P_Lk(tree,b_fcus->rght->b[i],b_fcus->rght);
             
-            l_infa  = 10.;
-            l_infb  = MAX(0.0,tree->mod->l_min/b_fcus->rght->b[i]->l->v);
+            l_infa  = 2.;
+            l_infb  = 1.E-4;
             lk_temp = Br_Len_Brent(l_infb,l_infa,b_fcus->rght->b[i],tree);
             
             if(lk_temp < lk2 - tree->mod->s_opt->min_diff_lk_local)
@@ -684,16 +686,7 @@ int NNI_Neigh_BL(t_edge *b_fcus, t_tree *tree)
   buff = (t_tree *)tree;
   do
     {
-      counter=0;
-      For(site,tree->n_pattern)
-        {
-          wei=0;
-          For(wei,tree->data->wght[site])
-            {
-              tree->log_lks_aLRT[2][counter]= tree->c_lnL_sorted[site] / tree->data->wght[site];
-              counter++;
-            }
-        }
+      For(site,tree->n_pattern) tree->log_lks_aLRT[2][site]= tree->c_lnL_sorted[site];
       tree = tree->next_mixt;
     }
   while(tree);
@@ -705,11 +698,17 @@ int NNI_Neigh_BL(t_edge *b_fcus, t_tree *tree)
   /***********/
 
   /*! restore the initial branch length values */
-  MIXT_Set_Lengths_Of_This_Edge(len_e1,e1,tree);
-  MIXT_Set_Lengths_Of_This_Edge(len_e2,e2,tree);
-  MIXT_Set_Lengths_Of_This_Edge(len_e3,e3,tree);
-  MIXT_Set_Lengths_Of_This_Edge(len_e4,e4,tree);
-  MIXT_Set_Lengths_Of_This_Edge(bl_init,b_fcus,tree);
+  Copy_Scalar_Dbl(len_e1,e1->l);
+  Copy_Scalar_Dbl(len_e2,e2->l);
+  Copy_Scalar_Dbl(len_e3,e3->l);
+  Copy_Scalar_Dbl(len_e4,e4->l);
+  Copy_Scalar_Dbl(l_init,b_fcus->l);
+  Copy_Scalar_Dbl(var_e1,e1->l_var);
+  Copy_Scalar_Dbl(var_e2,e2->l_var);
+  Copy_Scalar_Dbl(var_e3,e3->l_var);
+  Copy_Scalar_Dbl(var_e4,e4->l_var);
+  Copy_Scalar_Dbl(v_init,b_fcus->l_var);
+
 
   /*! recompute likelihoods */
   Update_PMat_At_Given_Edge(e1,tree);
@@ -769,11 +768,16 @@ int NNI_Neigh_BL(t_edge *b_fcus, t_tree *tree)
     }
 
 
-  Free(len_e1);
-  Free(len_e2);
-  Free(len_e3);
-  Free(len_e4);
-  Free(bl_init);
+  Free_Scalar_Dbl(len_e1);
+  Free_Scalar_Dbl(len_e2);
+  Free_Scalar_Dbl(len_e3);
+  Free_Scalar_Dbl(len_e4);
+  Free_Scalar_Dbl(l_init);
+  Free_Scalar_Dbl(var_e1);
+  Free_Scalar_Dbl(var_e2);
+  Free_Scalar_Dbl(var_e3);
+  Free_Scalar_Dbl(var_e4);
+  Free_Scalar_Dbl(v_init);
 
   return result;
 }
@@ -843,11 +847,11 @@ void Make_Target_Swap(t_tree *tree, t_edge *b_fcus, int swaptodo)
   MIXT_Set_Alias_Subpatt(YES,tree);
   Set_Both_Sides(YES,tree);
   lktodo = Update_Lk_At_Given_Edge(b_fcus,tree);
-
+  
   For(i,3)
     if(b_fcus->left->v[i] != b_fcus->rght)
       Update_P_Lk(tree,b_fcus->left->b[i],b_fcus->left);
-
+  
   For(i,3)
     if(b_fcus->rght->v[i] != b_fcus->left)
       Update_P_Lk(tree,b_fcus->rght->b[i],b_fcus->rght);
@@ -861,42 +865,40 @@ void Make_Target_Swap(t_tree *tree, t_edge *b_fcus, int swaptodo)
       lktodo = lk_temp;
 
       For(i,3)
-    if(b_fcus->left->v[i] != b_fcus->rght)
-      {
-        Update_P_Lk(tree,b_fcus->left->b[i],b_fcus->left);
-
-        l_infa  = 10.;
-        l_infb  = tree->mod->l_min/b_fcus->left->b[i]->l->v;
-        lk_temp = Br_Len_Brent(l_infb,l_infa,b_fcus->left->b[i],tree);
-      }
+        if(b_fcus->left->v[i] != b_fcus->rght)
+          {
+            Update_P_Lk(tree,b_fcus->left->b[i],b_fcus->left);
+            
+            l_infa  = 2.;
+            l_infb  = 1.E-4;
+            lk_temp = Br_Len_Brent(l_infb,l_infa,b_fcus->left->b[i],tree);
+          }
 
 
       Update_P_Lk(tree,b_fcus,b_fcus->left);
 
-      l_infa  = 10.;
-      l_infb  = tree->mod->l_min/b_fcus->l->v;
+      l_infa  = 2.;
+      l_infb  = 1.E-4;
       lk_temp = Br_Len_Brent(l_infb,l_infa,b_fcus,tree);
 
-
-
       For(i,3)
-    if(b_fcus->rght->v[i] != b_fcus->left)
-      {
-        Update_P_Lk(tree,b_fcus->rght->b[i],b_fcus->rght);
-
-        l_infa  = 10.;
-        l_infb  = tree->mod->l_min/b_fcus->rght->b[i]->l->v;
-        lk_temp = Br_Len_Brent(l_infb,l_infa,b_fcus->rght->b[i],tree);
-      }
+        if(b_fcus->rght->v[i] != b_fcus->left)
+          {
+            Update_P_Lk(tree,b_fcus->rght->b[i],b_fcus->rght);
+            
+            l_infa  = 2.;
+            l_infb  = 1.E-4;
+            lk_temp = Br_Len_Brent(l_infb,l_infa,b_fcus->rght->b[i],tree);
+          }
 
       Update_P_Lk(tree,b_fcus,b_fcus->rght);
 
       if(lk_temp < lktodo - tree->mod->s_opt->min_diff_lk_local)
-    {
-      PhyML_Printf("\n. Edge %3d lk_temp = %f lktodo = %f\n",b_fcus->num,lk_temp,lktodo);
-      PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__);
-      Warn_And_Exit("");
-    }
+        {
+          PhyML_Printf("\n== Edge %3d lk_temp = %f lktodo = %f\n",b_fcus->num,lk_temp,lktodo);
+          PhyML_Printf("\n== Err. in file %s at line %d\n\n",__FILE__,__LINE__);
+          Warn_And_Exit("");
+        }
     }
   while(FABS(lk_temp-lktodo) > tree->mod->s_opt->min_diff_lk_global);
   //until no significative improvement is detected
@@ -913,8 +915,7 @@ void Make_Target_Swap(t_tree *tree, t_edge *b_fcus, int swaptodo)
 
   if(tree->c_lnL < lk_init - tree->mod->s_opt->min_diff_lk_global)
     {
-      PhyML_Printf("\n. [%3d] v1=%d v2=%d v3=%d v4=%d",
-         b_fcus->num,v1->num,v2->num,v3->num,v4->num);
+      PhyML_Printf("\n. [%3d] v1=%d v2=%d v3=%d v4=%d",b_fcus->num,v1->num,v2->num,v3->num,v4->num);
       PhyML_Printf("\n. tree->c_lnL = %f lk_init = %f\n",tree->c_lnL,lk_init);
       PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__);
       Warn_And_Exit("");
@@ -1107,12 +1108,11 @@ phydbl Statistics_to_RELL(t_tree *tree)
   int i;
   int occurence=1000;
   phydbl nb=0.0;
-  phydbl res;
+  phydbl res,*pi;
   int site;
   phydbl lk0=0.0;
   phydbl lk1=0.0;
   phydbl lk2=0.0;
-  phydbl buff = -1.;
   int position = -1;
   t_tree *buff_tree;
 
@@ -1127,19 +1127,19 @@ phydbl Statistics_to_RELL(t_tree *tree)
       buff_tree = tree;
       do
         {
+          pi = (phydbl *)mCalloc(tree->data->crunch_len,sizeof(phydbl));
+          For(site,tree->n_pattern) pi[site] = tree->data->wght[site] / (phydbl)tree->data->init_len;
+
           For(site, tree->data->init_len)
             {
-              buff  = rand();
-              buff /= (RAND_MAX+1.);
-              buff *= tree->data->init_len;
-              position = (int)FLOOR(buff);
-
+              position = Sample_i_With_Proba_pi(pi,tree->n_pattern);
               lk0+=tree->log_lks_aLRT[0][position];
               lk1+=tree->log_lks_aLRT[1][position];
               lk2+=tree->log_lks_aLRT[2][position];
             }
           if (lk0>=lk1 && lk0>=lk2) nb++;
           tree = tree->next_mixt;
+          Free(pi);
         }
       while(tree);
       tree = buff_tree;
@@ -1169,22 +1169,22 @@ phydbl Statistics_To_SH(t_tree *tree)
   phydbl c0=0.0;
   phydbl c1=0.0;
   phydbl c2=0.0;
-  phydbl buff=-1.;
   int position=-1;
   phydbl delta_local=-1.;
   phydbl delta=0.0;
   t_tree *buff_tree;
+  phydbl *pi;
 
 
   /*! Compute the total log-lk of each NNI position */
   buff_tree = tree;
   do
     {
-      For(site, tree->data->init_len)
+      For(site, tree->n_pattern)
         {
-          c0+=tree->log_lks_aLRT[0][site];
-          c1+=tree->log_lks_aLRT[1][site];
-          c2+=tree->log_lks_aLRT[2][site];
+          c0+=tree->log_lks_aLRT[0][site] * tree->data->wght[site];
+          c1+=tree->log_lks_aLRT[1][site] * tree->data->wght[site];
+          c2+=tree->log_lks_aLRT[2][site] * tree->data->wght[site];
         }
       tree = tree->next_mixt;
     }
@@ -1236,20 +1236,20 @@ phydbl Statistics_To_SH(t_tree *tree)
       buff_tree = tree;
       do
         {
+          pi = (phydbl *)mCalloc(tree->data->crunch_len,sizeof(phydbl));
+          For(site,tree->n_pattern) pi[site] = tree->data->wght[site] / (phydbl)tree->data->init_len;
+
           /*! Shuffle the data */
           For(site, tree->data->init_len)
             {
-              buff  = rand();
-              buff /= (RAND_MAX+1.);
-              buff *= tree->data->init_len;
-              position = (int)FLOOR(buff);
-
+              position = Sample_i_With_Proba_pi(pi,tree->n_pattern);
               lk0+=tree->log_lks_aLRT[0][position];
               lk1+=tree->log_lks_aLRT[1][position];
               lk2+=tree->log_lks_aLRT[2][position];
             }
 
           tree = tree->next_mixt;
+          Free(pi);
         }
       while(tree);
       tree = buff_tree;
diff --git a/src/cl.c b/src/cl.c
index 4e75756..5b0e23a 100644
--- a/src/cl.c
+++ b/src/cl.c
@@ -26,7 +26,7 @@ int Read_Command_Line(option *io, int argc, char **argv)
 
   PhyML_Printf("\n. command-line: ");
   For(i,argc) PhyML_Printf("%s ",argv[i]);
-
+  PhyML_Printf("\n");
 
   if(argc == 1) Exit("\n. No argument was passed to the program. Please check the documentation. \n");
 
@@ -123,6 +123,8 @@ int Read_Command_Line(option *io, int argc, char **argv)
       {"ancestral",           no_argument,NULL,76},
       {"anc",                 no_argument,NULL,76},
       {"coord_file",          required_argument,NULL,77},
+      {"json_trace",          no_argument,NULL,78},
+      {"weights",             required_argument,NULL,79},
       {0,0,0,0}
     };
 
@@ -141,6 +143,18 @@ int Read_Command_Line(option *io, int argc, char **argv)
       switch(c)
 	{
 
+        case 79:
+          {
+            io->has_io_weights = YES;
+            strcpy(io->weight_file, optarg);
+            break;
+          }
+        case 78:
+          {
+	    io->print_json_trace = YES;
+	    break;            
+          }
+
         case 77:
           {
 	    char *tmp;
@@ -196,19 +210,31 @@ int Read_Command_Line(option *io, int argc, char **argv)
           }
 	case 73:
 	  {
-#ifndef INVITEE
+#ifdef INVITEE
             Free_Optimiz(io->mod->s_opt);
             M4_Free_M4_Model(io->mod->m4mod);
             Free_Model_Basic(io->mod);
             Free_Input(io);
-            PhyML_XML(optarg);
+            PhyTime_XML(optarg);
             return 0;
-#else
+
+#elif defined(PHYML)
+           
             Free_Optimiz(io->mod->s_opt);
             M4_Free_M4_Model(io->mod->m4mod);
             Free_Model_Basic(io->mod);
             Free_Input(io);
-            PhyTime_XML(optarg);
+            io = PhyML_XML(optarg);
+            Free(io);
+            return 0;
+
+#elif defined(DATE)
+
+            Free_Optimiz(io->mod->s_opt);
+            M4_Free_M4_Model(io->mod->m4mod);
+            Free_Model_Basic(io->mod);
+            Free_Input(io);
+            DATE_XML(optarg);
             return 0;
 #endif
             break;
@@ -508,9 +534,9 @@ int Read_Command_Line(option *io, int argc, char **argv)
 	  }
 	case 36 :
 	  {
-	    #ifndef PHYML
+#ifndef PHYML
             open_ps_file = 1;
-            #endif
+#endif
 	    break;
 	  }
 	case 35 :
@@ -1018,7 +1044,7 @@ int Read_Command_Line(option *io, int argc, char **argv)
 		  io->mod->s_opt->opt_state_freq = YES;
 		else
 		  {
-		    PhyML_Printf("\n. Please define the data type (nt or aa) before setting the -f option\n");
+		    PhyML_Printf("\n== Please define the data type (nt or aa) before setting the -f option\n");
 		    Exit("\n");
 		  }
 	      }
@@ -1030,7 +1056,7 @@ int Read_Command_Line(option *io, int argc, char **argv)
 		  io->mod->s_opt->opt_state_freq = NO;
 		else
 		  {
-		    PhyML_Printf("\n. Please define the data type (nt or aa) before setting the -f option\n");
+		    PhyML_Printf("\n== Please define the data type (nt or aa) before setting the -f option\n");
 		    Exit("\n");
 		  }
 	      }
@@ -1039,42 +1065,37 @@ int Read_Command_Line(option *io, int argc, char **argv)
 		phydbl sum;
 		double val1,val2,val3,val4;
 		
-		io->mod->s_opt->opt_state_freq  = 0;
-		io->mod->s_opt->user_state_freq = 1;
+		io->mod->s_opt->opt_state_freq  = NO;
+		io->mod->e_frq->user_state_freq = YES;
 		
-		/* 		sscanf(optarg,"%lf,%lf,%lf,%lf", */
-		/* 		       io->mod->user_b_freq, */
-		/* 		       io->mod->user_b_freq+1, */
-		/* 		       io->mod->user_b_freq+2, */
-		/* 		       io->mod->user_b_freq+3); */
 		sscanf(optarg,"%lf,%lf,%lf,%lf",&val1,&val2,&val3,&val4);
-		io->mod->user_b_freq->v[0] = (phydbl)val1;
-		io->mod->user_b_freq->v[1] = (phydbl)val2;
-		io->mod->user_b_freq->v[2] = (phydbl)val3;
-		io->mod->user_b_freq->v[3] = (phydbl)val4;
+		io->mod->e_frq->user_b_freq->v[0] = (phydbl)val1;
+		io->mod->e_frq->user_b_freq->v[1] = (phydbl)val2;
+		io->mod->e_frq->user_b_freq->v[2] = (phydbl)val3;
+		io->mod->e_frq->user_b_freq->v[3] = (phydbl)val4;
 		
 		sum =
-		  (io->mod->user_b_freq->v[0] +
-		   io->mod->user_b_freq->v[1] +
-		   io->mod->user_b_freq->v[2] +
-		   io->mod->user_b_freq->v[3]);
+		  (io->mod->e_frq->user_b_freq->v[0] +
+		   io->mod->e_frq->user_b_freq->v[1] +
+		   io->mod->e_frq->user_b_freq->v[2] +
+		   io->mod->e_frq->user_b_freq->v[3]);
 		
-		io->mod->user_b_freq->v[0] /= sum;
-		io->mod->user_b_freq->v[1] /= sum;
-		io->mod->user_b_freq->v[2] /= sum;
-		io->mod->user_b_freq->v[3] /= sum;
+		io->mod->e_frq->user_b_freq->v[0] /= sum;
+		io->mod->e_frq->user_b_freq->v[1] /= sum;
+		io->mod->e_frq->user_b_freq->v[2] /= sum;
+		io->mod->e_frq->user_b_freq->v[3] /= sum;
 		
 		
-		if(io->mod->user_b_freq->v[0] < .0 ||
-		   io->mod->user_b_freq->v[1] < .0 ||
-		   io->mod->user_b_freq->v[2] < .0 ||
-		   io->mod->user_b_freq->v[3] < .0 ||
-		   io->mod->user_b_freq->v[0] > 1. ||
-		   io->mod->user_b_freq->v[1] > 1. ||
-		   io->mod->user_b_freq->v[2] > 1. ||
-		   io->mod->user_b_freq->v[3] > 1.)
+		if(io->mod->e_frq->user_b_freq->v[0] < .0 ||
+		   io->mod->e_frq->user_b_freq->v[1] < .0 ||
+		   io->mod->e_frq->user_b_freq->v[2] < .0 ||
+		   io->mod->e_frq->user_b_freq->v[3] < .0 ||
+		   io->mod->e_frq->user_b_freq->v[0] > 1. ||
+		   io->mod->e_frq->user_b_freq->v[1] > 1. ||
+		   io->mod->e_frq->user_b_freq->v[2] > 1. ||
+		   io->mod->e_frq->user_b_freq->v[3] > 1.)
 		  {
-		    Warn_And_Exit("\n. Invalid base frequencies.\n");
+		    Warn_And_Exit("\n== Invalid base frequencies.\n");
 		  }
 	      }
 	    break;
@@ -1398,9 +1419,6 @@ int Read_Command_Line(option *io, int argc, char **argv)
       Exit("\n");
     }
   
-
-  
-
   if(io->mod->use_m4mod == NO)
     {
       io->mod->s_opt->opt_cov_delta      = 0;
@@ -1428,8 +1446,17 @@ int Read_Command_Line(option *io, int argc, char **argv)
       strcpy(io->out_trace_file,io->in_align_file);
       strcat(io->out_trace_file,"_phyml_trace");
       if(io->append_run_ID) { strcat(io->out_trace_file,"_"); strcat(io->out_trace_file,io->run_id_string); }
-      io->fp_out_trace = Openfile(io->out_trace_file,1);
+      io->fp_out_trace = Openfile(io->out_trace_file,WRITE);
+    }
+
+  if(io->print_json_trace)
+    {
+      strcpy(io->out_json_trace_file,io->in_align_file);
+      strcat(io->out_json_trace_file,"_phyml_trace.json");
+      if(io->append_run_ID) { strcat(io->out_json_trace_file,"_"); strcat(io->out_json_trace_file,io->run_id_string); }
+      io->fp_out_json_trace = Openfile(io->out_json_trace_file,READWRITE);
     }
+
   
   if(io->mod->s_opt->random_input_tree)
     {
diff --git a/src/cl.h b/src/cl.h
index 8bb5d37..9540071 100644
--- a/src/cl.h
+++ b/src/cl.h
@@ -24,6 +24,7 @@ the GNU public licence.  See http://www.opensource.org for details.
 #include "free.h"
 #include "interface.h"
 #include "invitee.h"
+#include "date.h"
 
 
 int Read_Command_Line(option *input, int argc, char **argv);
diff --git a/src/date.c b/src/date.c
new file mode 100644
index 0000000..e2b441f
--- /dev/null
+++ b/src/date.c
@@ -0,0 +1,789 @@
+/*
+
+PhyML:  a program that  computes maximum likelihood phylogenies from
+DNA or AA homologous sequences.
+
+Copyright (C) Stephane Guindon. Oct 2003 onward.
+
+All parts of the source except where indicated are distributed under
+the GNU public licence. See http://www.opensource.org for details.
+
+*/
+
+
+/* Routines for molecular dating */
+
+
+#include "date.h"
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+int DATE_Main(int argc, char **argv)
+{
+  option *io;
+  int seed;
+
+  seed = getpid();
+
+  /* seed = 1; */
+  /* seed = 8596; */
+  /* seed = 23595; */
+  /* seed = 10868; */
+  /* seed = 14848; */
+  /* seed = 22609; */
+  /* seed = 28079; */
+
+  seed = 28513;
+  printf("\n. seed: %d",seed);
+  srand(seed);
+
+  io = Get_Input(argc,argv);
+  Free(io);
+  return(0);
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void DATE_XML(char *xml_filename)
+{
+  FILE *fp_xml_in;
+  xml_node *xnd,*xnd_dum,*xnd_cal,*xroot;
+  t_tree *mixt_tree;
+  phydbl low,up,*res;
+  char *clade_name;
+
+  mixt_tree = XML_Process_Base(xml_filename);
+  assert(mixt_tree);
+
+  mixt_tree->rates = RATES_Make_Rate_Struct(mixt_tree->n_otu);
+  RATES_Init_Rate_Struct(mixt_tree->rates,NULL,mixt_tree->n_otu);
+
+  fp_xml_in = fopen(xml_filename,"r");
+  if(!fp_xml_in)
+    {
+      PhyML_Printf("\n== Could not find the XML file '%s'.\n",xml_filename);
+      Exit("\n");
+    }
+
+  xroot = XML_Load_File(fp_xml_in);
+
+  if(xroot == NULL)
+    {
+      PhyML_Printf("\n== Encountered an issue while loading the XML file.\n");
+      Exit("\n");
+    }
+  
+  // Looking for calibration node(s)
+  xnd = XML_Search_Node_Name("calibration",YES,xroot);
+
+  if(xnd == NULL)
+    {
+      PhyML_Printf("\n== No calibration information seems to be provided.");
+      PhyML_Printf("\n== Please amend your XML file. \n");
+      Exit("\n");
+    }
+  else
+    {
+      if(XML_Search_Node_Name("upper",NO,xnd->child) == NULL && XML_Search_Node_Name("lower",NO,xnd->child) == NULL)
+	{
+	  PhyML_Printf("\n== There is no calibration information provided. \n");
+	  PhyML_Printf("\n== Please check your data. \n");
+	  Exit("\n");
+	}
+    }
+
+
+  MIXT_Prepare_All(-1,mixt_tree);
+  if(mixt_tree->n_root == NULL) Add_Root(mixt_tree->a_edges[0],mixt_tree);
+
+  clade_name = (char *)mCalloc(T_MAX_NAME,sizeof(char));
+
+  xnd = xroot->child;
+  assert(xnd);
+  do
+    {
+      if(!strcmp(xnd->name,"calibration")) // Found a XML node <calibration>.
+	{
+          xnd_cal = xnd;
+
+          // TO DO: make sure calibs are shared across partition elements -> need to write chain function to
+          // call once the calib struct on the first mixt_tree is initialized.
+          /* mixt_tree->rates->tot_num_cal++; */
+	  /* if (mixt_tree->rates->calib == NULL) mixt_tree->rates->calib = Make_Calib(mixt_tree->n_otu); */
+
+	  low = -BIG;
+	  up  = BIG;
+
+	  xnd_dum = XML_Search_Node_Name("lower",YES,xnd_cal);
+	  if(xnd_dum != NULL) low = String_To_Dbl(xnd_dum->value); 
+
+	  xnd_dum = XML_Search_Node_Name("upper",YES,xnd_cal);
+	  if(xnd_dum != NULL) up = String_To_Dbl(xnd_dum->value);
+          
+          do
+            {
+              if(!strcmp("appliesto",xnd_cal->child->name)) 
+                {
+                  clade_name = XML_Get_Attribute_Value(xnd_cal->child,"clade.id");
+                  
+                  if(!clade_name)
+                    {
+                      PhyML_Printf("\n== Attribute 'value=CLADE_NAME' is mandatory");
+                      PhyML_Printf("\n== Please amend your XML file accordingly.");
+                      Exit("\n");
+                    }
+                  
+                  if(strcmp("root",clade_name))
+                    {
+                      xml_node *xnd_clade;
+                        
+                      xnd_clade = XML_Search_Node_Generic("clade","id",clade_name,YES,xroot);
+                      
+                      if(xnd_clade != NULL) // found clade with a given name
+                        {
+                          char **clade;
+                          int clade_size,nd_num;
+                          t_cal *cal;
+
+                          clade      = XML_Read_Clade(xnd_clade->child,mixt_tree);
+                          clade_size = XML_Number_Of_Taxa_In_Clade(xnd_clade->child);
+                          // TO DO: chain all calibrations
+                          cal        = Make_Calibration();
+                          
+                          Init_Calibration(cal);
+
+                          mixt_tree->rates->a_cal[mixt_tree->rates->n_cal] = cal;
+                          mixt_tree->rates->n_cal++;
+
+                          cal->is_primary   = YES;
+                          cal->target_tax   = clade;
+                          cal->n_target_tax = clade_size;
+                          cal->lower        = low;
+                          cal->upper        = up;
+
+                          nd_num = Find_Clade(clade,clade_size,mixt_tree);
+
+                          PhyML_Printf("\n. Node number to which calibration [%s] applies to is [%d]",clade_name,nd_num);                          
+                          PhyML_Printf("\n. Lower bound set to: %15f time units.",low);
+                          PhyML_Printf("\n. Upper bound set to: %15f time units.",up);
+                          PhyML_Printf("\n. .......................................................................");
+                        }
+                      else
+                        {
+                          PhyML_Printf("\n== Calibration information for clade [%s] was not found.", clade_name);
+                          PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__);
+                          Exit("\n");
+                        }                      
+                    }
+                }
+              xnd_cal->child = xnd_cal->child->next;
+            }
+          while(xnd_cal->child != NULL);
+        }
+          /* mixt_tree->rates->calib = mixt_tree->rates->calib->next;	    */
+      xnd = xnd->next;
+    }
+  while(xnd != NULL);
+ 
+  DATE_Chain_Cal(mixt_tree);
+  TIMES_Randomize_Tree_With_Time_Constraints(mixt_tree->rates->a_cal[0], mixt_tree);
+  
+  Print_Node(mixt_tree->n_root,mixt_tree->n_root->v[1],mixt_tree);
+  Print_Node(mixt_tree->n_root,mixt_tree->n_root->v[2],mixt_tree);
+
+  mixt_tree->rates->birth_rate = 0.10;
+  mixt_tree->rates->death_rate = 0.05;
+  mixt_tree->rates->bl_from_rt = YES;
+  mixt_tree->rates->clock_r    = 0.01 / FABS(mixt_tree->rates->nd_t[mixt_tree->n_root->num]);
+  mixt_tree->rates->model      = STRICTCLOCK;
+
+  RATES_Update_Cur_Bl(mixt_tree);
+
+  res = DATE_MCMC(mixt_tree);
+
+  Free(res);
+  Free(clade_name);
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+// Update t_prior_min and t_prior_max on a given ranked tree
+// given (primary and secondary) calibration information.
+// Make sure secondary and primary calibration are up-to-date
+void DATE_Update_T_Prior_MinMax(t_tree *tree)
+{
+  int i,j,*rk;
+
+  rk = tree->rates->t_rank;
+
+  for(i=tree->n_otu;i<2*tree->n_otu-1;i++) // All internal nodes 
+    {
+      tree->rates->t_prior_max[i] = 0.0;
+      tree->rates->t_prior_min[i] = -INFINITY;
+
+      if(tree->a_nodes[i]->n_cal > 0) // Primary calibration found on that node
+        {
+          For(j,tree->a_nodes[i]->n_cal)
+            {
+              tree->rates->t_prior_max[i] = MIN(tree->rates->t_prior_max[i],tree->a_nodes[i]->cal[j]->upper);
+              tree->rates->t_prior_min[i] = MAX(tree->rates->t_prior_min[i],MAX(tree->a_nodes[i]->cal[j]->lower,tree->rates->nd_t[tree->n_root->num]));
+            }
+        }
+      else
+        {
+          if(tree->a_nodes[i] != tree->n_root)
+            {                        
+              tree->rates->t_prior_max[i] = 0.0;
+              tree->rates->t_prior_min[i] = tree->rates->nd_t[tree->n_root->num];
+            }        
+        }
+    }
+
+  // TO DO: chain t_rank
+  TIMES_Update_Node_Ordering(tree);
+
+  For(i,tree->n_otu-1)
+    {
+      for(j=i+1;j<tree->n_otu-1;j++)
+        {
+          if(tree->rates->t_prior_min[rk[j]] < tree->rates->t_prior_min[rk[i]])
+            tree->rates->t_prior_min[rk[j]] = tree->rates->t_prior_min[rk[i]];
+
+          if(tree->rates->t_prior_max[rk[i]] > tree->rates->t_prior_max[rk[j]])
+            tree->rates->t_prior_max[rk[i]] = tree->rates->t_prior_max[rk[j]];
+        }
+    }
+  
+  /* For(i,tree->n_otu-1)  */
+  /*   { */
+  /*     PhyML_Printf("\n. node: %3d t: %12f min: %13G max: %13G %f", */
+  /*                  rk[i], */
+  /*                  tree->rates->nd_t[rk[i]], */
+  /*                  tree->rates->t_prior_min[rk[i]], */
+  /*                  tree->rates->t_prior_max[rk[i]], */
+  /*                  tree->rates->c_lnL_times); */
+  /*     fflush(NULL); */
+  /*     assert(tree->rates->t_prior_min[rk[i]] < tree->rates->t_prior_max[rk[i]]);  */
+  /*   } */
+
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void DATE_Assign_Primary_Calibration(t_tree *tree)
+{
+  int i,j,idx,node_num;
+  
+  For(i,2*tree->n_otu-1) 
+    For(j,MAX_N_CAL) 
+    {
+      tree->a_nodes[i]->cal[j] = NULL;
+      tree->a_nodes[i]->n_cal  = 0;
+    }
+  
+  For(i,tree->rates->n_cal)
+    {
+      node_num = Find_Clade(tree->rates->a_cal[i]->target_tax,
+                            tree->rates->a_cal[i]->n_target_tax,
+                            tree);
+      
+      idx = tree->a_nodes[node_num]->n_cal;
+      tree->a_nodes[node_num]->cal[idx] = tree->rates->a_cal[i];
+      tree->a_nodes[node_num]->n_cal++;
+
+      if(tree->a_nodes[node_num]->n_cal == MAX_N_CAL)
+        {
+          PhyML_Printf("\n== A node cannot have more than %d calibration",MAX_N_CAL); 
+          PhyML_Printf("\n== constraints attached to it. Feel free to increase the"); 
+          PhyML_Printf("\n== value of the variable MAX_N_CAL in utilities.h if");
+          PhyML_Printf("\n== necessary.");
+          Exit("\n");
+        }
+
+      /* printf("\n. Assign cal [%f %f] to %d (%d)", */
+      /*        tree->rates->a_cal[i]->lower, */
+      /*        tree->rates->a_cal[i]->upper, */
+      /*        node_num, */
+      /*        tree->a_nodes[node_num]->n_cal); */
+      /* int j; */
+      /* For(j,tree->rates->a_cal[i]->n_target_tax) */
+      /*   printf("\n> %s",tree->rates->a_cal[i]->target_tax[j]); */
+    }
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+// Return splitted calibration intervals. Make sure all primary
+// and secondary calibration intervals are up-to-date.
+phydbl *DATE_Splitted_Calibration(t_tree *tree)
+{
+  phydbl *minmax,*splitted_cal,buff;
+  int i,len,done;
+
+  // One t_prior_min and one t_prior_max per internal nodes except root, so 
+  // 2 x # of internal nodes boundaries in total at most.
+  minmax = (phydbl *)mCalloc(2*(tree->n_otu-2),sizeof(phydbl));
+  For(i,2*(tree->n_otu-2)) minmax[i] = +INFINITY;
+  splitted_cal = (phydbl *)mCalloc((int)(4*tree->n_otu-10),sizeof(phydbl));
+
+
+  len = 0;
+  for(i = tree->n_otu; i < 2*tree->n_otu-1; i++)
+    {
+      if(tree->a_nodes[i] != tree->n_root)
+        {
+          minmax[len]   = MAX(tree->rates->t_prior_min[i],tree->rates->nd_t[tree->n_root->num]);
+          minmax[len+1] = tree->rates->t_prior_max[i];        
+          len+=2;
+        }
+    }
+
+  
+  // Bubble sort of all these times in increasing order
+  do
+    {
+      done = YES;
+      For(i,len-1) 
+        {
+          if(minmax[i] > minmax[i+1])
+            {
+              buff        = minmax[i];
+              minmax[i]   = minmax[i+1];
+              minmax[i+1] = buff;
+              done = NO;
+            }
+        }
+    }
+  while(done == NO);
+
+  For(i,len-1) assert(!(minmax[i] > minmax[i+1]));
+  
+  // Remove ties
+  For(i,len-1) 
+    if(Are_Equal(minmax[i],minmax[i+1],1.E-6) == YES) 
+      minmax[i] = 0.0;
+
+  // Sort again to effectively remove ties
+  do
+    {
+      done = YES;
+      For(i,len-1) 
+        {
+          if(minmax[i] > minmax[i+1])
+            {
+              buff        = minmax[i];
+              minmax[i]   = minmax[i+1];
+              minmax[i+1] = buff;
+              done = NO;
+            }
+        }
+    }
+  while(done == NO);
+
+  splitted_cal[0] = minmax[0];
+  len = 1;
+  for(i = 1; i < 2*(tree->n_otu-2); i++)                                        
+    {
+      splitted_cal[len]   = minmax[i];
+      if(len+1 < 4*tree->n_otu-10) splitted_cal[len+1] = minmax[i];
+      len+=2;
+    }
+
+  /* For(i,4*tree->n_otu-10) PhyML_Printf("\n. split -- %3d %12f",i,splitted_cal[i]); */
+
+  Free(minmax);
+   
+  return splitted_cal;
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+phydbl DATE_J_Sum_Product(t_tree *tree)
+{
+  phydbl prod, total,*splitted_cal;
+  int fact,idx,ans,rk;
+  
+  DATE_Assign_Primary_Calibration(tree);
+  DATE_Update_T_Prior_MinMax(tree);
+
+  splitted_cal = DATE_Splitted_Calibration(tree);
+  
+  ans   = 0;
+  total = 0.0;
+  idx   = 0;
+  rk    = 1;
+  do
+    {
+      prod = 1.0;
+      fact = 1;
+      ans = DATE_J_Sum_Product_Pre(tree->a_nodes[tree->rates->t_rank[rk]], // Oldest node after root (as rk=1)
+                                   idx,
+                                   -1,
+                                   prod,fact,&total,splitted_cal,rk,tree);
+      idx+=2;
+    }
+  while(ans != 1);
+
+  return(total);
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+int DATE_J_Sum_Product_Pre(t_node *d, int split_idx_d, int split_idx_a, phydbl prod, int fact, phydbl *total, phydbl *splitted_cal, int rk, t_tree *tree)
+{
+  int ans,idx;
+
+  ans = DATE_Is_Split_Accessible(d,split_idx_d,splitted_cal,tree);
+
+  /* printf("\n. IN d: %d [%12f %12f] %d ans: %d prod: %f fact: %d", */
+  /*        d->num, */
+  /*        splitted_cal[split_idx_d], */
+  /*        splitted_cal[split_idx_d+1], */
+  /*        tree->rates->t_rank[d->num],ans,prod,fact); */
+
+  switch(ans)
+    {
+    case 1 : // split interval is younger than t_prior_max. No need to go further.
+      {
+        return ans;
+        break;
+      }
+    case 0 : // split interval is within [t_prior_min,t_prior_max]
+      {
+        int local_ans;
+
+        // Calculate J for this time interval
+        prod *= DATE_J(tree->rates->birth_rate, 
+                       tree->rates->death_rate,
+                       FABS(splitted_cal[split_idx_d+1]),
+                       FABS(splitted_cal[split_idx_d]));
+        
+        // Remove factorial term from current product
+        prod *= fact;
+        
+        if(split_idx_d == split_idx_a) fact++;
+        else fact = 1;
+        
+        prod /= fact;
+        
+        /* PhyML_Printf("\n. Node: %d [%12f %12f] %4d %4d [%12G %12G] %4d", */
+        /*              d->num, */
+        /*              splitted_cal[split_idx_d], */
+        /*              splitted_cal[split_idx_d+1], */
+        /*              split_idx_a, */
+        /*              split_idx_d, */
+        /*              prod,*total,fact); */
+        
+        /* fflush(NULL); */
+        
+        if(tree->rates->t_rank[tree->n_otu-2] == d->num) // Youngest internal node 
+          {
+            (*total) += prod;
+            /* printf(" == total: %f",*total); */
+            return 0;
+          }
+
+        idx = split_idx_d;
+        do
+          {
+            local_ans = DATE_J_Sum_Product_Pre(tree->a_nodes[tree->rates->t_rank[rk+1]],
+                                               idx,
+                                               split_idx_d,
+                                               prod,fact,total,splitted_cal,rk+1,tree);
+            idx+=2;
+          }
+        while(local_ans == 0);
+
+        break;
+      }
+    case -1 : // split interval is older than t_prior_min. Move forward.
+      {
+        int local_ans;
+        // Advance to younger split intervals and stop once you're in
+        idx = split_idx_d+2;
+        do
+          {
+            local_ans = DATE_J_Sum_Product_Pre(d,
+                                         idx,
+                                         idx+1,
+                                         prod,fact,total,splitted_cal,rk,tree);
+            idx+=2;
+          }
+        while(local_ans == -1);
+        break;
+      }
+    }
+
+  /* printf("\n. OUT d: %d [%12f %12f] %d ans: %d", */
+  /*        d->num, */
+  /*        splitted_cal[split_idx_d], */
+  /*        splitted_cal[split_idx_d+1], */
+  /*        tree->rates->t_rank[d->num],ans); */
+
+  return ans;
+}
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+int DATE_Is_Split_Accessible(t_node *d, int which, phydbl *splitted_cal, t_tree *tree)
+{
+  phydbl eps;
+
+  assert(d->tax == NO);
+
+  eps = FABS(tree->rates->t_prior_min[d->num]) / 1.E+6;
+
+  assert(eps > MDBL_MIN);
+
+  // Upper and lower bound of splitted calibration interval are equal to zero
+  if(Are_Equal(splitted_cal[which],0.0,eps) && Are_Equal(splitted_cal[which+1],0.0,eps)) return +1;
+
+
+  if(Are_Equal(tree->rates->t_prior_min[d->num],splitted_cal[which],eps)   ||
+     Are_Equal(tree->rates->t_prior_max[d->num],splitted_cal[which+1],eps) ||
+     (tree->rates->t_prior_min[d->num] < splitted_cal[which] && 
+      tree->rates->t_prior_max[d->num] > splitted_cal[which+1]))                   return  0; // splitted interval is within [t_prior_min,t_prior_max]
+  else if(Are_Equal(tree->rates->t_prior_max[d->num],splitted_cal[which],eps) ||
+          splitted_cal[which] > tree->rates->t_prior_max[d->num])                  return +1; // splitted interval is younger than [t_prior_min,t_prior_max]
+  else if(Are_Equal(tree->rates->t_prior_min[d->num],splitted_cal[which+1],eps) ||
+          splitted_cal[which+1] < tree->rates->t_prior_min[d->num])                return -1; // splitted interval is older than [t_prior_min,t_prior_max]
+  else
+    {
+      PhyML_Printf("\n== d->num: %d d->tax: %d",d->num,d->tax);
+      PhyML_Printf("\n== t_prior_min: %f t_prior_max: %f",
+                   tree->rates->t_prior_min[d->num],
+                   tree->rates->t_prior_max[d->num]);
+      PhyML_Printf("\n== splitted_cal_min: %f splitted_cal_max: %f",
+                   splitted_cal[which],
+                   splitted_cal[which+1]);      
+      PhyML_Printf("\n");
+      assert(FALSE); // splitted interval cannot be partially overlapping [t_prior_min,t_prior_max]
+    }
+  return(0);
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+phydbl DATE_J(phydbl birth_r, phydbl death_r, phydbl t_min, phydbl t_pls)
+{
+  phydbl d,b,J;
+  assert(t_pls > t_min);
+  d = death_r;
+  b = birth_r;
+  J = (b-d)*(EXP(t_min*d+t_pls*b) - EXP(t_min*b+t_pls*d));
+  J /= ((b*EXP(t_min*b)-d*EXP(t_min*d)) * (b*EXP(t_pls*b)-d*EXP(t_pls*d)));
+  /* printf("  J : %f",J); */
+  return(J);
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void DATE_Chain_Cal(t_tree *mixt_tree)
+{
+  int i;
+  For(i,mixt_tree->rates->n_cal-1) 
+    {
+      mixt_tree->rates->a_cal[i]->next   = mixt_tree->rates->a_cal[i+1];
+      mixt_tree->rates->a_cal[i+1]->prev = mixt_tree->rates->a_cal[i];
+    }
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+int DATE_Check_Calibration_Constraints(t_tree *tree)
+{
+  int i,j;
+  phydbl lower,upper;
+
+  lower = upper = -1.;
+
+  For(i,2*tree->n_otu-1)
+    {
+      if(tree->a_nodes[i]->n_cal > 1)
+        {
+          lower = tree->a_nodes[i]->cal[0]->lower;
+          upper = tree->a_nodes[i]->cal[0]->upper;
+          for(j=1; j < tree->a_nodes[i]->n_cal; j++)
+            {
+              lower = MAX(lower,tree->a_nodes[i]->cal[j]->lower);
+              upper = MIN(upper,tree->a_nodes[i]->cal[j]->upper);
+              if(upper < lower) 
+                {
+                  /* PhyML_Printf("\n. Inconsistency detected on node %d",i); */
+                  return 0; 
+                }
+            }
+        }
+    }
+  return 1;
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+int DATE_Check_Time_Constraints(t_tree *tree)
+{
+  int i;
+
+  For(i,2*tree->n_otu-1)
+    {
+      if(tree->a_nodes[i] != tree->n_root && tree->a_nodes[i]->tax == NO)
+        {
+          if(tree->rates->nd_t[i] > tree->rates->t_prior_max[i] ||
+             tree->rates->nd_t[i] < tree->rates->t_prior_min[i])
+            {
+              return 0;
+            }
+        }
+    }
+  return 1;
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+phydbl *DATE_MCMC(t_tree *tree)
+{
+  t_mcmc *mcmc;
+  int move, n_vars, i, adjust_len;
+  phydbl u;
+  phydbl *res;
+  FILE *fp_stats;
+
+  fp_stats = tree->io->fp_out_stats;
+
+  mcmc = MCMC_Make_MCMC_Struct();
+
+  tree->mcmc = mcmc;
+
+  MCMC_Init_MCMC_Struct(NULL,NULL,mcmc);
+
+  MCMC_Complete_MCMC(mcmc,tree);
+
+  n_vars                = 10;
+  adjust_len            = 1E+6;
+  mcmc->sample_interval = 500;
+
+  res = (phydbl *)mCalloc(tree->mcmc->chain_len / tree->mcmc->sample_interval * n_vars,sizeof(phydbl));
+  
+  Lk(NULL,tree);
+  TIMES_Lk_Birth_Death(tree);
+  RATES_Lk_Rates(tree);
+
+  PhyML_Printf("\n. log(Pr(Seq|Tree)) = %f",tree->c_lnL);
+  PhyML_Printf("\n. log(Pr(Tree)) = %f",tree->rates->c_lnL_times);
+  
+  PhyML_Fprintf(fp_stats,"\n%s\t%s\t%s\t%s\t%s",
+                "sample",
+                "lnL(seq)",
+                "lnL(times)",
+                "birth",
+                "death");
+  fflush(NULL);
+
+  For(i,2*tree->n_otu-1)
+    {
+      if(tree->a_nodes[i]->tax == NO)
+        {
+          PhyML_Fprintf(fp_stats,"\t%s%d",
+                        "t",i);
+        }
+    }
+  fflush(NULL);
+
+
+
+  For(i,mcmc->n_moves) tree->mcmc->start_ess[i] = YES;
+
+  Set_Both_Sides(NO,tree);
+  mcmc->use_data   = YES; 
+  mcmc->always_yes = NO;
+  move             = -1;
+  do
+    {
+
+      /* tree->mcmc->adjust_tuning[i] = NO; */
+      if(mcmc->run > adjust_len) For(i,mcmc->n_moves) tree->mcmc->adjust_tuning[i] = NO;
+
+      if(tree->c_lnL < UNLIKELY + 0.1)
+        {
+          PhyML_Printf("\n== Move '%s' failed\n",tree->mcmc->move_name[move]);
+          assert(FALSE);
+        }
+
+      u = Uni();
+
+      For(move,tree->mcmc->n_moves) if(tree->mcmc->move_weight[move] > u-1.E-10) break;
+
+      assert(!(move == tree->mcmc->n_moves));      
+
+      if(!strcmp(tree->mcmc->move_name[move],"birth_rate"))  MCMC_Birth_Rate(tree);
+      if(!strcmp(tree->mcmc->move_name[move],"death_rate"))  MCMC_Death_Rate(tree);
+      if(!strcmp(tree->mcmc->move_name[move],"tree_height")) MCMC_Tree_Height(tree);
+      if(!strcmp(tree->mcmc->move_name[move],"time"))        MCMC_Time_All(tree);
+      if(!strcmp(tree->mcmc->move_name[move],"spr"))         MCMC_Prune_Regraft(tree);
+
+      tree->mcmc->run++;
+      MCMC_Get_Acc_Rates(tree->mcmc);
+
+      if(!(tree->mcmc->run%tree->mcmc->sample_interval))
+        {
+          PhyML_Fprintf(fp_stats,"\n%6d\t%9.1f\t%9.1f\t%12G\t%12G",
+                        tree->mcmc->run,
+                        tree->c_lnL,
+                        tree->rates->c_lnL_times,
+                        tree->rates->birth_rate,
+                        tree->rates->death_rate);
+          fflush(NULL);
+
+          For(i,2*tree->n_otu-1)
+            {
+              if(tree->a_nodes[i]->tax == NO)
+                {
+                  PhyML_Fprintf(fp_stats,"\t%12G",
+                                tree->rates->nd_t[i]);
+                }
+            }
+          fflush(NULL);
+
+          tree->mcmc->sample_num++;
+        }
+    }
+  while(tree->mcmc->run < tree->mcmc->chain_len);
+
+
+  return(res);
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
diff --git a/src/date.h b/src/date.h
new file mode 100644
index 0000000..3ae2f70
--- /dev/null
+++ b/src/date.h
@@ -0,0 +1,41 @@
+/*
+
+PhyML:  a program that  computes maximum likelihood phylogenies from
+DNA or AA homologous sequences.
+
+Copyright (C) Stephane Guindon. Oct 2003 onward.
+
+All parts of the source except where indicated are distributed under
+the GNU public licence. See http://www.opensource.org for details.
+
+*/
+
+#include <config.h>
+
+#ifndef DATE_H
+#define DATE_H
+
+#include "utilities.h"
+
+int DATE_Main(int argc, char **argv);
+void DATE_XML(char *xml_filename);
+void DATE_Update_Secondary_Cal(t_tree *tree);
+void DATE_Update_Secondary_Cal_Post(t_node *a, t_node *d, t_tree *tree);
+void DATE_Update_Secondary_Cal_Pre(t_node *a, t_node *d, t_tree *tree);
+phydbl *DATE_Splitted_Calibration(t_tree *tree);
+void DATE_Assign_Primary_Calibration(t_tree *tree);
+void DATE_Update_T_Prior_MinMax(t_tree *tree);
+phydbl DATE_J(phydbl birth_r, phydbl death_r, phydbl t_min, phydbl t_pls);
+int DATE_Is_Split_Accessible(t_node *d, int which, phydbl *splitted_cal, t_tree *tree);
+phydbl *DATE_Splitted_Calibration(t_tree *tree);
+phydbl DATE_J_Sum_Product(t_tree *tree);
+int DATE_J_Sum_Product_Pre(t_node *d, int split_idx_d, int split_idx_a, phydbl prod, int fact, phydbl *total, phydbl *splitted_cal, int rk, t_tree *tree);
+void DATE_Chain_Cal(t_tree *mixt_tree);
+int DATE_Check_Calibration_Constraints(t_tree *tree);
+int DATE_Check_Time_Constraints(t_tree *tree);
+phydbl *DATE_MCMC(t_tree *tree);
+
+
+
+
+#endif
diff --git a/src/free.c b/src/free.c
index 10ef233..20fd375 100644
--- a/src/free.c
+++ b/src/free.c
@@ -103,6 +103,8 @@ void Free_Node(t_node *n)
   Free(n->score);
   Free(n->s_ingrp);
   Free(n->s_outgrp);
+  Free(n->cal);
+
   if(n->c_seq_anc != NULL) 
     {
       Free(n->c_seq_anc->state);
@@ -222,10 +224,11 @@ void Free_Bip(t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-void Free_Cseq(calign *data)
+void Free_Calign(calign *data)
 {
   int i;
 
+  if(data->io_wght) Free_Scalar_Dbl(data->io_wght);
   Free(data->invar);
   Free(data->wght);
   Free(data->ambigu);
@@ -270,7 +273,7 @@ void Free_Seq(align **d, int n_otu)
 
 void Free_All(align **d, calign *cdata, t_tree *tree)
 {
-  Free_Cseq(cdata);
+  Free_Calign(cdata);
   Free_Seq(d,tree->n_otu);
   Free_Tree(tree);
 }
@@ -321,17 +324,13 @@ void Free_Tree_Pars(t_tree *mixt_tree)
 
       For(i,2*tree->n_otu-3) 
         {
-          /* printf("\n. FREE b->num: %d %p %p",tree->a_edges[i]->num,tree->a_edges[i]->pars_l,tree->a_edges[i]->pars_r); */
           Free_Edge_Pars(tree->a_edges[i]);
         }
 
       if(tree->n_root)
         {
-          /* printf("\n. FREE b1->num: %d %p %p",tree->n_root->b[1]->num,tree->n_root->b[1]->pars_l,tree->n_root->b[1]->pars_r); */
           Free_Edge_Pars_Left(tree->n_root->b[1]);
           Free_Edge_Pars_Left(tree->n_root->b[2]);
-          /* if(tree->n_root->b[1]->pars_r) Free_Edge_Pars_Rght(tree->n_root->b[1]); */
-          /* if(tree->n_root->b[2]->pars_r) Free_Edge_Pars_Rght(tree->n_root->b[2]); */
         }
       else
         {
@@ -399,24 +398,29 @@ void Free_Tree_Lk(t_tree *mixt_tree)
       Free(tree->unscaled_site_lk_cat);
 
       For(i,2*tree->n_otu-3) Free_Edge_Lk(tree->a_edges[i]);
+      For(i,2*tree->n_otu-3) Free_Edge_Loc(tree->a_edges[i]);
 
       if(tree->n_root)
         {
-          Free(tree->n_root->b[1]->nni);
-          Free(tree->n_root->b[2]->nni);
+          Free_NNI(tree->n_root->b[1]->nni);
+          Free_NNI(tree->n_root->b[2]->nni);
           Free(tree->n_root->b[1]->Pij_rr);
           Free(tree->n_root->b[2]->Pij_rr);
           Free_Edge_Lk_Left(tree->n_root->b[1]);
           Free_Edge_Lk_Left(tree->n_root->b[2]);
-          /* if(tree->n_root->b[1]->p_lk_rght) Free_Edge_Lk_Rght(tree->n_root->b[1]); */
-          /* if(tree->n_root->b[2]->p_lk_rght) Free_Edge_Lk_Rght(tree->n_root->b[2]); */
+          Free_Edge_Loc_Left(tree->n_root->b[1]);
+          Free_Edge_Loc_Left(tree->n_root->b[2]);
         }
       else
         {
           Free_Edge_Lk(tree->a_edges[2*tree->n_otu-3]);
           Free_Edge_Lk(tree->a_edges[2*tree->n_otu-2]);
+          Free_Edge_Loc(tree->a_edges[2*tree->n_otu-3]);
+          Free_Edge_Loc(tree->a_edges[2*tree->n_otu-2]);
         }
+
       tree = tree->next;
+
     }
   while(tree);
 
@@ -444,12 +448,9 @@ void Free_Edge_Lk_Rght(t_edge *b)
       if(b->sum_scale_rght) Free(b->sum_scale_rght);
     }
 
-  if(b->p_lk_tip_r) Free(b->p_lk_tip_r);
-
-  Free(b->sum_scale_rght_cat);
-  Free(b->patt_id_rght);
-  Free(b->p_lk_loc_rght);
-
+  if(b->p_lk_tip_r)         Free(b->p_lk_tip_r);
+  if(b->sum_scale_rght_cat) Free(b->sum_scale_rght_cat);
+  if(b->patt_id_rght)       Free(b->patt_id_rght);
 }
 
 //////////////////////////////////////////////////////////////
@@ -466,12 +467,9 @@ void Free_Edge_Lk_Left(t_edge *b)
       if(b->sum_scale_left) Free(b->sum_scale_left);
     }
 
-  if(b->p_lk_tip_l) Free(b->p_lk_tip_l);
-
-  Free(b->sum_scale_left_cat);
-  Free(b->patt_id_left);
-  Free(b->p_lk_loc_left);
-
+  if(b->p_lk_tip_l)         Free(b->p_lk_tip_l);
+  if(b->sum_scale_left_cat) Free(b->sum_scale_left_cat);
+  if(b->patt_id_left)       Free(b->patt_id_left);
 }
 
 //////////////////////////////////////////////////////////////
@@ -479,7 +477,7 @@ void Free_Edge_Lk_Left(t_edge *b)
 
 void Free_Edge_Lk(t_edge *b)
 {
-  Free(b->nni);
+  Free_NNI(b->nni);
   Free(b->Pij_rr);
   Free_Edge_Lk_Left(b);
   Free_Edge_Lk_Rght(b);
@@ -488,6 +486,31 @@ void Free_Edge_Lk(t_edge *b)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
+void Free_Edge_Loc_Rght(t_edge *b)
+{
+  if(b->p_lk_loc_rght) Free(b->p_lk_loc_rght);
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void Free_Edge_Loc_Left(t_edge *b)
+{
+  if(b->p_lk_loc_left) Free(b->p_lk_loc_left);
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void Free_Edge_Loc(t_edge *b)
+{
+  Free_Edge_Loc_Left(b);
+  Free_Edge_Loc_Rght(b);
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
 void Free_Model_Complete(t_mod *mixt_mod)
 {
   Free_Eigen(mixt_mod->eigen);
@@ -501,19 +524,60 @@ void Free_Model_Complete(t_mod *mixt_mod)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
+void Free_Rmat_Weights(t_mod *mixt_mod)
+{
+  t_mod *mod;
+
+  mod = mixt_mod;
+
+  do
+    {
+      Free(mod->r_mat_weight);
+      mod = mod->next_mixt;
+    }
+  while(mod);
+
+  if(mixt_mod->next) Free_Scalar_Dbl(mixt_mod->next->r_mat_weight);
+
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void Free_Efrq_Weights(t_mod *mixt_mod)
+{
+  t_mod *mod;
+
+  mod = mixt_mod;
+
+  do
+    {
+      Free(mod->e_frq_weight);
+      mod = mod->next_mixt;
+    }
+  while(mod);
+
+  if(mixt_mod->next) Free_Scalar_Dbl(mixt_mod->next->e_frq_weight);
+
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
 void Free_Model_Basic(t_mod *mixt_mod)
 {
   t_mod *mod;
 
   Free_RAS(mixt_mod->ras);
-  Free_Vect_Dbl(mixt_mod->user_b_freq);
   Free_Scalar_Dbl(mixt_mod->mr);
   Free_Scalar_Dbl(mixt_mod->kappa);
   Free_Scalar_Dbl(mixt_mod->lambda);
   Free_Scalar_Dbl(mixt_mod->br_len_mult);
   Free_Scalar_Dbl(mixt_mod->br_len_mult_unscaled);
-  Free_Scalar_Dbl(mixt_mod->e_frq_weight);
-  Free_Scalar_Dbl(mixt_mod->r_mat_weight);
+
+  Free_Rmat_Weights(mixt_mod);
+  Free_Efrq_Weights(mixt_mod);
+
   Free_String(mixt_mod->modelname);
   Free_String(mixt_mod->custom_mod_string);
   Free_String(mixt_mod->aa_rate_mat_file);
@@ -543,6 +607,8 @@ void Free_Vect_Dbl(vect_dbl *v)
 {
   vect_dbl *next;
 
+  assert(v);
+
   next = v->next;
   do
     {
@@ -561,6 +627,8 @@ void Free_Vect_Dbl(vect_dbl *v)
 void Free_Scalar_Dbl(scalar_dbl *v)
 {
   scalar_dbl *next;
+  
+  assert(v);
 
   next = v->next;
   do
@@ -575,6 +643,25 @@ void Free_Scalar_Dbl(scalar_dbl *v)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
+void Free_Linked_List(t_ll *t)
+{
+  t_ll *next;
+
+  assert(t);
+
+  next = t->next;
+  do
+    {
+      Free(t);
+      t = next;
+      if(t) next = t->next;
+    }
+  while(t);
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
 void Free_String(t_string *ts)
 {
   t_string *next;
@@ -609,6 +696,9 @@ void Free_Efrq(t_efrq *e_frq)
   Free(e_frq->pi_unscaled->v);
   Free(e_frq->pi_unscaled);
 
+  Free(e_frq->user_b_freq->v);
+  Free(e_frq->user_b_freq);
+
   if(e_frq->next) Free_Efrq(e_frq->next);
 
   Free(e_frq);
@@ -717,10 +807,12 @@ void Free_Input(option *io)
       Free(io->out_boot_tree_file);
       Free(io->out_boot_stats_file);
       Free(io->out_stats_file);
+      Free(io->weight_file);
       Free(io->out_lk_file);
       Free(io->out_summary_file);
       Free(io->out_ps_file);
       Free(io->out_trace_file);
+      Free(io->out_json_trace_file);
       Free(io->out_ancestral_file);
       Free(io->nt_or_cd);
       Free(io->run_id_string);
@@ -774,7 +866,7 @@ void Free_St(supert_tree *st)
   int i;
 
   For(i,2*st->tree->n_otu-1)
-    Free(st->tree->a_edges[i]->nni);
+    Free_NNI(st->tree->a_edges[i]->nni);
 
   For(i,st->n_part) Free(st->match_st_node_in_gt[i]);
 
@@ -812,7 +904,17 @@ void Free_Eigen(eigen *eigen_struct)
 void Free_One_Spr(t_spr *this_spr)
 {
   Free(this_spr->path);
-  Free(this_spr);
+  if(this_spr->l0) Free_Scalar_Dbl(this_spr->l0);
+  if(this_spr->l1) Free_Scalar_Dbl(this_spr->l1);
+  if(this_spr->l2) Free_Scalar_Dbl(this_spr->l2);
+  if(this_spr->v0) Free_Scalar_Dbl(this_spr->v0);
+  if(this_spr->v1) Free_Scalar_Dbl(this_spr->v1);
+  if(this_spr->v2) Free_Scalar_Dbl(this_spr->v2);
+  
+  if(this_spr->init_target_l) Free_Scalar_Dbl(this_spr->init_target_l);
+  if(this_spr->init_target_v) Free_Scalar_Dbl(this_spr->init_target_v);
+  
+  Free(this_spr);  
 }
 
 //////////////////////////////////////////////////////////////
@@ -1087,6 +1189,8 @@ void RATES_Free_Rates(t_rate *rates)
 {
   if(rates->is_allocated == YES)
     {
+      int i;
+
       Free(rates->nd_r);
       Free(rates->br_r);
       Free(rates->buff_r);
@@ -1138,15 +1242,14 @@ void RATES_Free_Rates(t_rate *rates)
       Free(rates->has_survived);
       Free(rates->survival_rank);
       Free(rates->survival_dur);
-      Free(rates->calib_prob);
       Free(rates->node_height_dens_log_norm_const_update);
-      Free(rates->curr_nd_for_cal);
       Free(rates->t_prior_min_ori);
       Free(rates->t_prior_max_ori);
       Free(rates->times_partial_proba);
       Free(rates->numb_calib_chosen);
+      For(i,rates->n_cal) Free_Calib(rates->a_cal[i]);
+      Free(rates->a_cal);
     }
-  Free_Calib(rates->calib);
   Free(rates);
 }
 
@@ -1155,9 +1258,19 @@ void RATES_Free_Rates(t_rate *rates)
 
 void Free_Calib(t_cal *cal)
 {
+  
   if(!cal) return;
-  else Free_Calib(cal->next);
-  Free(cal);
+  else 
+    {      
+      Free_Calib(cal->next);
+      if(cal->target_tax != NULL)
+        {
+          int i;
+          For(i,cal->n_target_tax) Free(cal->target_tax[i]);
+          Free(cal->target_tax);
+        }
+      Free(cal);
+    }
 }
 
 /*////////////////////////////////////////////////////////////
@@ -1240,10 +1353,61 @@ void Free_Mmod(t_phyrex_mod *mmod)
   Free_Geo_Coord(mmod->lim);
   Free(mmod);
 }
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void JSON_Free_Array(json_a *a)
+{
+  if(a->object) JSON_Free_Object(a->object);
+  Free(a);
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void JSON_Free_Object(json_o *o)
+{
+  if(o->sv) JSON_Free_StringVal(o->sv);
+  if(o->next) JSON_Free_Object(o->next);
+  Free(o);
+}
+
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
+void JSON_Free_StringVal(json_sv *sv)
+{
+  if(sv->string) Free(sv->string);
+  if(sv->value) Free(sv->value);
+  if(sv->object) JSON_Free_Object(sv->object);
+  if(sv->array) JSON_Free_Array(sv->array);
+  if(sv->next) JSON_Free_StringVal(sv->next);
+  Free(sv);
+}
+
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
+
+void Free_NNI(t_nni *t)
+{
+  if(t->init_l) Free_Scalar_Dbl(t->init_l);
+  if(t->init_v) Free_Scalar_Dbl(t->init_v);
+
+  if(t->best_l) Free_Scalar_Dbl(t->best_l);
+  if(t->best_v) Free_Scalar_Dbl(t->best_v);
+  
+  if(t->l0) Free_Scalar_Dbl(t->l0);
+  if(t->v0) Free_Scalar_Dbl(t->v0);
+
+  if(t->l1) Free_Scalar_Dbl(t->l1);
+  if(t->v1) Free_Scalar_Dbl(t->v1);
+
+  if(t->l2) Free_Scalar_Dbl(t->l2);
+  if(t->v2) Free_Scalar_Dbl(t->v2);
+  
+  Free(t);
+}
+
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
diff --git a/src/free.h b/src/free.h
index 868325c..b01b4fe 100644
--- a/src/free.h
+++ b/src/free.h
@@ -26,7 +26,7 @@ void Free_Bip(t_tree *tree);
 void Free_Edge_Labels(t_edge *b);
 void Free_Edge(t_edge *b);
 void Free_Node(t_node *n);
-void Free_Cseq(calign *data);
+void Free_Calign(calign *data);
 void Free_Seq(align **d,int n_otu);
 void Free_All(align **d,calign *cdata,t_tree *tree);
 void Free_SubTree(t_edge *b_fcus,t_node *a,t_node *d,t_tree *tree);
@@ -79,5 +79,15 @@ void Free_Disk(t_dsk *t);
 void Free_Ldisk(t_ldsk *t);
 void Free_Poly(t_poly *p);
 void Free_Mmod(t_phyrex_mod *mmod);
+void Free_Efrq_Weights(t_mod *mixt_mod);
+void Free_Rmat_Weights(t_mod *mixt_mod);
+void JSON_Free_StringVal(json_sv *sv);
+void JSON_Free_Object(json_o *o);
+void JSON_Free_Array(json_a *a);
+void Free_Edge_Loc_Rght(t_edge *b);
+void Free_Edge_Loc_Left(t_edge *b);
+void Free_Edge_Loc(t_edge *b);
+void Free_NNI(t_nni *t);
+void Free_Linked_List(t_ll *t);
 
 #endif
diff --git a/src/init.c b/src/init.c
index e3ac4ee..717ba7b 100644
--- a/src/init.c
+++ b/src/init.c
@@ -86,10 +86,12 @@ void Init_Triplet_Struct(triplet *t)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-void Init_Efrq(t_efrq *f)
+void Init_Efrq(phydbl *b_frq, t_efrq *f)
 {
-  f->next = NULL;
-  f->prev = NULL;
+  f->user_state_freq      = NO;
+  f->empirical_state_freq = NO;
+  f->next                 = NULL;
+  f->prev                 = NULL;
 }
 
 //////////////////////////////////////////////////////////////
@@ -110,6 +112,7 @@ void Init_Tree(t_tree *tree, int n_otu)
   tree->prev                      = NULL;
   tree->mixt_tree                 = NULL;
   tree->geo                       = NULL;
+  tree->xml_root                  = NULL;
 
   tree->is_mixt_tree              = NO;
   tree->tree_num                  = 0;
@@ -147,6 +150,7 @@ void Init_Tree(t_tree *tree, int n_otu)
   tree->ignore_root               = YES;
   tree->annealing_temp            = 0.;
   tree->both_sides                = NO;
+  tree->json_num                  = 0;
 #ifdef BEAGLE
   tree->b_inst                    = UNINITIALIZED;
 #endif
@@ -225,23 +229,25 @@ void Init_Node_Light(t_node *n, int num)
   n->id_rank                = 0;
   n->next                   = NULL;
   n->prev                   = NULL;
-  /* n->next                  = NULL; */
+  n->n_cal                  = 0;
+  /* n->next                 = NULL; */
   /* n->prev                 = NULL; */
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
-void Init_NNI(nni *a_nni)
+void Init_NNI(t_nni *a_nni)
 {
   a_nni->left         = NULL;
   a_nni->rght         = NULL;
   a_nni->b            = NULL;
-  a_nni->init_l       = -1.;
+  a_nni->init_l       = NULL;
+  a_nni->init_v       = NULL;
   a_nni->init_lk      = .0;
   a_nni->score        = +1.0;
-  a_nni->best_l       = -1.;
+  a_nni->best_l       = NULL;
+  a_nni->best_v       = NULL;
   a_nni->swap_node_v1 = NULL;
   a_nni->swap_node_v2 = NULL;
   a_nni->swap_node_v3 = NULL;
@@ -249,9 +255,12 @@ void Init_NNI(nni *a_nni)
   a_nni->lk0          = UNLIKELY;
   a_nni->lk1          = UNLIKELY;
   a_nni->lk2          = UNLIKELY;
-  a_nni->l0           = -1.0;
-  a_nni->l1           = -1.0;
-  a_nni->l2           = -1.0;
+  a_nni->l0           = NULL;
+  a_nni->l1           = NULL;
+  a_nni->l2           = NULL;
+  a_nni->v0           = NULL;
+  a_nni->v1           = NULL;
+  a_nni->v2           = NULL;
 }
 
 //////////////////////////////////////////////////////////////
@@ -521,6 +530,9 @@ void Set_Defaults_Input(option* io)
   io->fp_out_stats               = NULL;
   io->fp_out_ancestral           = NULL;
   io->fp_in_coord                = NULL;
+  io->fp_out_trace               = NULL;
+  io->fp_weight_file             = NULL;
+  io->fp_out_json_trace          = NULL;
   io->long_tax_names             = NULL;
   io->short_tax_names            = NULL;
   io->lon                        = NULL;
@@ -549,7 +561,8 @@ void Set_Defaults_Input(option* io)
   io->r_seed                     = -1;
   io->collapse_boot              = 0;
   io->random_boot_seq_order      = YES;
-  io->print_trace                = 0;
+  io->print_trace                = NO;
+  io->print_json_trace           = NO;
   io->print_site_lnl             = 0;
   io->m4_model                   = NO;
   io->rm_ambigu                  = 0;
@@ -568,6 +581,7 @@ void Set_Defaults_Input(option* io)
   io->state_len                  = 1;
   io->ancestral                  = NO;
   io->use_xml                    = NO;
+  io->has_io_weights             = NO;
 #ifdef BEAGLE
   io->beagle_resource            = 0;
 #endif
@@ -689,7 +703,6 @@ void Set_Defaults_Optimiz(t_opt *s_opt)
   s_opt->n_rand_starts        = 5;
   s_opt->brent_it_max         = BRENT_IT_MAX;
   s_opt->steph_spr            = YES;
-  s_opt->user_state_freq      = NO;
   s_opt->opt_br_len_mult      = NO;
 
   /* s_opt->min_diff_lk_local    = 1.E-04; */
@@ -705,6 +718,7 @@ void Set_Defaults_Optimiz(t_opt *s_opt)
   s_opt->general_pars         = NO;
   s_opt->tree_size_mult       = 1;
   s_opt->opt_five_branch      = YES;
+  s_opt->nni_br_len_opt       = YES;
 
   s_opt->pars_thresh          = 5;
 
@@ -786,7 +800,7 @@ void RATES_Init_Rate_Struct(t_rate *rates, t_rate *existing_rates, int n_otu)
 {
   int i;
 
-  if(existing_rates && (existing_rates->model != -1))
+  if(existing_rates && existing_rates->model != -1)
     {
       rates->model = existing_rates->model;
     }
@@ -809,7 +823,7 @@ void RATES_Init_Rate_Struct(t_rate *rates, t_rate *existing_rates, int n_otu)
   else
     {
       PhyML_Printf("\n== Please initialize model properly.");
-      PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__);
+      PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__);
       Warn_And_Exit("");
     }
 
@@ -829,6 +843,10 @@ void RATES_Init_Rate_Struct(t_rate *rates, t_rate *existing_rates, int n_otu)
   rates->birth_rate_min   = 1.E-6;
   rates->birth_rate_max   = 1.E+1;
 
+  rates->death_rate       = 1.E-2;
+  rates->death_rate_min   = 1.E-6;
+  rates->death_rate_max   = 1.E+1;
+
   if(rates->model_log_rates == YES)
     {
       rates->max_rate  =  LOG(10.);
@@ -880,6 +898,7 @@ void RATES_Init_Rate_Struct(t_rate *rates, t_rate *existing_rates, int n_otu)
 
   rates->update_mean_l = NO;
   rates->update_cov_l  = NO;
+  rates->n_cal         = 0;
 
   rates->p_max         = 0.01;
 
@@ -923,7 +942,7 @@ void RATES_Init_Rate_Struct(t_rate *rates, t_rate *existing_rates, int n_otu)
           else
             {
               rates->t_has_prior[i] = NO;
-              rates->t_prior_max[i] =  BIG;
+              rates->t_prior_max[i] =  0.0;
               rates->t_prior_min[i] = -BIG;
             }
           
@@ -934,7 +953,6 @@ void RATES_Init_Rate_Struct(t_rate *rates, t_rate *existing_rates, int n_otu)
         }
     }
   
-  rates->calib = NULL;
   rates->update_time_norm_const = NO;
 }
 
@@ -943,27 +961,27 @@ void RATES_Init_Rate_Struct(t_rate *rates, t_rate *existing_rates, int n_otu)
 
 void Init_One_Spr(t_spr *a_spr)
 {
-  a_spr->lnL             = UNLIKELY;
-  a_spr->pars            = 1E+5;
-  a_spr->depth_path      = 0;
-  a_spr->dist            = 0;
-  a_spr->init_target_l   = -1.;
-  a_spr->init_target_v   = -1.;
-  a_spr->l0              = -1.;
-  a_spr->l1              = -1.;
-  a_spr->l2              = -1.;
-  a_spr->v0              = -1.;
-  a_spr->v1              = -1.;
-  a_spr->v2              = -1.;
-  a_spr->n_link          = NULL;
-  a_spr->n_opp_to_link   = NULL;
-  a_spr->b_opp_to_link   = NULL;
-  a_spr->b_target        = NULL;
-  a_spr->b_init_target   = NULL;
-  a_spr->next            = NULL;
-  a_spr->prev            = NULL;
-  a_spr->next           = NULL;
-  a_spr->prev          = NULL;
+  a_spr->lnL              = UNLIKELY;
+  a_spr->pars             = 1E+5;
+  a_spr->depth_path       = 0;
+  a_spr->dist             = 0;
+  a_spr->init_target_l    = NULL;
+  a_spr->init_target_v    = NULL;
+  a_spr->l0               = NULL;
+  a_spr->l1               = NULL;
+  a_spr->l2               = NULL;
+  a_spr->v0               = NULL;
+  a_spr->v1               = NULL;
+  a_spr->v2               = NULL;
+  a_spr->n_link           = NULL;
+  a_spr->n_opp_to_link    = NULL;
+  a_spr->b_opp_to_link    = NULL;
+  a_spr->b_target         = NULL;
+  a_spr->b_init_target    = NULL;
+  a_spr->next             = NULL;
+  a_spr->prev             = NULL;
+  a_spr->next             = NULL;
+  a_spr->prev             = NULL;
 }
 
 //////////////////////////////////////////////////////////////
@@ -976,6 +994,10 @@ void Init_Model(calign *data, t_mod *mod, option *io)
   int result;
   phydbl *dr, *di, *space;
 
+  assert(data);
+  assert(mod);
+  assert(io);
+
 #ifdef BEAGLE
   mod->b_inst = UNINITIALIZED; //prevents calling an uninitialized BEAGLE instance (for ex: prevents Update_Eigen(), Update_RAS(), from calling BEAGLE)
   mod->optimizing_topology = false;
@@ -985,8 +1007,6 @@ void Init_Model(calign *data, t_mod *mod, option *io)
 
   if(io->datatype == GENERIC) mod->whichmodel = JC69;
 
-  /* if(!mod->ras->invar) For(i,data->crunch_len) data->invar[i] = 0; */
-
   dr      = (phydbl *)mCalloc(  mod->ns,sizeof(phydbl));
   di      = (phydbl *)mCalloc(  mod->ns,sizeof(phydbl));
   space   = (phydbl *)mCalloc(2*mod->ns,sizeof(phydbl));
@@ -1025,16 +1045,6 @@ void Init_Model(calign *data, t_mod *mod, option *io)
         }
     }
   
-  /* mod->br_len_mult->v          = 1.0; */
-  /* mod->br_len_mult_unscaled->v = 1.0; */
-  
-  For(i,mod->ns)
-    {
-      mod->e_frq->pi->v[i] = data->b_frq[i];
-      mod->e_frq->pi_unscaled->v[i] = mod->e_frq->pi->v[i] * 100.;
-    }
-
-
   if(io->datatype == NT)
     {
       /* Set the substitution parameters to their default values
@@ -1049,7 +1059,7 @@ void Init_Model(calign *data, t_mod *mod, option *io)
         {
           For(i,6) mod->r_mat->rr_val->v[i] = 1.0;
 
-          /* Condition below is true for if custom model corresponds to TN93 or K80 */
+          /* Condition below is true if custom model corresponds to TN93 or K80 */
           if(mod->r_mat->rr_num->v[AC] == mod->r_mat->rr_num->v[AT] &&
              mod->r_mat->rr_num->v[AT] == mod->r_mat->rr_num->v[CG] &&
              mod->r_mat->rr_num->v[CG] == mod->r_mat->rr_num->v[GT] &&
@@ -1102,12 +1112,18 @@ void Init_Model(calign *data, t_mod *mod, option *io)
       
       if(mod->whichmodel == F81)
         {
+          if(mod->e_frq->user_state_freq == NO) Init_Efrqs_Using_Observed_Freqs(mod->e_frq,data->b_frq,mod->ns);  
+          else For(i,4) mod->e_frq->pi->v[i] = mod->e_frq->user_b_freq->v[i];
+          For(i,mod->ns) mod->e_frq->pi_unscaled->v[i] = mod->e_frq->pi->v[i] * 100.;
           mod->kappa->v = 1.;
           mod->update_eigen = NO;
         }
       
       if(mod->whichmodel == F84)
         {
+          if(mod->e_frq->user_state_freq == NO) Init_Efrqs_Using_Observed_Freqs(mod->e_frq,data->b_frq,mod->ns);  
+          else For(i,4) mod->e_frq->pi->v[i] = mod->e_frq->user_b_freq->v[i];
+          For(i,mod->ns) mod->e_frq->pi_unscaled->v[i] = mod->e_frq->pi->v[i] * 100.;
           aux = ((mod->e_frq->pi->v[0]+mod->e_frq->pi->v[2])-(mod->e_frq->pi->v[1]+mod->e_frq->pi->v[3]))/(2.*mod->kappa->v);
           mod->lambda->v = ((mod->e_frq->pi->v[1]+mod->e_frq->pi->v[3]) + aux)/((mod->e_frq->pi->v[0]+mod->e_frq->pi->v[2]) - aux);
           mod->update_eigen = NO;
@@ -1115,12 +1131,26 @@ void Init_Model(calign *data, t_mod *mod, option *io)
       
       if(mod->whichmodel == TN93)
         {
+          if(mod->e_frq->user_state_freq == NO) Init_Efrqs_Using_Observed_Freqs(mod->e_frq,data->b_frq,mod->ns);  
+          else For(i,4) mod->e_frq->pi->v[i] = mod->e_frq->user_b_freq->v[i];
+          For(i,mod->ns) mod->e_frq->pi_unscaled->v[i] = mod->e_frq->pi->v[i] * 100.;
           mod->update_eigen = NO;
           if(io->mod->s_opt->opt_kappa) io->mod->s_opt->opt_lambda = YES;
         }
+
+      if(mod->whichmodel == HKY85)
+        {
+          if(mod->e_frq->user_state_freq == NO) Init_Efrqs_Using_Observed_Freqs(mod->e_frq,data->b_frq,mod->ns);  
+          else For(i,4) mod->e_frq->pi->v[i] = mod->e_frq->user_b_freq->v[i];
+          For(i,mod->ns) mod->e_frq->pi_unscaled->v[i] = mod->e_frq->pi->v[i] * 100.;
+          mod->update_eigen = NO;
+        }
       
       if(mod->whichmodel == GTR)
         {
+          if(mod->e_frq->user_state_freq == NO) Init_Efrqs_Using_Observed_Freqs(mod->e_frq,data->b_frq,mod->ns);  
+          else For(i,4) mod->e_frq->pi->v[i] = mod->e_frq->user_b_freq->v[i];
+          For(i,mod->ns) mod->e_frq->pi_unscaled->v[i] = mod->e_frq->pi->v[i] * 100.;
           mod->kappa->v          = 1.;
           mod->update_eigen      = YES;
           io->mod->s_opt->opt_rr = YES;
@@ -1128,6 +1158,9 @@ void Init_Model(calign *data, t_mod *mod, option *io)
       
       if(mod->whichmodel == CUSTOM)
         {
+          if(mod->e_frq->user_state_freq == NO) Init_Efrqs_Using_Observed_Freqs(mod->e_frq,data->b_frq,mod->ns);  
+          else For(i,4) mod->e_frq->pi->v[i] = mod->e_frq->user_b_freq->v[i];
+          For(i,mod->ns) mod->e_frq->pi_unscaled->v[i] = mod->e_frq->pi->v[i] * 100.;
           mod->kappa->v = 1.;
           mod->update_eigen = YES;
           /* 	  io->mod->s_opt->opt_rr     = YES; */ /* What if the user decided not to optimise the rates? */
@@ -1143,15 +1176,8 @@ void Init_Model(calign *data, t_mod *mod, option *io)
           mod->custom_mod_string->s[5] = '5';
           Translate_Custom_Mod_String(mod);
         }
-      
-      if(mod->s_opt->user_state_freq == YES && mod->whichmodel != JC69 && mod->whichmodel != K80)
-        {
-          For(i,4)
-            {
-              mod->e_frq->pi->v[i] = mod->user_b_freq->v[i];
-            }
-        }
-      
+                  
+
       if(((mod->whichmodel == GTR)    ||
           (mod->whichmodel == CUSTOM) ||
           (mod->whichmodel == HKY85)) &&
@@ -1164,6 +1190,7 @@ void Init_Model(calign *data, t_mod *mod, option *io)
       /* if((mod->whichmodel != GTR)    &&  */
       /* 	 (mod->whichmodel != CUSTOM) &&  */
       /* 	 (mod->whichmodel != HKY85)) mod->update_eigen = NO; */
+
     }
   else if(mod->io->datatype == AA)
     {
@@ -1183,136 +1210,116 @@ void Init_Model(calign *data, t_mod *mod, option *io)
         case DAYHOFF :
           {
             Init_Qmat_Dayhoff(mod->r_mat->qmat->v,mod->e_frq->pi->v);
-            if(mod->s_opt->opt_state_freq)
-              For(i,mod->ns) mod->e_frq->pi->v[i] = data->b_frq[i];
+            if(mod->e_frq->empirical_state_freq == YES) Init_Efrqs_Using_Observed_Freqs(mod->e_frq,data->b_frq,mod->ns);  
             break;
           }
         case JTT :
           {
             Init_Qmat_JTT(mod->r_mat->qmat->v,mod->e_frq->pi->v);
-            if(mod->s_opt->opt_state_freq)
-              For(i,mod->ns) mod->e_frq->pi->v[i] = data->b_frq[i];
+            if(mod->e_frq->empirical_state_freq == YES) Init_Efrqs_Using_Observed_Freqs(mod->e_frq,data->b_frq,mod->ns);  
             break;
           }
         case MTREV :
           {
             Init_Qmat_MtREV(mod->r_mat->qmat->v,mod->e_frq->pi->v);
-            if(mod->s_opt->opt_state_freq)
-              For(i,mod->ns) mod->e_frq->pi->v[i] = data->b_frq[i];
+            if(mod->e_frq->empirical_state_freq == YES) Init_Efrqs_Using_Observed_Freqs(mod->e_frq,data->b_frq,mod->ns);  
             break;
           }
         case LG :
           {
             Init_Qmat_LG(mod->r_mat->qmat->v,mod->e_frq->pi->v);
-            if(mod->s_opt->opt_state_freq)
-              For(i,mod->ns) mod->e_frq->pi->v[i] = data->b_frq[i];
+            if(mod->e_frq->empirical_state_freq == YES) Init_Efrqs_Using_Observed_Freqs(mod->e_frq,data->b_frq,mod->ns);  
             break;
           }
         case WAG :
           {
             Init_Qmat_WAG(mod->r_mat->qmat->v,mod->e_frq->pi->v);
-            if(mod->s_opt->opt_state_freq)
-              For(i,mod->ns) mod->e_frq->pi->v[i] = data->b_frq[i];
+            if(mod->e_frq->empirical_state_freq == YES) Init_Efrqs_Using_Observed_Freqs(mod->e_frq,data->b_frq,mod->ns);  
             break;
           }
         case DCMUT :
           {
             Init_Qmat_DCMut(mod->r_mat->qmat->v,mod->e_frq->pi->v);
-            if(mod->s_opt->opt_state_freq)
-              For(i,mod->ns) mod->e_frq->pi->v[i] = data->b_frq[i];
+            if(mod->e_frq->empirical_state_freq == YES) Init_Efrqs_Using_Observed_Freqs(mod->e_frq,data->b_frq,mod->ns);  
             break;
           }
         case RTREV :
           {
             Init_Qmat_RtREV(mod->r_mat->qmat->v,mod->e_frq->pi->v);
-            if(mod->s_opt->opt_state_freq)
-              For(i,mod->ns) mod->e_frq->pi->v[i] = data->b_frq[i];
+            if(mod->e_frq->empirical_state_freq == YES) Init_Efrqs_Using_Observed_Freqs(mod->e_frq,data->b_frq,mod->ns);  
             break;
           }
         case CPREV :
           {
             Init_Qmat_CpREV(mod->r_mat->qmat->v,mod->e_frq->pi->v);
-            if(mod->s_opt->opt_state_freq)
-              For(i,mod->ns) mod->e_frq->pi->v[i] = data->b_frq[i];
+            if(mod->e_frq->empirical_state_freq == YES) Init_Efrqs_Using_Observed_Freqs(mod->e_frq,data->b_frq,mod->ns);  
             break;
           }
         case VT :
           {
             Init_Qmat_VT(mod->r_mat->qmat->v,mod->e_frq->pi->v);
-            if(mod->s_opt->opt_state_freq)
-              For(i,mod->ns) mod->e_frq->pi->v[i] = data->b_frq[i];
+            if(mod->e_frq->empirical_state_freq == YES) Init_Efrqs_Using_Observed_Freqs(mod->e_frq,data->b_frq,mod->ns);  
             break;
           }
         case BLOSUM62 :
           {
             Init_Qmat_Blosum62(mod->r_mat->qmat->v,mod->e_frq->pi->v);
-            if(mod->s_opt->opt_state_freq)
-              For(i,mod->ns) mod->e_frq->pi->v[i] = data->b_frq[i];
+            if(mod->e_frq->empirical_state_freq == YES) Init_Efrqs_Using_Observed_Freqs(mod->e_frq,data->b_frq,mod->ns);  
             break;
           }
         case MTMAM :
           {
             Init_Qmat_MtMam(mod->r_mat->qmat->v,mod->e_frq->pi->v);
-            if(mod->s_opt->opt_state_freq)
-              For(i,mod->ns) mod->e_frq->pi->v[i] = data->b_frq[i];
+            if(mod->e_frq->empirical_state_freq == YES) Init_Efrqs_Using_Observed_Freqs(mod->e_frq,data->b_frq,mod->ns);  
             break;
           }
         case MTART :
           {
             Init_Qmat_MtArt(mod->r_mat->qmat->v,mod->e_frq->pi->v);
-            if(mod->s_opt->opt_state_freq)
-              For(i,mod->ns) mod->e_frq->pi->v[i] = data->b_frq[i];
+            if(mod->e_frq->empirical_state_freq == YES) Init_Efrqs_Using_Observed_Freqs(mod->e_frq,data->b_frq,mod->ns);  
             break;
           }
         case HIVW :
           {
             Init_Qmat_HIVw(mod->r_mat->qmat->v,mod->e_frq->pi->v);
-            if(mod->s_opt->opt_state_freq)
-              For(i,mod->ns) mod->e_frq->pi->v[i] = data->b_frq[i];
+            if(mod->e_frq->empirical_state_freq == YES) Init_Efrqs_Using_Observed_Freqs(mod->e_frq,data->b_frq,mod->ns);  
             break;
           }
         case HIVB :
           {
             Init_Qmat_HIVb(mod->r_mat->qmat->v,mod->e_frq->pi->v);
-            if(mod->s_opt->opt_state_freq)
-              For(i,mod->ns) mod->e_frq->pi->v[i] = data->b_frq[i];
+            if(mod->e_frq->empirical_state_freq == YES) Init_Efrqs_Using_Observed_Freqs(mod->e_frq,data->b_frq,mod->ns);  
             break;
           }
          case AB :
           {
             Init_Qmat_AB(mod->r_mat->qmat->v,mod->e_frq->pi->v);
-            if(mod->s_opt->opt_state_freq)
-              For(i,mod->ns) mod->e_frq->pi->v[i] = data->b_frq[i];
+            if(mod->e_frq->empirical_state_freq == YES) Init_Efrqs_Using_Observed_Freqs(mod->e_frq,data->b_frq,mod->ns);  
             break;
           } 
         case CUSTOMAA :
           {
-            if(mod->fp_aa_rate_mat == NULL)
-              {
-                PhyML_Printf("\n. Cannot open custom rate matrix file '%s'.\n",mod->aa_rate_mat_file->s); 
-                Exit("\n");
-              }
-
+            mod->fp_aa_rate_mat = Openfile(mod->aa_rate_mat_file->s,READ);
             Read_Qmat(mod->r_mat->qmat->v,mod->e_frq->pi->v,mod->fp_aa_rate_mat);
-            if(mod->s_opt->opt_state_freq) For(i,mod->ns) mod->e_frq->pi->v[i] = data->b_frq[i];
+            fclose(mod->fp_aa_rate_mat);
+            if(mod->e_frq->empirical_state_freq == YES) Init_Efrqs_Using_Observed_Freqs(mod->e_frq,data->b_frq,mod->ns);  
 	    break;
 	  }
 	case FLU : 
 	  {
 	    Init_Qmat_FLU(mod->r_mat->qmat->v,mod->e_frq->pi->v);
-	    if(mod->s_opt->opt_state_freq)
-	      For(i,mod->ns) mod->e_frq->pi->v[i] = data->b_frq[i];
+            if(mod->e_frq->empirical_state_freq == YES) Init_Efrqs_Using_Observed_Freqs(mod->e_frq,data->b_frq,mod->ns);  
             break;
           }
         default :
           {
             Init_Qmat_LG(mod->r_mat->qmat->v,mod->e_frq->pi->v);
-            if(mod->s_opt->opt_state_freq)
-              For(i,mod->ns) mod->e_frq->pi->v[i] = data->b_frq[i];
+            if(mod->e_frq->empirical_state_freq == YES) Init_Efrqs_Using_Observed_Freqs(mod->e_frq,data->b_frq,mod->ns);  
             break;
           }
         }
       
+      if(mod->s_opt->opt_state_freq == YES) Init_Efrqs_Using_Observed_Freqs(mod->e_frq,data->b_frq,mod->ns);
 
       For(i,mod->ns) if(mod->e_frq->pi->v[i] < 1.E-10)
         {
@@ -1322,7 +1329,7 @@ void Init_Model(calign *data, t_mod *mod, option *io)
         }
                        
 
-      /*       /\* multiply the nth col of Q by the nth term of pi/100 just as in PAML *\/ */
+      /* multiply the nth col of Q by the nth term of pi/100 just as in PAML */
       For(i,mod->ns) For(j,mod->ns) mod->r_mat->qmat->v[i*mod->ns+j] *= mod->e_frq->pi->v[j] / 100.0;
       
       /* compute diagonal terms of Q and mean rate mr = l/t */
@@ -1335,7 +1342,7 @@ void Init_Model(calign *data, t_mod *mod, option *io)
           mod->mr->v += mod->e_frq->pi->v[i] * sum;
         }
       
-      /* scale imod->nstantaneous rate matrix so that mu=1 */
+      /* scale instantaneous rate matrix so that mu=1 */
       For (i,mod->ns*mod->ns) mod->r_mat->qmat->v[i] /= mod->mr->v;
       
       /* compute eigenvectors/values */
@@ -1391,6 +1398,19 @@ void Init_Model(calign *data, t_mod *mod, option *io)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
+void Init_Efrqs_Using_Observed_Freqs(t_efrq *f, phydbl *o, int ns)
+{
+  int i;
+
+  assert(f);
+  assert(o);
+
+  For(i,ns)  f->pi->v[i] = o[i];
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
 int Init_Qmat_Dayhoff(phydbl *daa, phydbl *pi)
 {
   /* Dayhoff's model data
@@ -3466,7 +3486,7 @@ void PHYREX_Init_Migrep_Mod(t_phyrex_mod *t, int n_dim, phydbl max_lat, phydbl m
 
   t->soft_bound_area = 0.1;
   
-  t->sampl_area      = 0.0;
+  t->samp_area       = NULL;
 }
 
 //////////////////////////////////////////////////////////////
@@ -3492,6 +3512,8 @@ void MCMC_Init_MCMC_Struct(char *filename, option *io, t_mcmc *mcmc)
 {
   int pid;
 
+  assert(mcmc);
+
   mcmc->io               = io;
   mcmc->is               = NO;
   mcmc->use_data         = YES;
@@ -3557,6 +3579,76 @@ void MCMC_Init_MCMC_Struct(char *filename, option *io, t_mcmc *mcmc)
     }
 }
 
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void Init_Calibration(t_cal *cal)
+{
+  cal->target_nd  = NULL;
+  cal->next       = NULL;
+  cal->prev       = NULL;
+  cal->target_tax = NULL;
+  cal->lower      = -1.;
+  cal->upper      = -1.;
+  cal->is_primary = FALSE;
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void Init_All_Calibration(t_tree *tree)
+{
+  int i;
+  assert(tree->rates && tree->rates->a_cal);
+  For(i,2*tree->n_otu-1) Init_Calibration(tree->rates->a_cal[i]);
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void Init_Sarea(t_sarea *s)
+{
+  assert(s);
+  s->n_poly = 0;
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void Init_Calign(int n_otu, int crunch_len, int init_len, calign *this)
+{
+  this->obs_pinvar  = .0;
+  this->n_otu       = n_otu;
+  this->clean_len   = -1;
+  this->crunch_len  = crunch_len;
+  this->init_len    = init_len;
+  this->format      = 0;
+  this->io_wght     = NULL;
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void Init_Linked_List(t_ll *list)
+{
+  list->head = list;
+  list->tail = list;
+  list->next = NULL;
+  list->v    = NULL;
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
diff --git a/src/init.h b/src/init.h
index 7beea75..0df1746 100644
--- a/src/init.h
+++ b/src/init.h
@@ -25,7 +25,7 @@ void Init_Vect_Int(int len,vect_int *p);
 void Init_Tree(t_tree *tree,int n_otu);
 void Init_Edge_Light(t_edge *b,int num);
 void Init_Node_Light(t_node *n,int num);
-void Init_NNI(nni *a_nni);
+void Init_NNI(t_nni *a_nni);
 void Init_Nexus_Format(nexcom **com);
 void Init_Mat(matrix *mat,calign *data);
 void Set_Defaults_Input(option *io);
@@ -52,7 +52,7 @@ int Init_Qmat_AB(phydbl *daa, phydbl *pi);
 void XML_Init_Attribute(xml_attr *attr);
 void Init_String(t_string *ts);
 void Init_Triplet_Struct(triplet *triplet);
-void Init_Efrq(t_efrq *f);
+void Init_Efrq(phydbl *b_frq, t_efrq *f);
 void M4_Init_Model(m4 *m4mod, calign *data, t_mod *mod);
 void RATES_Init_Rate_Struct(t_rate *rates, t_rate *existing_rates, int n_otu);
 void Init_Rmat(t_rmat *rmat);
@@ -64,5 +64,11 @@ void PHYREX_Init_Disk_Event(t_dsk *t, int n_dim, t_phyrex_mod *mod);
 void PHYREX_Init_Lindisk_Node(t_ldsk *t, t_dsk *devt, int n_dim);
 void PHYREX_Init_Migrep_Mod(t_phyrex_mod *t, int n_dim, phydbl max_lat, phydbl max_lon);
 void MCMC_Init_MCMC_Struct(char *filename, option *io, t_mcmc *mcmc);
+void Init_Calibration(t_cal *cal);
+void Init_All_Calibration(t_tree *tree);
+void Init_Sarea(t_sarea *s);
+void Init_Efrqs_Using_Observed_Freqs(t_efrq *f, phydbl *o, int ns);
+void Init_Calign(int n_otu, int crunch_len, int init_len, calign *this);
+void Init_Linked_List(t_ll *list);
 
 #endif
diff --git a/src/interface.c b/src/interface.c
index dc91189..91991bc 100644
--- a/src/interface.c
+++ b/src/interface.c
@@ -135,7 +135,6 @@ void Launch_Interface(option *io)
       strcpy(io->out_lk_file,io->in_align_file);
       strcat(io->out_lk_file, "_phyml_lk");
       if(io->append_run_ID) { strcat(io->out_lk_file,"_"); strcat(io->out_lk_file,io->run_id_string); }
-      strcat(io->out_lk_file, ".txt");
       io->fp_out_lk = Openfile(io->out_lk_file,1);
     }
   
@@ -144,7 +143,6 @@ void Launch_Interface(option *io)
       strcpy(io->out_trace_file,io->in_align_file);
       strcat(io->out_trace_file,"_phyml_trace");
       if(io->append_run_ID) { strcat(io->out_trace_file,"_"); strcat(io->out_trace_file,io->run_id_string); }
-      strcat(io->out_trace_file,".txt");
       io->fp_out_trace = Openfile(io->out_trace_file,1);
     }
   
@@ -153,7 +151,6 @@ void Launch_Interface(option *io)
       strcpy(io->out_trees_file,io->in_align_file);
       strcat(io->out_trees_file,"_phyml_trees");
       if(io->append_run_ID) { strcat(io->out_trees_file,"_"); strcat(io->out_trees_file,io->run_id_string); }
-      strcat(io->out_trees_file,".txt");
       io->fp_out_trees = Openfile(io->out_trees_file,1);
     }
 
@@ -162,13 +159,11 @@ void Launch_Interface(option *io)
       strcpy(io->out_boot_tree_file,io->in_align_file);
       strcat(io->out_boot_tree_file,"_phyml_boot_trees");
       if(io->append_run_ID) { strcat(io->out_boot_tree_file,"_"); strcat(io->out_boot_tree_file,io->run_id_string); }
-      strcat(io->out_boot_tree_file,".txt");
       io->fp_out_boot_tree = Openfile(io->out_boot_tree_file,1);
       
       strcpy(io->out_boot_stats_file,io->in_align_file);
       strcat(io->out_boot_stats_file,"_phyml_boot_stats");
       if(io->append_run_ID) { strcat(io->out_boot_stats_file,"_"); strcat(io->out_boot_stats_file,io->run_id_string); }
-      strcat(io->out_boot_stats_file,".txt");
       io->fp_out_boot_stats = Openfile(io->out_boot_stats_file,1);
     }
   
@@ -178,8 +173,6 @@ void Launch_Interface(option *io)
       strcat(io->out_stats_file,"_");
       strcat(io->out_tree_file,io->run_id_string);
       strcat(io->out_stats_file,io->run_id_string);
-      strcat(io->out_tree_file,".txt");
-      strcat(io->out_stats_file,".txt");
     }
 
   if(io->mod->ras->n_catg == 1) io->mod->s_opt->opt_alpha = 0;
@@ -638,7 +631,7 @@ void Launch_Interface_Model(option *io)
 		  PhyML_Printf("                [E] "
 			 "......... Equilibrium frequencies (empirical/user) "
 			 " %-15s \n",
-			 (io->mod->s_opt->user_state_freq)?("user defined"):("empirical"));
+			 (io->mod->e_frq->user_state_freq)?("user defined"):("empirical"));
 		}
 	      PhyML_Printf("                [K] "
 		     "............................. Current custom model "
@@ -892,9 +885,9 @@ void Launch_Interface_Model(option *io)
 
 	if(io->mod->whichmodel == CUSTOM)
 	  {
-	    io->mod->s_opt->user_state_freq = (io->mod->s_opt->user_state_freq)?(0):(1);
+	    io->mod->e_frq->user_state_freq = (io->mod->e_frq->user_state_freq)?(0):(1);
 
-	    if(io->mod->s_opt->user_state_freq)
+	    if(io->mod->e_frq->user_state_freq)
 	      {
 		if(!io->mod->s_opt->opt_state_freq)
 		  {
@@ -928,20 +921,20 @@ void Launch_Interface_Model(option *io)
 			    PhyML_Printf("\n. Enter a new value > ");
 			    Getstring_Stdin(bs);
 			  }
-			io->mod->user_b_freq->v[i] = (phydbl)atof(bs);
-			sum += io->mod->user_b_freq->v[i];
+			io->mod->e_frq->user_b_freq->v[i] = (phydbl)atof(bs);
+			sum += io->mod->e_frq->user_b_freq->v[i];
 		      }
 		
-		    For(i,4) io->mod->user_b_freq->v[i] /= sum;
+		    For(i,4) io->mod->e_frq->user_b_freq->v[i] /= sum;
 
 		    if(sum > 1.0 || sum < 1.0)
 		      {
 			PhyML_Printf("\n. The nucleotide frequencies have to be normalised in order to sum to 1.0.\n");
 			PhyML_Printf("\n. The frequencies are now : f(A)=%f, f(C)=%f, f(G)=%f, f(T)=%f.\n",
-			       io->mod->user_b_freq->v[0],
-			       io->mod->user_b_freq->v[1],
-			       io->mod->user_b_freq->v[2],
-			       io->mod->user_b_freq->v[3]);			  
+			       io->mod->e_frq->user_b_freq->v[0],
+			       io->mod->e_frq->user_b_freq->v[1],
+			       io->mod->e_frq->user_b_freq->v[2],
+			       io->mod->e_frq->user_b_freq->v[3]);			  
 			PhyML_Printf("\n. Enter any key to continue.\n");
 			if(!scanf("%c",bs)) Exit("\n");
 		      }
diff --git a/src/invitee.c b/src/invitee.c
index 2f49697..427cd9f 100644
--- a/src/invitee.c
+++ b/src/invitee.c
@@ -341,7 +341,7 @@ void PhyTime_XML(char *xml_file)
                           i = 0;
                           xml_node *nd;
                           nd = n_clade -> child;
-                          clade = XML_Reading_Clade(nd, tree);
+                          clade = XML_Read_Clade(nd, tree);
                           clade_size = XML_Number_Of_Taxa_In_Clade(nd);
                           node_num = Find_Clade(clade, clade_size, io -> tree);
                         }
@@ -417,7 +417,7 @@ void PhyTime_XML(char *xml_file)
 
           tree -> rates -> calib = tree -> rates -> calib -> next;	   
           n_r = n_r -> next;
-        }      
+        }
       else if(!strcmp(n_r -> name, "ratematrices"))//initializing rate matrix:
         {
           if(n_r -> child) 
@@ -445,6 +445,7 @@ void PhyTime_XML(char *xml_file)
             }
           else n_r = n_r -> next;
         }
+
       else if (n_r -> next) n_r = n_r -> next;
       else break;
     }
@@ -2317,65 +2318,10 @@ xml_node *XML_Search_Node_Attribute_Value_Clade(char *attr_name, char *value, in
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
-char **XML_Reading_Clade(xml_node *n_clade, t_tree *tree)
-{
-  int i, /* j, */ n_otu;
-  char **clade;
-
-  i = 0;
-  n_otu = tree -> n_otu;
-
-  clade = (char **)mCalloc(n_otu, sizeof(char *));
-  /* For(j, n_otu) */
-  /*   { */
-  /*     clade[j] = (char *)mCalloc(T_MAX_NAME,sizeof(char)); */
-  /*   } */
-
-  if(n_clade)
-    {
-      do
-        {
-          clade[i] =  n_clade -> attr -> value; 
-          i++;
-          if(n_clade -> next) n_clade = n_clade -> next;
-          else break;
-        }
-      while(n_clade);
-    }
-  else
-    {
-      PhyML_Printf("== Clade is empty. \n");
-      PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__);
-      Exit("\n");
-    }
 
-  return(clade);                          
-}
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
-int XML_Number_Of_Taxa_In_Clade(xml_node *n_clade)
-{
-  int clade_size = 0;
-  if(n_clade)
-    {
-      do
-        {
-          clade_size++; 
-          if(n_clade -> next) n_clade = n_clade -> next;
-          else break;
-        }
-      while(n_clade);
-    }
-  else
-    {
-      PhyML_Printf("==Clade is empty. \n");
-      PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__);
-      Exit("\n");
-    }
-  return(clade_size);
-}
-
 
 
 //////////////////////////////////////////////////////////////
diff --git a/src/invitee.h b/src/invitee.h
index 0b00c7a..afc292a 100644
--- a/src/invitee.h
+++ b/src/invitee.h
@@ -28,7 +28,7 @@ int Factorial(int base);
 phydbl *Norm_Constant_Prior_Times(t_tree *tree);
 void TIMES_Calib_Partial_Proba(t_tree *tree);
 xml_node *XML_Search_Node_Attribute_Value_Clade(char *attr_name, char *value, int skip, xml_node *node);
-char **XML_Reading_Clade(xml_node *n_clade, t_tree *tree);
+char **XML_Read_Clade(xml_node *n_clade, t_tree *tree);
 int XML_Number_Of_Taxa_In_Clade(xml_node *n_clade);
 void TIMES_Set_All_Node_Priors_S(int *result, t_tree *tree);
 void TIMES_Set_All_Node_Priors_Bottom_Up_S(t_node *a, t_node *d, int *result, t_tree *tree);
diff --git a/src/io.c b/src/io.c
index 8dd69e2..bc8e172 100644
--- a/src/io.c
+++ b/src/io.c
@@ -568,12 +568,11 @@ char *Write_Tree(t_tree *tree, int custom)
   s=(char *)mCalloc(T_MAX_LINE,sizeof(char));
 #endif
 
-
   s[0]='(';
 
   if(custom == NO)
     {
-      if(!tree->n_root)
+      if(tree->n_root == NO)
         {
           i = 0;
           while((!tree->a_nodes[tree->n_otu+i]->v[0]) ||
@@ -782,7 +781,7 @@ void R_wtree(t_node *pere, t_node *fils, int *available, char **s_tree, t_tree *
       /* 	} */
       
       
-      if(tree->n_root)
+      if(tree->n_root != NULL)
         {
           For(i,3)
             {
@@ -1627,7 +1626,6 @@ align **Get_Seq_Phylip(option *io)
       Exit("\n");
     }
   
-
   if(io->interleaved) io->data = Read_Seq_Interleaved(io);
   else                io->data = Read_Seq_Sequential(io);
 
@@ -1693,6 +1691,7 @@ align **Read_Seq_Sequential(option *io)
   
   sprintf(format, "%%%ds", T_MAX_NAME);
 
+
   For(i,io->n_otu)
     {
       data[i]        = (align *)mCalloc(1,sizeof(align));
@@ -1706,7 +1705,7 @@ align **Read_Seq_Sequential(option *io)
 
       Check_Sequence_Name(data[i]->name);
 
-      while(data[i]->len < io->init_len * io->state_len) Read_One_Line_Seq(&data,i,io->fp_in_align);
+      while(data[i]->len < io->init_len * io->state_len) assert(Read_One_Line_Seq(&data,i,io->fp_in_align));
 
       if(data[i]->len != io->init_len * io->state_len)
         {
@@ -1863,7 +1862,7 @@ int Read_One_Line_Seq(align ***data, int num_otu, FILE *in)
 
       if((c == 13) || (c == 10))
         {
-          /* 	  PhyML_Printf("[%d %d]\n",c,nchar); fflush(NULL); */
+          /* PhyML_Printf("[%d %d]\n",c,nchar); fflush(NULL); */
           if(!nchar)
             {
               c=(char)fgetc(in);
@@ -1871,18 +1870,18 @@ int Read_One_Line_Seq(align ***data, int num_otu, FILE *in)
             }
           else
             {
-              /* 	      PhyML_Printf("break\n");  */
+              /* PhyML_Printf("break\n"); */
               break;
             }
         }
       else if(c == EOF)
         {
-          /* 	  PhyML_Printf("EOL\n"); */
+          /* PhyML_Printf("EOL\n"); */
           break;
         }
       else if((c == ' ') || (c == '\t') || (c == 32))
         {
-          /* 	  PhyML_Printf("[%d]",c); */
+          /* PhyML_Printf("[%d]",c); */
           c=(char)fgetc(in);
           continue;
         }
@@ -1899,7 +1898,7 @@ int Read_One_Line_Seq(align ***data, int num_otu, FILE *in)
       (*data)[num_otu]->state[(*data)[num_otu]->len]=c;
       (*data)[num_otu]->len++;
       c = (char)fgetc(in);
-      /* PhyML_Printf("[%c %d]",c,c); */
+      /* PhyML_Printf("[%c %d]",c,c); fflush(NULL); */
       if(c == ';') break;
     }
 
@@ -1915,12 +1914,7 @@ t_tree *Read_Tree_File(option *io)
 {
   t_tree *tree;
 
-  if(!io->fp_in_tree)
-    {
-      PhyML_Printf("\n== Filehandle to '%s' seems to be closed.",io->in_tree_file);
-      Exit("\n");
-    }
-
+  assert(io->fp_in_tree);
 
   Detect_Tree_File_Format(io);
 
@@ -1934,6 +1928,8 @@ t_tree *Read_Tree_File(option *io)
       {
         io->treelist->tree = (t_tree **)realloc(io->treelist->tree,(io->treelist->list_size+1)*sizeof(t_tree *));
         io->tree = Read_Tree_File_Phylip(io->fp_in_tree);
+        fclose(io->fp_in_tree);
+        io->fp_in_tree = NULL;
         if(!io->tree) break;
         if(io->treelist->list_size > 1) PhyML_Printf("\n. Reading tree %d",io->treelist->list_size+1);
         io->treelist->tree[io->treelist->list_size] = io->tree;
@@ -1943,11 +1939,13 @@ t_tree *Read_Tree_File(option *io)
       }
     case NEXUS:
       {
-    io->nex_com_list = Make_Nexus_Com();
-    Init_Nexus_Format(io->nex_com_list);
-    Get_Nexus_Data(io->fp_in_tree,io);
-    Free_Nexus(io);
-    break;
+        io->nex_com_list = Make_Nexus_Com();
+        Init_Nexus_Format(io->nex_com_list);
+        Get_Nexus_Data(io->fp_in_tree,io);
+        fclose(io->fp_in_tree);
+        io->fp_in_tree = NULL;
+        Free_Nexus(io);
+        break;
       }
     default:
       {
@@ -1980,6 +1978,37 @@ t_tree *Read_Tree_File(option *io)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
+scalar_dbl *Read_Io_Weights(option *io)
+{
+  scalar_dbl *w,*ori;
+  double val;
+
+  assert(io->weight_file);
+  
+  io->fp_weight_file = Openfile(io->weight_file,READ);
+
+  w = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl));
+  ori = w;
+
+  do
+    {
+      if(fscanf(io->fp_weight_file,"%lf,",&val) == EOF) break;      
+      w->v = (phydbl)val;
+      w->next = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl));
+      w = w->next;
+    }
+  while(1);
+
+  w->next = NULL;
+
+  fclose(io->fp_weight_file);
+  
+  return(ori);
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
 char *Return_Tree_String_Phylip(FILE *fp_input_tree)
 {
   char *line;
@@ -2374,12 +2403,14 @@ void Print_Node(t_node *a, t_node *d, t_tree *tree)
   int dir;
   dir = -1;
   For(i,3) if(a->v[i] == d) {dir = i; break;}
-  PhyML_Printf("Node nums: %3d %3d  (dir:%3d) (anc:%3d) ta:%12f td:%12f;",
+  PhyML_Printf("Node nums: %3d %3d  (dir:%3d) (anc:%3d) ta:%8.4f td:%8.4f t_min:%6.2f t_max:%6.2f",
                a->num,d->num,dir,a->anc?a->anc->num:(-1),
                tree->rates?tree->rates->nd_t[a->num]:-1.,
-               tree->rates?tree->rates->nd_t[d->num]:-1.);
+               tree->rates?tree->rates->nd_t[d->num]:-1.,
+               tree->rates?tree->rates->t_prior_min[a->num]:-1.,
+               tree->rates?tree->rates->t_prior_max[a->num]:-1.);
 
-  PhyML_Printf("Node names = '%10s' '%10s' ; ",a->name,d->name);
+  PhyML_Printf(" names = '%10s' '%10s' ; ",a->name,d->name);
   For(i,3) if(a->v[i] == d)
     {
       if(a->b[i])
@@ -2499,7 +2530,7 @@ void Print_Model(t_mod *mod)
 
   PhyML_Printf("\n. Freqs");
   PhyML_Printf("\n");
-  For(i,mod->ns) PhyML_Printf(" %12f ",mod->user_b_freq->v[i]);
+  For(i,mod->ns) PhyML_Printf(" %12f ",mod->e_frq->user_b_freq->v[i]);
   PhyML_Printf("\n");
   For(i,mod->ns) PhyML_Printf(" %12f ",mod->e_frq->pi->v[i]);
   PhyML_Printf("\n");
@@ -2577,42 +2608,39 @@ void Print_Mat(matrix *mat)
 
 FILE *Openfile(char *filename, int mode)
 {
-  /* mode = 0 -> read */
-  /* mode = 1 -> write */
-  /* mode = 2 -> append */
-
   FILE *fp;
   char *s;
   int open_test=0;
 
-/*   s = (char *)mCalloc(T_MAX_FILE,sizeof(char)); */
-
-/*   strcpy(s,filename); */
-
   s = filename;
 
   fp = NULL;
 
   switch(mode)
     {
-    case 0 :
-      {
-    while(!(fp = (FILE *)fopen(s,"r")) && ++open_test<10)
+    case READ :
       {
-        PhyML_Printf("\n. Can't open file '%s', enter a new name : ",s);
-        Getstring_Stdin(s);
+        while(!(fp = (FILE *)fopen(s,"r")) && ++open_test<10)
+          {
+            PhyML_Printf("\n. Can't open file '%s', enter a new name : ",s);
+            Getstring_Stdin(s);
+          }
+        break;
       }
-    break;
+    case WRITE :
+      {
+        fp = (FILE *)fopen(s,"w");
+        break;
       }
-    case 1 :
+    case APPEND :
       {
-    fp = (FILE *)fopen(s,"w");
-    break;
+        fp = (FILE *)fopen(s,"a");
+        break;
       }
-    case 2 :
+    case READWRITE :
       {
-    fp = (FILE *)fopen(s,"a");
-    break;
+        fp = (FILE *)fopen(s,"w+");
+        break;
       }
 
     default : break;
@@ -2633,9 +2661,7 @@ void Print_Fp_Out(FILE *fp_out, time_t t_beg, time_t t_end, t_tree *tree, option
   div_t hour,min;
   int i;
 
-/*   For(i,2*tree->n_otu-3) fprintf(fp_out,"\n. * Edge %3d: %f",i,tree->a_edges[i]->l); */
-
-  if((!n_data_set) || (!num_tree))
+  if(n_data_set == 1)
     {
       rewind(fp_out);
       Print_Banner_Small(fp_out);
@@ -3179,7 +3205,7 @@ void Print_Settings(option *io)
          (io->mod->whichmodel != K80)  &&
          (io->mod->whichmodel != F81))
         {
-          if(io->mod->s_opt && !io->mod->s_opt->user_state_freq)
+          if(io->mod->s_opt && !io->mod->e_frq->user_state_freq)
             {
               PhyML_Printf("\n                . Nucleotide equilibrium frequencies:\t\t %s", (io->mod->s_opt->opt_state_freq) ? ("ML"):("empirical"));
             }
@@ -3719,6 +3745,8 @@ t_tree *Read_User_Tree(calign *cdata, t_mod *mod, option *io)
   PhyML_Printf("\n. Reading tree..."); fflush(NULL);
   if(io->n_trees == 1) rewind(io->fp_in_tree);
   tree = Read_Tree_File_Phylip(io->fp_in_tree);
+  fclose(io->fp_in_tree);
+  io->fp_in_tree = NULL;
   if(!tree) Exit("\n== Input tree not found...");
   /* Add branch lengths if necessary */
   if(!tree->has_branch_lengths) Add_BioNJ_Branch_Lengths(tree,cdata,mod);
@@ -3761,7 +3789,7 @@ void PhyML_Printf(char *format, ...)
       va_end(ptr);
 #endif
 
-  /* fflush (NULL); */
+  fflush (NULL);
 }
 
 //////////////////////////////////////////////////////////////
@@ -4252,7 +4280,7 @@ void Print_Data_Structure(int final, FILE *fp, t_tree *mixt_tree)
              tree->mod->whichmodel == HKY85 ||
              tree->mod->whichmodel == TN93)
             {
-              PhyML_Fprintf(fp,"\n   Value of the ts/tv raqtio:\t%12f",tree->mod->kappa->v);
+              PhyML_Fprintf(fp,"\n   Value of the ts/tv ratio:\t%12f",tree->mod->kappa->v);
               PhyML_Fprintf(fp,"\n   Optimise ts/tv ratio:\t%12s",tree->mod->s_opt->opt_kappa?"yes":"no");
             }
           else if(tree->mod->whichmodel == GTR ||
@@ -4572,1201 +4600,30 @@ void Print_Data_Structure(int final, FILE *fp, t_tree *mixt_tree)
 
 option *PhyML_XML(char *xml_filename)
 {
-  FILE *fp;
-  xml_node *root,*p_elem,*m_elem,*parent,*instance;
+  char *most_likely_tree;
+  phydbl best_lnL;
+  int num_rand_tree;
+  t_tree *mixt_tree,*tree;
   option *io,*dum;
-  void *buff;
-  t_mod *mod,*iomod;
-  t_tree *tree,*mixt_tree,*root_tree;
-  int select;
-  char *component;
-  int i,j,n_components;
-  int first_m_elem;
-  int class_number;
-  scalar_dbl **lens,**lens_var,**ori_lens,**lens_old,**lens_var_old,**ori_lens_old,**ori_lens_var,**ori_lens_var_old;
-  t_ds *ds;
-  char *outputfile;
-  char *alignment;
-  char *s;
-  int lens_size;
-  int first;
-  int *class_num;
-
-
-  fp = fopen(xml_filename,"r");
-  if(!fp)
-    {
-      PhyML_Printf("\n== Could not find the XML file '%s'.\n",xml_filename);
-      Exit("\n");
-    }
-
-
-  root = XML_Load_File(fp);
-
-  if(!root)
-    {
-      PhyML_Printf("\n== Encountered an issue while loading the XML file.\n");
-      Exit("\n");
-    }
-
-  class_num = (int *)mCalloc(N_MAX_MIXT_CLASSES,sizeof(int));
-  For(i,N_MAX_MIXT_CLASSES) class_num[i] = i;
-
-  component = (char *)mCalloc(T_MAX_NAME,sizeof(char));
-
-  m_elem           = NULL;
-  p_elem           = root;
-  io               = NULL;
-  mixt_tree        = NULL;
-  root_tree        = NULL;
-  mod              = NULL;
-  tree             = NULL;
-  lens             = NULL;
-  lens_var         = NULL;
-  lens_old         = NULL;
-  lens_var_old     = NULL;
-  select           = -1;
-  class_number     = -1;
-  ds               = NULL;
-  lens_size        = 0;
-  ori_lens         = NULL;
-  ori_lens_old     = NULL;
-  ori_lens_var     = NULL;
-  ori_lens_var_old = NULL;
-  first            = YES;
+  xml_node *xml_root;
 
+  mixt_tree        = XML_Process_Base(xml_filename);
+  io               = mixt_tree->io;
+  most_likely_tree = NULL;
+  xml_root         = mixt_tree->xml_root;
+  best_lnL         = UNLIKELY;
+  dum              = NULL;
 
   dum = (option *)mCalloc(1,sizeof(option));
   dum->use_xml = YES;
 
-  // Make sure there are no duplicates in node's IDs
-  XML_Check_Duplicate_ID(root);
-
-  int count = 0;
-  XML_Count_Number_Of_Node_With_Name("topology",&count,root);
-
-  if(count > 1)
-    {
-      PhyML_Printf("\n== There should not more than one 'topology' node.");
-      PhyML_Printf("\n== Found %d. Please fix your XML file",count);
-      Exit("\n");
-    }
-  else if(count < 1)
-    {
-      PhyML_Printf("\n== There should be at least one 'topology' node.");
-      PhyML_Printf("\n== Found none. Please fix your XML file");
-      Exit("\n");
-    }
-
-  p_elem = XML_Search_Node_Name("phyml",NO,p_elem);
-
-  /*! Input file
-   */
-  outputfile = XML_Get_Attribute_Value(p_elem,"output.file");
-
-  if(!outputfile)
-    {
-      PhyML_Printf("\n== The 'outputfile' attribute in 'phyml' tag is mandatory.");
-      PhyML_Printf("\n== Please amend your XML file accordingly.");
-      Exit("\n");
-    }
-
-  io = (option *)Make_Input();
-  Set_Defaults_Input(io);
-
-  s = XML_Get_Attribute_Value(p_elem,"run.id");
-  if(s)
-    {
-      io->append_run_ID = YES;
-      strcpy(io->run_id_string,s);
-    }
-
-  strcpy(io->out_file,outputfile);
-  strcpy(io->out_tree_file,outputfile);
-  if(io->append_run_ID) { strcat(io->out_tree_file,"_"); strcat(io->out_tree_file,io->run_id_string); }
-  strcat(io->out_tree_file,"_phyml_tree");
-  strcpy(io->out_stats_file,outputfile);
-  if(io->append_run_ID) { strcat(io->out_stats_file,"_"); strcat(io->out_stats_file,io->run_id_string); }
-  strcat(io->out_stats_file,"_phyml_stats");
-  io->fp_out_tree  = Openfile(io->out_tree_file,1);
-  io->fp_out_stats = Openfile(io->out_stats_file,1);
-
-  s = XML_Get_Attribute_Value(p_elem,"print.trace");
-
-  if(s)
-    {
-      select = XML_Validate_Attr_Int(s,6,
-                                     "true","yes","y",
-                                     "false","no","n");
-      
-      if(select < 3)
-        {
-          io->print_trace = YES;
-          strcpy(io->out_trace_file,outputfile);
-          if(io->append_run_ID) { strcat(io->out_trace_file,"_"); strcat(io->out_trace_file,io->run_id_string); }
-          strcat(io->out_trace_file,"_phyml_trace");
-          io->fp_out_trace = Openfile(io->out_trace_file,1);
-        }
-    }
-  
-  
-  s = XML_Get_Attribute_Value(p_elem,"branch.test");
-  if(s)
-    {
-      if(!strcmp(s,"aLRT"))
-        {
-          io->ratio_test = ALRTSTAT;
-        }
-      else if(!strcmp(s,"aBayes"))
-        {
-          io->ratio_test = ABAYES;
-        }
-      else if(!strcmp(s,"SH"))
-        {
-          io->ratio_test = SH;
-        }
-      else if(!strcmp(s,"no") || !strcmp(s,"none"))
-        {
-          io->ratio_test = 0;
-        }
-      else
-        {
-          PhyML_Printf("\n== '%s' is not a valid option for 'branch.test'.",s);
-          PhyML_Printf("\n== Please use 'aLRT' or 'aBayes' or 'SH'.");
-          Exit("\n");
-        }
-    }
-  
-  s = XML_Get_Attribute_Value(p_elem,"quiet");
-  if(s)
-    {
-      select = XML_Validate_Attr_Int(s,6,
-                                     "true","yes","y",
-                                     "false","no","n");
-      if(select < 3) io->quiet = YES;
-    }
-
-  s = XML_Get_Attribute_Value(p_elem,"memory.check");
-  if(s)
-    {
-      select = XML_Validate_Attr_Int(s,6,
-                                     "true","yes","y",
-                                     "false","no","n");
-      if(select >= 3) io->mem_question = NO;
-    }
-
-  /*! Read all partitionelem nodes and mixturelem nodes in each of them
-   */
-  do
-    {
-      p_elem = XML_Search_Node_Name("partitionelem",YES,p_elem);
-      
-      if(p_elem == NULL) break;
-      
-      buff = (option *)Make_Input();
-      Set_Defaults_Input(buff);
-      io->next = buff;
-      io->next->prev = io;
-      
-      io = io->next;
-      if(first == YES)
-        {
-          io = io->prev;
-          io->next = NULL;
-          Free_Input(buff);
-          first = NO;
-        }
-      
-      
-      /*! Set the datatype (required when compressing data)
-       */
-      char *dt = NULL;
-      dt = XML_Get_Attribute_Value(p_elem,"data.type");
-      if(!dt)
-        {
-          PhyML_Printf("\n== Please specify the type of data ('aa' or 'nt') for partition element '%s'",
-                       XML_Get_Attribute_Value(p_elem,"id"));
-          PhyML_Printf("\n== Syntax: 'data.type=\"aa\"' or 'data.type=\"nt\"'");
-          Exit("\n");
-        }
-      
-      select = XML_Validate_Attr_Int(dt,2,"aa","nt");
-      switch(select)
-        {
-        case 0:
-          {
-            io->datatype = AA;
-            break;
-          }
-        case 1:
-          {
-            io->datatype = NT;
-            break;
-          }
-        default:
-          {
-            PhyML_Printf("\n== Unknown data type. Must be either 'aa' or 'nt'.");
-            Exit("\n");
-          }
-        }
-      
-      char *format = NULL;
-      format = XML_Get_Attribute_Value(p_elem,"format");
-      if(format)
-        {
-          if(!strcmp(format,"interleave") ||
-             !strcmp(format,"interleaved"))
-            {
-              io->interleaved = YES;
-            }
-          else if(!strcmp(format,"sequential"))
-            {
-              io->interleaved = NO;
-            }
-        }
-      
-      
-      /*! Attach a model to this io struct
-       */
-      io->mod = (t_mod *)Make_Model_Basic();
-      Set_Defaults_Model(io->mod);
-      io->mod->ras->n_catg = 1;
-      io->mod->io = io;
-      iomod = io->mod;
-      
-      /*! Attach an optimization structure to this model
-       */
-      iomod->s_opt = (t_opt *)Make_Optimiz();
-      Set_Defaults_Optimiz(iomod->s_opt);
-      
-      iomod->s_opt->opt_kappa   = NO;
-      iomod->s_opt->opt_lambda  = NO;
-      iomod->s_opt->opt_rr      = NO;
-      
-      /*! Input file
-       */
-      alignment = XML_Get_Attribute_Value(p_elem,"file.name");
-      
-      if(!alignment)
-        {
-          PhyML_Printf("\n== 'file.name' tag is mandatory. Please amend your");
-          PhyML_Printf("\n== XML file accordingly.");
-          Exit("\n");
-        }
-      
-      strcpy(io->in_align_file,alignment);
-      
-      /*! Open pointer to alignment
-       */
-      io->fp_in_align = Openfile(io->in_align_file,0);
-      
-      /*! Load sequence file
-       */
-      io->data  = Get_Seq(io);
-      
-      /*! Close pointer to alignment
-       */
-      fclose(io->fp_in_align);
-      
-      /*! Compress alignment
-       */
-      io->cdata = Compact_Data(io->data,io);
-      
-      /*! Free uncompressed alignment
-       */
-      Free_Seq(io->data,io->n_otu);
-      
-      /*! Create new mixture tree
-       */
-      buff = (t_tree *)Make_Tree_From_Scratch(io->cdata->n_otu,io->cdata);
-      
-      if(mixt_tree)
-        {
-          mixt_tree->next_mixt            = buff;
-          mixt_tree->next_mixt->prev_mixt = mixt_tree;
-          mixt_tree                       = mixt_tree->next_mixt;
-          mixt_tree->dp                   = mixt_tree->prev_mixt->dp+1;
-        }
-      else mixt_tree = buff;
-      
-      /*! Connect mixt_tree to io struct
-       */
-      mixt_tree->io = io;
-      
-      /*! Connect mixt_tree to model struct
-       */
-      mixt_tree->mod = iomod;
-      
-      /*! mixt_tree is a mixture tree
-       */
-      mixt_tree->is_mixt_tree = YES;
-      
-      /*! mixt_tree is a mixture tree
-       */
-      mixt_tree->mod->is_mixt_mod = YES;
-      
-      /*! Connect mixt_tree to compressed data
-       */
-      mixt_tree->data = io->cdata;
-      
-      /*! Set total number of patterns
-       */
-      mixt_tree->n_pattern = io->cdata->crunch_len;
-      
-      /*! Remove branch lengths from mixt_tree */
-      For(i,2*mixt_tree->n_otu-1)
-        {
-          Free_Scalar_Dbl(mixt_tree->a_edges[i]->l);
-          Free_Scalar_Dbl(mixt_tree->a_edges[i]->l_old);
-          Free_Scalar_Dbl(mixt_tree->a_edges[i]->l_var);
-          Free_Scalar_Dbl(mixt_tree->a_edges[i]->l_var_old);
-        }
-      
-      /*! Connect last tree of the mixture for the
-        previous partition element to the next mixture tree
-      */
-      if(tree)
-        {
-          tree->next = mixt_tree;
-          mixt_tree->prev = tree;
-        }
-      
-      /*! Do the same for the model
-       */
-      if(mod)
-        {
-          mod->next = iomod;
-          iomod->prev = mod;
-        }
-      
-      if(!root_tree) root_tree = mixt_tree;
-      
-      /*! Tree size scaling factor */
-      char *scale_tree = NULL;
-      scale_tree = XML_Get_Attribute_Value(p_elem,"optimise.tree.scale");
-
-      if(scale_tree)
-        {
-          int select;
-          
-          select = XML_Validate_Attr_Int(scale_tree,6,
-                                         "true","yes","y",
-                                         "false","no","n");
-          
-          if(select < 3) mixt_tree->mod->s_opt->opt_br_len_mult = YES;
-        }
-      
-      scale_tree = NULL;
-      scale_tree = XML_Get_Attribute_Value(p_elem,"tree.scale");
-      
-      if(scale_tree)
-        {
-          char *scale_val;
-
-          scale_val = XML_Get_Attribute_Value(p_elem,"tree.scale");
-          if(scale_val)
-            {
-              mixt_tree->mod->br_len_mult->v          = String_To_Dbl(scale_val);
-              mixt_tree->mod->br_len_mult_unscaled->v = String_To_Dbl(scale_val);
-              Free(scale_val);
-            }
-        }
-
-      /*! Process all the mixtureelem tags in this partition element
-       */
-      n_components  = 0;
-      m_elem        = p_elem;
-      first_m_elem  = 0;
-      mod           = NULL;
-      tree          = NULL;
-      class_number  = 0;
-      do
-        {
-          m_elem = XML_Search_Node_Name("mixtureelem",YES,m_elem);
-          if(m_elem == NULL) break;
-          
-          if(!strcmp(m_elem->name,"mixtureelem"))
-            {
-              first_m_elem++;
-              
-              /*! Rewind tree and model when processing a new mixtureelem node
-               */
-              if(first_m_elem > 1)
-                {
-                  while(tree->prev && tree->prev->is_mixt_tree == NO) { tree = tree->prev; } 
-                  while(mod->prev  && mod->prev->is_mixt_mod == NO)   { mod  = mod->prev;  }
-                }
-              
-              /*! Read and process model components
-               */
-              char *list;
-              list = XML_Get_Attribute_Value(m_elem,"list");
-              
-              j = 0;
-              For(i,(int)strlen(list)) if(list[i] == ',') j++;
-              
-              if(j != n_components && first_m_elem > 1)
-                {
-                  PhyML_Printf("\n== Discrepancy in the number of elements in nodes 'mixtureelem' partitionelem id '%s'",p_elem->id);
-                  PhyML_Printf("\n== Check 'mixturelem' node with list '%s'",list);
-                  Exit("\n");
-                }
-              n_components = j;
-              
-              i = j = 0;
-              component[0] = '\0';
-              while(1)
-                {
-                  if(list[j] == ',' || j == (int)strlen(list))
-                    {
-                      /*! Reading a new component
-                       */
-                      
-                      if(first_m_elem == YES) /* Only true when processing the first mixtureelem node */
-                        {
-                          t_tree *this_tree;
-                          t_mod *this_mod;
-                          
-                          /*! Create new tree
-                           */
-                          this_tree = (t_tree *)Make_Tree_From_Scratch(io->cdata->n_otu,io->cdata);
-                          
-                          /*! Update the number of mixtures */
-                          iomod->n_mixt_classes++;
-                          
-                          if(tree)
-                            {
-                              tree->next = this_tree;
-                              tree->next->prev = tree;
-                            }
-                          else
-                            {
-                              mixt_tree->next = this_tree;
-                              mixt_tree->next->prev = mixt_tree;
-                            }
-                          
-                          tree = this_tree;
-                          tree->mixt_tree = mixt_tree;
-                          
-                          
-                          /*! Create a new model
-                           */
-                          this_mod = (t_mod *)Make_Model_Basic();
-                          Set_Defaults_Model(this_mod);
-                          this_mod->ras->n_catg = 1;
-
-                          /*! All br_len_multiplier point to the corresponding */
-                          /*! parameter in the relevant mixt_tree */
-                          Free_Scalar_Dbl(this_mod->br_len_mult);
-                          this_mod->br_len_mult = iomod->br_len_mult;                          
-                          
-                          if(mod)
-                            {
-                              mod->next = this_mod;
-                              mod->next->prev = mod;
-                            }
-                          else
-                            {
-                              this_mod->prev = iomod;
-                            }
-                          
-                          mod = this_mod;
-                          if(!iomod->next) iomod->next = mod;
-                          mod->io = io;
-                          
-                          mod->s_opt = (t_opt *)Make_Optimiz();
-                          Set_Defaults_Optimiz(mod->s_opt);
-                          
-                          mod->s_opt->opt_alpha  = NO;
-                          mod->s_opt->opt_pinvar = NO;
-                          
-                          tree->data      = io->cdata;
-                          tree->n_pattern = io->cdata->crunch_len;
-                          tree->io        = io;
-                          tree->mod       = mod;
-                          
-                          if(tree->n_pattern != tree->prev->n_pattern) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
-                        }
-                      
-                      /*! Read a component
-                       */
-                      component[i] = '\0';
-                      if(j != (int)strlen(list)-1) i = 0;
-                      
-                      /*! Find which node this ID corresponds to
-                       */
-                      instance = XML_Search_Node_ID(component,YES,root);
-                      
-                      if(!instance)
-                        {
-                          PhyML_Printf("\n== Could not find a node with id:'%s'.",component);
-                          PhyML_Printf("\n== Problem with 'mixtureelem' node, list '%s'.",list);
-                          Exit("\n");
-                        }
-                      
-                      if(!instance->parent)
-                        {
-                          PhyML_Printf("\n== Node '%s' with id:'%s' has no parent.",instance->name,component);
-                          Exit("\n");
-                        }
-                      
-                      parent = instance->parent;
-                      
-                      ////////////////////////////////////////
-                      //        SUBSTITUTION MODEL          //
-                      ////////////////////////////////////////
-                      
-                      if(!strcmp(parent->name,"ratematrices"))
-                        {
-                          /* ! First time we process this 'instance' node which has this 'ratematrices' parent */
-                          if(instance->ds->obj == NULL)
-                            {
-                              Make_Ratematrice_From_XML_Node(instance, io, mod);
-                              
-                              ds = instance->ds;
-                              
-                              /*! Connect the data structure n->ds to mod->r_mat */
-                              ds->obj = (t_rmat *)(mod->r_mat);
-                              
-                              /*! Create and connect the data structure n->ds->next to mod->kappa */
-                              ds->next      = (t_ds *)mCalloc(1,sizeof(t_ds));
-                              ds = ds->next;
-                              ds->obj = (scalar_dbl *)(mod->kappa);
-                              
-                              /*! Create and connect the data structure n->ds->next to mod->s_opt->opt_kappa */
-                              ds->next      = (t_ds *)mCalloc(1,sizeof(t_ds));
-                              ds = ds->next;
-                              ds->obj = (int *)(&mod->s_opt->opt_kappa);
-                              
-                              /*! Create and connect the data structure n->ds->next to mod->s_opt->opt_rr */
-                              ds->next      = (t_ds *)mCalloc(1,sizeof(t_ds));
-                              ds = ds->next;
-                              ds->obj = (int *)(&mod->s_opt->opt_rr);
-                              
-                              /*! Create and connect the data structure n->ds->next to mod->whichmodel */
-                              ds->next      = (t_ds *)mCalloc(1,sizeof(t_ds));
-                              ds = ds->next;
-                              ds->obj = (int *)(&mod->whichmodel);
-                              
-                              /*! Create and connect the data structure n->ds->next to mod->modelname */
-                              ds->next      = (t_ds *)mCalloc(1,sizeof(t_ds));
-                              ds = ds->next;
-                              ds->obj = (t_string *)(mod->modelname);
-                              
-                              /*! Create and connect the data structure n->ds->next to mod->ns */
-                              ds->next      = (t_ds *)mCalloc(1,sizeof(t_ds));
-                              ds = ds->next;
-                              ds->obj = (int *)(&mod->ns);
-                              
-                              /*! Create and connect the data structure n->ds->next to mod->modelname */
-                              ds->next      = (t_ds *)mCalloc(1,sizeof(t_ds));
-                              ds = ds->next;
-                              ds->obj = (t_string *)(mod->custom_mod_string);
-
-
-                              /*! Create and connect the data structure n->ds->next to mod->fp_aa_rate_mat */
-                              ds->next      = (t_ds *)mCalloc(1,sizeof(t_ds));
-                              ds = ds->next;
-                              ds->obj = (FILE *)(mod->fp_aa_rate_mat);
-
-                              /*! Create and connect the data structure n->ds->next to mod->aa_rate_mat_file */
-                              ds->next      = (t_ds *)mCalloc(1,sizeof(t_ds));
-                              ds = ds->next;
-                              ds->obj = (t_string *)mod->aa_rate_mat_file;                              
-                            }
-                          else
-                            {
-                              /*! Connect to already extisting r_mat & kappa structs. */
-                              t_ds *ds;
-                              
-                              
-                              ds = instance->ds;
-                              Free(mod->r_mat);
-                              mod->r_mat             = (t_rmat *)ds->obj;
-                              
-                              ds = ds->next;
-                              Free_Scalar_Dbl(mod->kappa);
-                              mod->kappa             = (scalar_dbl *)ds->obj;
-                              
-                              ds = ds->next;
-                              mod->s_opt->opt_kappa  = *((int *)ds->obj);
-                              
-                              ds = ds->next;
-                              mod->s_opt->opt_rr     = *((int *)ds->obj);
-                              
-                              ds = ds->next;
-                              mod->whichmodel        = *((int *)ds->obj);
-                              
-                              ds = ds->next;
-                              Free_String(mod->modelname);
-                              mod->modelname         = (t_string *)ds->obj;
-                              
-                              ds = ds->next;
-                              mod->ns                = *((int *)ds->obj);
-                              
-                              ds = ds->next;
-                              Free_String(mod->custom_mod_string);
-                              mod->custom_mod_string = (t_string *)ds->obj;
-
-                              ds = ds->next;
-                              mod->fp_aa_rate_mat = (FILE *)ds->obj;
-
-                              ds = ds->next;
-                              Free_String(mod->aa_rate_mat_file);
-                              mod->aa_rate_mat_file = (t_string *)ds->obj;
-
-                            }
-                        }
-                      
-                      ////////////////////////////////////////
-                      //           STATE FREQS              //
-                      ////////////////////////////////////////
-                      
-                      else if(!strcmp(parent->name,"equfreqs"))
-                        {
-                          
-                          /* If n->ds == NULL, the corrresponding node data structure, n->ds, has not */
-                          /* been initialized. If not, do nothing. */
-                          if(instance->ds->obj == NULL)
-                            {
-                              Make_Efrq_From_XML_Node(instance,io,mod);
-                              
-                              t_ds *ds;
-                              
-                              ds = instance->ds;
-                              ds->obj = (t_efrq *)mod->e_frq;
-                              
-                              ds->next = (t_ds *)mCalloc(1,sizeof(t_ds));
-                              ds = ds->next;
-                              ds->obj = (int *)(&mod->s_opt->opt_state_freq);
-                              
-                              ds->next = (t_ds *)mCalloc(1,sizeof(t_ds));
-                              ds = ds->next;
-                              ds->obj = (int *)(&mod->s_opt->user_state_freq);
-                              
-                              ds->next = (t_ds *)mCalloc(1,sizeof(t_ds));
-                              ds = ds->next;
-                              ds->obj = (vect_dbl *)(mod->user_b_freq);
-                            }
-                          else
-                            {
-                              /* Connect the data structure n->ds to mod->e_frq */
-                              
-                              ds = instance->ds;
-                              mod->e_frq = (t_efrq *)ds->obj;
-                              
-                              ds = ds->next;
-                              mod->s_opt->opt_state_freq = *((int *)ds->obj);
-                              
-                              ds = ds->next;
-                              mod->s_opt->user_state_freq = *((int *)ds->obj);
-                              
-                              ds = ds->next;
-                              Free_Vect_Dbl(mod->user_b_freq);
-                              mod->user_b_freq = (vect_dbl *)ds->obj;
-                            }
-                        }
-                      
-                      //////////////////////////////////////////
-                      //             TOPOLOGY                 //
-                      //////////////////////////////////////////
-                      
-                      else if(!strcmp(parent->name,"topology"))
-                        {
-                          if(parent->ds->obj == NULL) Make_Topology_From_XML_Node(instance,io,iomod);
-                          
-                          ds = parent->ds;
-                          
-                          int buff;
-                          ds->obj = (int *)(& buff);
-                        }
-                      
-                      //////////////////////////////////////////
-                      //                RAS                   //
-                      //////////////////////////////////////////
-                      
-                      else if(!strcmp(parent->name,"siterates"))
-                        {
-                          char *rate_value = NULL;
-                          /* scalar_dbl *r; */
-                          phydbl val;
-                          
-                          /*! First time we process this 'siterates' node, check that its format is valid.
-                            and process it afterwards.
-                          */
-                          if(parent->ds->obj == NULL)
-                            {
-                              class_number = 0;
-                              
-                              Make_RAS_From_XML_Node(parent,iomod);
-                              
-                              ds = parent->ds;
-                              
-                              ds->obj = (t_ras *)iomod->ras;
-                              
-                              ds->next      = (t_ds *)mCalloc(1,sizeof(t_ds));
-                              ds = ds->next;
-                              ds->obj = (int *)(&iomod->s_opt->opt_alpha);
-                              
-                              ds->next      = (t_ds *)mCalloc(1,sizeof(t_ds));
-                              ds = ds->next;
-                              ds->obj = (int *)(&iomod->s_opt->opt_free_mixt_rates);
-                            }
-                          else /*! Connect ras struct to already defined one. Same for opt_alpha & opt_free_mixt_rates */
-                            {
-                              if(iomod->ras != (t_ras *)parent->ds->obj) Free_RAS(iomod->ras);
-                              iomod->ras = (t_ras *)parent->ds->obj;
-                              iomod->s_opt->opt_alpha = *((int *)parent->ds->next->obj);
-                              iomod->s_opt->opt_free_mixt_rates = *((int *)parent->ds->next->next->obj);
-                            }
-                          
-                          rate_value = XML_Get_Attribute_Value(instance,"init.value");
-                          
-                          val = 1.;
-                          if(rate_value) val = String_To_Dbl(rate_value);
-                          
-                          if(instance->ds->obj == NULL)
-                            {
-                              instance->ds->obj = (phydbl *)(&val);
-                              instance->ds->next = (t_ds *)mCalloc(1,sizeof(t_ds));
-                              instance->ds->next->obj = (int *)(class_num + class_number);
-                              
-                              iomod->ras->gamma_rr->v[class_number] = val;
-                              iomod->ras->gamma_rr_unscaled->v[class_number] = val;
-                              
-                              iomod->ras->init_rr = NO;
-                              
-                              if(Are_Equal(val,0.0,1E-20) == NO) class_number++;
-                            }
-                          
-                          
-                          /*! Note: ras is already connected to the relevant t_ds stucture. No need
-                            to connect ras->gamma_rr or ras->p_invar */
-                          
-                          /*! Invariant */
-                          if(Are_Equal(val,0.0,1E-20))
-                            {
-                              mod->ras->invar = YES;
-                            }
-                          else
-                            {
-                              mod->ras->parent_class_number = *((int *)instance->ds->next->obj);
-                            }
-                          
-                          xml_node *orig_w = NULL;
-                          orig_w = XML_Search_Node_Attribute_Value("appliesto",instance->id,YES,instance->parent);
-                          
-                          if(orig_w)
-                            {
-                              char *weight;
-                              weight = XML_Get_Attribute_Value(orig_w,"value");
-                              if(mod->ras->invar == YES)
-                                {
-                                  iomod->ras->pinvar->v = String_To_Dbl(weight);
-                                }
-                              else
-                                {
-                                  int class;
-                                  class = *((int *)instance->ds->next->obj);
-                                  iomod->ras->gamma_r_proba->v[class] = String_To_Dbl(weight);
-                                  iomod->ras->init_r_proba = NO;
-                                }
-                            }
-                        }
-                      
-                      //////////////////////////////////////////////
-                      //           BRANCH LENGTHS                 //
-                      //////////////////////////////////////////////
-                      
-                      else if(!strcmp(parent->name,"branchlengths"))
-                        {
-                          int i;
-                          int n_otu;
-                          
-                          n_otu = tree->n_otu;
-                          
-                          if(instance->ds->obj == NULL)
-                            {
-                              if(!lens)
-                                {
-                                  ori_lens         = (scalar_dbl **)mCalloc(2*tree->n_otu-1,sizeof(scalar_dbl *));
-                                  ori_lens_old     = (scalar_dbl **)mCalloc(2*tree->n_otu-1,sizeof(scalar_dbl *));
-                                  
-                                  ori_lens_var     = (scalar_dbl **)mCalloc(2*tree->n_otu-1,sizeof(scalar_dbl *));
-                                  ori_lens_var_old = (scalar_dbl **)mCalloc(2*tree->n_otu-1,sizeof(scalar_dbl *));
-                                  
-                                  lens     = ori_lens;
-                                  lens_old = ori_lens_old;
-                                  
-                                  lens_var     = ori_lens_var;
-                                  lens_var_old = ori_lens_var_old;
-                                  
-                                  lens_size = 2*tree->n_otu-1;
-                                }
-                              else
-                                {
-                                  ori_lens         = (scalar_dbl **)mRealloc(ori_lens,2*tree->n_otu-1+lens_size,sizeof(scalar_dbl *));
-                                  ori_lens_old     = (scalar_dbl **)mRealloc(ori_lens_old,2*tree->n_otu-1+lens_size,sizeof(scalar_dbl *));
-                                  
-                                  ori_lens_var     = (scalar_dbl **)mRealloc(ori_lens_var,2*tree->n_otu-1+lens_size,sizeof(scalar_dbl *));
-                                  ori_lens_var_old = (scalar_dbl **)mRealloc(ori_lens_var_old,2*tree->n_otu-1+lens_size,sizeof(scalar_dbl *));
-                                  
-                                  lens     = ori_lens     + lens_size;;
-                                  lens_old = ori_lens_old + lens_size;;
-                                  
-                                  lens_var     = ori_lens_var     + lens_size;;
-                                  lens_var_old = ori_lens_var_old + lens_size;;
-                                  
-                                  lens_size += 2*tree->n_otu-1;
-                                }
-                              
-                              For(i,2*tree->n_otu-1)
-                                {
-                                  lens[i] = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl));
-                                  Init_Scalar_Dbl(lens[i]);
-                                  
-                                  lens_old[i] = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl));
-                                  Init_Scalar_Dbl(lens_old[i]);
-                                  
-                                  lens_var[i] = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl));
-                                  Init_Scalar_Dbl(lens_var[i]);
-                                  
-                                  lens_var_old[i] = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl));
-                                  Init_Scalar_Dbl(lens_var_old[i]);
-                                  
-                                  Free_Scalar_Dbl(tree->a_edges[i]->l);
-                                  Free_Scalar_Dbl(tree->a_edges[i]->l_old);
-                                  
-                                  Free_Scalar_Dbl(tree->a_edges[i]->l_var);
-                                  Free_Scalar_Dbl(tree->a_edges[i]->l_var_old);
-                                  
-                                  if(tree->prev &&
-                                     tree->prev->a_edges[i]->l == mixt_tree->a_edges[i]->l &&
-                                     tree->prev->is_mixt_tree == NO)
-                                    {
-                                      PhyML_Printf("\n== %p %p",tree->a_edges[i]->l,mixt_tree->a_edges[i]->l);
-                                      PhyML_Printf("\n== Only one set of edge lengths is allowed ");
-                                      PhyML_Printf("\n== in a 'partitionelem'. Please fix your XML file.");
-                                      Exit("\n");
-                                    }
-                                }
-                              
-                              char *opt_bl = NULL;
-                              opt_bl = XML_Get_Attribute_Value(instance,"optimise.lens");
-                              
-                              if(opt_bl)
-                                {
-                                  if(!strcmp(opt_bl,"yes") || !strcmp(opt_bl,"true"))
-                                    {
-                                      iomod->s_opt->opt_bl = YES;
-                                    }
-                                  else
-                                    {
-                                      iomod->s_opt->opt_bl = NO;
-                                    }
-                                }
-                              
-                              ds = instance->ds;
-                              
-                              ds->obj       = (scalar_dbl **)lens;
-                              
-                              ds->next      = (t_ds *)mCalloc(1,sizeof(t_ds));
-                              ds            = ds->next;
-                              ds->obj       = (scalar_dbl **)lens_old;
-                              
-                              ds->next      = (t_ds *)mCalloc(1,sizeof(t_ds));
-                              ds            = ds->next;
-                              ds->obj       = (scalar_dbl **)lens_var;
-                              
-                              ds->next      = (t_ds *)mCalloc(1,sizeof(t_ds));
-                              ds            = ds->next;
-                              ds->obj       = (scalar_dbl **)lens_var_old;
-                              
-                              ds->next      = (t_ds *)mCalloc(1,sizeof(t_ds));
-                              ds            = ds->next;
-                              ds->obj       = (int *)(&iomod->s_opt->opt_bl);
-                            }
-                          else
-                            {
-                              For(i,2*tree->n_otu-1)
-                                {
-                                  Free_Scalar_Dbl(tree->a_edges[i]->l);
-                                  Free_Scalar_Dbl(tree->a_edges[i]->l_old);
-                                  Free_Scalar_Dbl(tree->a_edges[i]->l_var);
-                                  Free_Scalar_Dbl(tree->a_edges[i]->l_var_old);
-                                }
-                              
-                              ds = instance->ds;
-                              
-                              lens     = (scalar_dbl **)ds->obj;
-                              
-                              ds = ds->next;
-                              lens_old = (scalar_dbl **)ds->obj;
-                              
-                              ds = ds->next;
-                              lens_var = (scalar_dbl **)ds->obj;
-                              
-                              ds = ds->next;
-                              lens_var_old = (scalar_dbl **)ds->obj;
-                              
-                              ds = ds->next;
-                              iomod->s_opt->opt_bl = *((int *)ds->obj);
-                            }
-                          
-                          if(n_otu != tree->n_otu)
-                            {
-                              PhyML_Printf("\n== All the data sets should display the same number of sequences.");
-                              PhyML_Printf("\n== Found at least one data set with %d sequences and one with %d sequences.",n_otu,tree->n_otu);
-                              Exit("\n");
-                            }
-                          
-                          For(i,2*tree->n_otu-1)
-                            {
-                              tree->a_edges[i]->l          = lens[i];
-                              mixt_tree->a_edges[i]->l     = lens[i];
-                              tree->a_edges[i]->l_old      = lens_old[i];
-                              mixt_tree->a_edges[i]->l_old = lens_old[i];
-                              
-                              tree->a_edges[i]->l_var          = lens_var[i];
-                              mixt_tree->a_edges[i]->l_var     = lens_var[i];
-                              tree->a_edges[i]->l_var_old      = lens_var_old[i];
-                              mixt_tree->a_edges[i]->l_var_old = lens_var_old[i];
-                            }
-                        }
-                      
-                      ///////////////////////////////////////////////
-                      ///////////////////////////////////////////////
-                      ///////////////////////////////////////////////
-                      
-                      if(first_m_elem > 1) // Done with this component, move to the next tree and model
-                        {
-                          if(tree->next) tree = tree->next;
-                          if(mod->next)   mod  = mod->next;
-                        }
-                      
-                    }
-                  else if(list[j] != ' ')
-                    {
-                      component[i] = list[j];
-                      i++;
-                    }
-                  j++;
-                  if(j == (int)strlen(list)+1) break;
-                  
-                } // end of mixtureelem processing
-            } // end of partitionelem processing
-        }
-      while(1);
-    }
-  while(1);
-  
-  
-  if(ori_lens)         Free(ori_lens);
-  if(ori_lens_old)     Free(ori_lens_old);
-  if(ori_lens_var)     Free(ori_lens_var);
-  if(ori_lens_var_old) Free(ori_lens_var_old);
-
-  while(io->prev != NULL) io = io->prev;
-  while(mixt_tree->prev != NULL) mixt_tree = mixt_tree->prev;
-
-  /*! Finish making the models */
-  mod = mixt_tree->mod;
-  do
-    {
-      Make_Model_Complete(mod);
-      mod = mod->next;
-    }
-  while(mod);
-
-  Check_Taxa_Sets(mixt_tree);
-
-  Check_Mandatory_XML_Node(root,"phyml");
-  Check_Mandatory_XML_Node(root,"topology");
-  Check_Mandatory_XML_Node(root,"branchlengths");
-  Check_Mandatory_XML_Node(root,"ratematrices");
-  Check_Mandatory_XML_Node(root,"equfreqs");
-  Check_Mandatory_XML_Node(root,"siterates");
-  Check_Mandatory_XML_Node(root,"partitionelem");
-  Check_Mandatory_XML_Node(root,"mixtureelem");
-
-  if(!io->mod->s_opt->random_input_tree) io->mod->s_opt->n_rand_starts = 1;
-
-  char *most_likely_tree = NULL;
-  phydbl best_lnL = UNLIKELY;
-  int num_rand_tree;
   For(num_rand_tree,io->mod->s_opt->n_rand_starts)
     {
-      /*! Initialize the models */
-      mod = mixt_tree->mod;
-      do
-        {
-          Init_Model(mod->io->cdata,mod,io);
-          mod = mod->next;
-        }
-      while(mod);
-
-      /* printf("\n%f %f %f %f", */
-      /*        mixt_tree->mod->ras->gamma_r_proba->v[0], */
-      /*        mixt_tree->mod->ras->gamma_r_proba->v[1], */
-      /*        mixt_tree->mod->ras->gamma_r_proba->v[2], */
-      /*        mixt_tree->mod->ras->gamma_r_proba->v[3]); */
-      /* Exit("\n"); */
-
-      Print_Data_Structure(NO,stdout,mixt_tree);
-
-      t_tree *bionj_tree = NULL;
-      switch(mixt_tree->io->in_tree)
-        {
-        case 2: /*! user-defined input tree */
-          {
-            if(!mixt_tree->io->fp_in_tree)
-              {
-                PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__);
-                Exit("\n");
-              }
-
-            /*!
-              Copy the user tree to all the tree structures
-            */
-            tree = Read_User_Tree(mixt_tree->io->cdata,
-                                  mixt_tree->mod,
-                                  mixt_tree->io);
-            break;
-          }
-        case 1: case 0:
-          {
-            if(!bionj_tree)
-              {
-                /*! Build a BioNJ tree from the analysis of
-                  the first partition element
-                */
-                tree = Dist_And_BioNJ(mixt_tree->data,
-                                      mixt_tree->mod,
-                                      mixt_tree->io);
-                bionj_tree = (t_tree *)Make_Tree_From_Scratch(mixt_tree->n_otu,mixt_tree->data);
-                Copy_Tree(tree,bionj_tree);
-              }
-            else
-              {
-                tree = (t_tree *)Make_Tree_From_Scratch(mixt_tree->n_otu,mixt_tree->data);
-                Copy_Tree(bionj_tree,tree);
-              }
-            break;
-          }
-        }
-
-
-      Copy_Tree(tree,mixt_tree);
-      Free_Tree(tree);
-      if(bionj_tree) Free_Tree(bionj_tree);
-
-      if(io->mod->s_opt->random_input_tree)
-        {
-          PhyML_Printf("\n\n. [%3d/%3d]",num_rand_tree+1,io->mod->s_opt->n_rand_starts);
-          Random_Tree(mixt_tree);
-        }
-
-      tree = mixt_tree;
-      do
-        {
-          if(tree != mixt_tree) Copy_Tree(mixt_tree,tree);
-          Connect_CSeqs_To_Nodes(tree->data,io,tree);
-          tree = tree->next;
-        }
-      while(tree);
-
-
-      /*! Initialize t_beg in each mixture tree */
-      tree = mixt_tree;
-      do
-        {
-          time(&(tree->t_beg));
-          tree = tree->next_mixt;
-        }
-      while(tree);
-
-      Prepare_Tree_For_Lk(mixt_tree);
-
-      MIXT_Chain_All(mixt_tree);
-
-      /*! Check that all the edges in a mixt_tree at pointing
-        to a single set of lengths
-      */
-      tree = mixt_tree;
-      do
-        {
-          MIXT_Check_Single_Edge_Lens(tree);
-          tree = tree->next_mixt;
-        }
-      while(tree);
-
-      /*! Turn all branches to ON state */
-      tree = mixt_tree;
-      do
-        {
-          MIXT_Turn_Branches_OnOff(ON,tree);
-          tree = tree->next_mixt;
-        }
-      while(tree);
-
-      
-      tree = mixt_tree;
-      do
-        {
-          if(tree->next_mixt)
-            {
-              tree->mod->next_mixt = tree->next_mixt->mod;
-              tree->next_mixt->mod->prev_mixt = tree->mod;
-            }
-          tree = tree->next_mixt;
-        }
-      while(tree);
-
-
-
-      /* TO DO
-
-         1) REMOVE ROOT
-         X 2) ALLOW MORE THAN ONE VECTOR OF BRANCH LENGTHS -> NEED TO
-         LOOK CAREFULY AT WHAT IT MEANS FOR SPR,  SIMULTANEOUS NNI MOVES
-         PRUNE AND REGRAFT...
-         X 3) Branch lengths in Prune and Regarft -> make sure you don't apply
-         change several times
-         4) Make sure you can't have the same branch lengths with distinct
-         data types
-         5) Finish rewritting Opt_Free_Param
-         X 6) Make sure you can have only one set of branch lengths per partition
-         7) BIONJ starting tree
-         X 8) When iomod->ras->invar = YES, check that only one mod has mod->ras->invar = YES;
-         9) Reflect changes on simu.c to spr.c, especially regarding invariants
-         10) Rough_SPR to replace SPR_Shuffle and first step in nni (refining tree)
-         11) Tree corresponding to invar class is never really used (except for testing
-         whether tree->mod->ras->invar==YES). Do we need to use memory for this?
-         X 12) Check that mixt_tree->mod->ras->n_catg corresponds to the same number of
-         trees in the mixture (do that for each mixt_tree).
-         13) Change tree->a_edges to tree->a_edges (t is for type a is for array)
-         14) Change tree->a_nodes to tree->a_nodes (t is for type a is for array)
-         X 15) tstv should be shared! Check the following:
-         // Connect the data structure n->ds to mod->r_mat
-         mod->r_mat = (t_rmat *)instance->ds->obj;
-         mod->kappa = (scalar_dbl *)instance->ds->next->obj;
-         16) Replace s_opt struct by opt flag for each param?
-         X 17) Check the sequences and tree have the same number of otus
-         X 18) Avoid transformation to lower case of attribute values when processing XML.
-         X 19) Break mixture: break nodes and branches too.
-         X 20) Check alrt.c
-         X 21) Set_Alias_Subpatt
-         X 22) Check that all partition elements have the same set of taxa.
-         23) What if ratematrices are not specified ? Default is ok?
-         X 24) Set upper and lower bounds on Br_Len_Brent
-      */
-
-
-      MIXT_Check_Invar_Struct_In_Each_Partition_Elem(mixt_tree);
-      MIXT_Check_RAS_Struct_In_Each_Partition_Elem(mixt_tree);
-
+      MIXT_Prepare_All(num_rand_tree,mixt_tree);
+      Br_Len_Not_Involving_Invar(mixt_tree);
+      Unscale_Br_Len_Multiplier_Tree(mixt_tree);
       Set_Both_Sides(YES,mixt_tree);
-
+      
       if(mixt_tree->mod->s_opt->opt_topo)
         {
           if(mixt_tree->mod->s_opt->topo_search      == NNI_MOVE) Simu_Loop(mixt_tree);
@@ -5778,7 +4635,6 @@ option *PhyML_XML(char *xml_filename)
           if(mixt_tree->mod->s_opt->opt_subst_param ||
              mixt_tree->mod->s_opt->opt_bl)
             {
-
               Round_Optimize(mixt_tree,mixt_tree->data,ROUND_MAX);
             }
           else
@@ -5790,6 +4646,7 @@ option *PhyML_XML(char *xml_filename)
 
       PhyML_Printf("\n\n. Log-likelihood = %f",mixt_tree->c_lnL);
 
+
       if((num_rand_tree == io->mod->s_opt->n_rand_starts-1) && (io->mod->s_opt->random_input_tree))
         {
           num_rand_tree--;
@@ -5815,15 +4672,15 @@ option *PhyML_XML(char *xml_filename)
           mixt_tree->lock_topo = NO;
         }
 
-      /*! Initialize t_end in each mixture tree */
       tree = mixt_tree;
       do
         {
-          time(&(tree->t_current));
+          if(tree->io->print_site_lnl == YES) Print_Site_Lk(tree,tree->io->fp_out_lk);
           tree = tree->next_mixt;
         }
       while(tree);
 
+      MIXT_Init_T_End(mixt_tree);
       Print_Data_Structure(YES,mixt_tree->io->fp_out_stats,mixt_tree);
 
       Free_Spr_List(mixt_tree);
@@ -5835,10 +4692,9 @@ option *PhyML_XML(char *xml_filename)
   /*! Print the most likely tree in the output file */
   if(!mixt_tree->io->quiet) PhyML_Printf("\n\n. Printing the most likely tree in file '%s'...\n", Basename(mixt_tree->io->out_tree_file));
   PhyML_Fprintf(mixt_tree->io->fp_out_tree,"%s\n",most_likely_tree);
-  Free(component);
 
   /*! Bootstrap analysis */
-  MIXT_Bootstrap(most_likely_tree,root);
+  MIXT_Bootstrap(most_likely_tree,xml_root);
 
   while(io->prev != NULL) io = io->prev;
 
@@ -5847,7 +4703,7 @@ option *PhyML_XML(char *xml_filename)
   tree = mixt_tree;
   do
     {
-      Free_Cseq(tree->data);
+      Free_Calign(tree->data);
       tree = tree->next_mixt;
     }
   while(tree);
@@ -5864,15 +4720,13 @@ option *PhyML_XML(char *xml_filename)
   Free_Model_Basic(mixt_tree->mod);
   Free_Tree(mixt_tree);
 
-  if(io->fp_out_trees) fclose(io->fp_out_trees);
-  if(io->fp_out_tree)  fclose(io->fp_out_tree);
-  if(io->fp_out_stats) fclose(io->fp_out_stats);
+  if(io->fp_out_trees)      fclose(io->fp_out_trees);
+  if(io->fp_out_tree)       fclose(io->fp_out_tree);
+  if(io->fp_out_stats)      fclose(io->fp_out_stats);
+  if(io->fp_out_json_trace) fclose(io->fp_out_json_trace);
   Free_Input(io);
-  XML_Free_XML_Tree(root);
-
-  Free(class_num);
 
-  fclose(fp);
+  XML_Free_XML_Tree(xml_root);
 
   return(dum);
 }
@@ -5958,10 +4812,8 @@ void Make_Ratematrice_From_XML_Node(xml_node *instance, option *io, t_mod *mod)
                                  "LG",       //26
                                  "AB" );     //27
 
-
   if(select < 9)
     {
-      mod->ns = 4;
       if(io->datatype != NT)
         {
           PhyML_Printf("\n== Data type and selected model are incompatible");
@@ -5970,7 +4822,6 @@ void Make_Ratematrice_From_XML_Node(xml_node *instance, option *io, t_mod *mod)
     }
   else
     {
-      mod->ns = 20;
       if(io->datatype != AA)
         {
           PhyML_Printf("\n== Data type and selected model are incompatible");
@@ -5978,8 +4829,6 @@ void Make_Ratematrice_From_XML_Node(xml_node *instance, option *io, t_mod *mod)
         }
     }
 
-  io->mod->ns = mod->ns;
-
   mod->r_mat = (t_rmat *)Make_Rmat(mod->ns);
   Init_Rmat(mod->r_mat);
 
@@ -6075,7 +4924,6 @@ void Make_Ratematrice_From_XML_Node(xml_node *instance, option *io, t_mod *mod)
         }
       else
         {
-          mod->fp_aa_rate_mat = Openfile(r_mat_file,0);
           strcpy(mod->aa_rate_mat_file->s,r_mat_file);
         }
 
@@ -6103,7 +4951,7 @@ void Make_Efrq_From_XML_Node(xml_node *instance, option *io, t_mod *mod)
   char *buff;
 
   mod->e_frq = (t_efrq *)Make_Efrq(mod->ns);
-  Init_Efrq(mod->e_frq);
+  Init_Efrq(NULL,mod->e_frq);
 
   buff = XML_Get_Attribute_Value(instance,"optimise.freqs");
 
@@ -6130,14 +4978,14 @@ void Make_Efrq_From_XML_Node(xml_node *instance, option *io, t_mod *mod)
         {
           if(io->datatype == AA)
             {
-              mod->s_opt->opt_state_freq = YES;
+              mod->s_opt->opt_state_freq       = YES;
+              mod->e_frq->empirical_state_freq = YES;
             }
           else if(io->datatype == NT)
             {
               mod->s_opt->opt_state_freq = NO;
             }
         }
-      /* Free(buff); */
     }
 
 
@@ -6154,11 +5002,11 @@ void Make_Efrq_From_XML_Node(xml_node *instance, option *io, t_mod *mod)
         {
           phydbl A,C,G,T;
           sscanf(buff,"%lf,%lf,%lf,%lf",&A,&C,&G,&T);
-          mod->user_b_freq->v[0] = (phydbl)A;
-          mod->user_b_freq->v[1] = (phydbl)C;
-          mod->user_b_freq->v[2] = (phydbl)G;
-          mod->user_b_freq->v[3] = (phydbl)T;
-          mod->s_opt->user_state_freq = YES;
+          mod->e_frq->user_b_freq->v[0] = (phydbl)A;
+          mod->e_frq->user_b_freq->v[1] = (phydbl)C;
+          mod->e_frq->user_b_freq->v[2] = (phydbl)G;
+          mod->e_frq->user_b_freq->v[3] = (phydbl)T;
+          mod->e_frq->user_state_freq = YES;
           mod->s_opt->opt_state_freq  = NO;
         }
     }
@@ -6314,6 +5162,7 @@ void Make_RAS_From_XML_Node(xml_node *parent, t_mod *mod)
   char *family;
   int select;
 
+  family = NULL;
   mod->ras->n_catg = 0;
 
   XML_Check_Siterates_Node(parent);
@@ -6322,7 +5171,8 @@ void Make_RAS_From_XML_Node(xml_node *parent, t_mod *mod)
   if(w)
     {
       family = XML_Get_Attribute_Value(w,"family");
-      select = XML_Validate_Attr_Int(family,3,"gamma","gamma+inv","freerates");
+      if(family == NULL) select = -1;
+      else               select = XML_Validate_Attr_Int(family,3,"gamma","gamma+inv","freerates");
       switch(select)
         {
         case 0:// Gamma model
@@ -6466,7 +5316,16 @@ void Make_RAS_From_XML_Node(xml_node *parent, t_mod *mod)
           }
         default:
           {
-            PhyML_Printf("\n== family: %s",family);
+            if(family != NULL) PhyML_Printf("\n== family: %s",family);
+            else 
+              {
+                PhyML_Printf("\n== Please specify a model family (\"gamma\", \"gamma+inv\" or \"freerate\")");
+                PhyML_Printf("\n== for every 'weights' element in every 'siterate' element. Note that " );
+                PhyML_Printf("\n== a \"gamma\" or a \"freerate\" model with a single rate class amounts");
+                PhyML_Printf("\n== to no variation of rates across sites, if this is the model you'd");
+                PhyML_Printf("\n== like to implement...");
+              }
+
             PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__);
             Exit("\n");
           }
@@ -6502,10 +5361,285 @@ void Generic_Exit(const char *file, int line, const char *function)
 
 /*////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////*/
+
+void JSON_Write_Object(json_o *obj, FILE *where)
+{
+  json_sv *sv;
+  
+  assert(obj);
+  assert(where);
+  
+  sv = obj->sv;
+  assert(sv);
+
+  PhyML_Fprintf(where,"{");
+
+  do
+    {
+      PhyML_Fprintf(where,"\"%s\":",sv->string);
+      if(sv->value != NULL) PhyML_Fprintf(where,"\"%s\"",sv->value);
+      else if(sv->array != NULL) JSON_Write_Array(sv->array,where);
+      else if(sv->object != NULL) JSON_Write_Object(sv->object,where);
+      sv = sv->next;
+      if(sv) PhyML_Fprintf(where,",");      
+    }
+  while(sv);
+
+  PhyML_Fprintf(where,"}");
+}
+
 /*////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////*/
+
+void JSON_Write_Array(json_a *array, FILE *where)
+{
+  json_o *o;
+
+  assert(where);
+  assert(array);
+
+  o = array->object;
+  
+  assert(o);
+
+  PhyML_Fprintf(where,"[");
+
+  do
+    {      
+      JSON_Write_Object(o,where);      
+      o = o->next;
+      if(o) PhyML_Fprintf(where,",");
+    }
+  while(o);
+  
+  PhyML_Fprintf(where,"]\n");
+}
+
+/*////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////*/
+
+void JSON_Write_All(json_a *array, FILE *where)
+{
+  JSON_Write_Array(array,where);  
+}
+
 /*////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////*/
+
+json_o *JSON_Tree_To_Object(t_tree *tree)
+{
+  json_sv *state,*sv;
+  json_o *ret,*o;
+  json_a *a;
+  int string_len;
+  char *s;
+  time_t t_end;
+
+  string_len = 20;
+
+  ret = (json_o *)mCalloc(1,sizeof(json_o));
+  ret->next = NULL;
+  
+  state = (json_sv *)mCalloc(1,sizeof(json_sv));
+  ret->sv = state;
+
+  state->string = (char *)mCalloc(string_len,sizeof(char));
+  strcpy(state->string,"state");
+  
+  state->value = NULL; state->array = NULL; state->object = NULL; state->next = NULL;
+
+  state->array = (json_a *)mCalloc(1,sizeof(json_a));
+  a = state->array;
+
+  a->object = (json_o *)mCalloc(1,sizeof(json_o));
+  o = a->object;
+
+  // State num
+  o->sv = (json_sv *)mCalloc(1,sizeof(json_sv));
+  sv = o->sv;
+  sv->value = NULL; sv->array = NULL; sv->object = NULL; sv->next = NULL;
+  sv->string = (char *)mCalloc(string_len,sizeof(char));
+  strcpy(sv->string,"type");
+  sv->value = (char *)mCalloc(string_len,sizeof(char));
+  strcpy(sv->value,"t_num");
+  
+  sv->next = (json_sv *)mCalloc(1,sizeof(json_sv));
+  sv = sv->next;
+
+  sv->value = NULL; sv->array = NULL; sv->object = NULL; sv->next = NULL;
+  sv->string = (char *)mCalloc(string_len,sizeof(char));
+  strcpy(sv->string,"id");
+  sv->value = (char *)mCalloc(string_len,sizeof(char));
+  strcpy(sv->value,"state_num");
+
+  sv->next = (json_sv *)mCalloc(1,sizeof(json_sv));
+  sv = sv->next;
+
+  sv->value = NULL; sv->array = NULL; sv->object = NULL; sv->next = NULL;
+  sv->string = (char *)mCalloc(string_len,sizeof(char));
+  strcpy(sv->string,"value");
+  sv->value = (char *)mCalloc(string_len,sizeof(char));
+  sprintf(sv->value,"%d",tree->json_num);
+  tree->json_num++;
+  
+  sv->next = NULL;
+
+
+
+  
+  // Time
+  o->next = (json_o *)mCalloc(1,sizeof(json_o));
+  o = o->next;
+
+  o->sv = (json_sv *)mCalloc(1,sizeof(json_sv));
+  sv = o->sv;
+  
+  sv->value  = NULL; sv->array  = NULL; sv->object = NULL; sv->next = NULL;
+  sv->string = (char *)mCalloc(string_len,sizeof(char));
+  strcpy(sv->string,"type");
+  sv->value = (char *)mCalloc(string_len,sizeof(char));
+  strcpy(sv->value,"t_time");
+  
+  sv->next = (json_sv *)mCalloc(1,sizeof(json_sv));
+  sv = sv->next;
+  sv->value  = NULL; sv->array  = NULL; sv->object = NULL; sv->next = NULL;
+  sv->string = (char *)mCalloc(string_len,sizeof(char));
+  strcpy(sv->string,"id");
+  sv->value = (char *)mCalloc(string_len,sizeof(char));
+  strcpy(sv->value,"time");
+
+
+  sv->next = (json_sv *)mCalloc(1,sizeof(json_sv));
+  sv = sv->next;
+  sv->value = NULL; sv->array = NULL; sv->object = NULL; sv->next = NULL;
+  sv->string = (char *)mCalloc(string_len,sizeof(char));
+  strcpy(sv->string,"value");
+  sv->value = (char *)mCalloc(string_len,sizeof(char));
+  time(&t_end);
+  sprintf(sv->value,"%d",(int)(t_end-tree->t_beg));
+  
+  sv->next = NULL;
+
+
+  // Tree
+  o->next = (json_o *)mCalloc(1,sizeof(json_o));
+  o = o->next;
+
+  o->sv = (json_sv *)mCalloc(1,sizeof(json_sv));
+  sv = o->sv;
+
+  sv->value  = NULL; sv->array = NULL; sv->object = NULL; sv->next = NULL;
+  sv->string = (char *)mCalloc(string_len,sizeof(char));
+  strcpy(sv->string,"type");
+  sv->value = (char *)mCalloc(string_len,sizeof(char));
+  strcpy(sv->value,"t_tree");
+  
+  sv->next = (json_sv *)mCalloc(1,sizeof(json_sv));
+  sv = sv->next;
+  sv->value = NULL; sv->array = NULL; sv->object = NULL; sv->next = NULL;
+  sv->string = (char *)mCalloc(string_len,sizeof(char));
+  strcpy(sv->string,"id");
+  sv->value = (char *)mCalloc(string_len,sizeof(char));
+  strcpy(sv->value,"tree");
+
+
+  sv->next = (json_sv *)mCalloc(1,sizeof(json_sv));
+  sv = sv->next;
+  sv->value = NULL; sv->array = NULL; sv->object = NULL; sv->next = NULL;
+  sv->string = (char *)mCalloc(string_len,sizeof(char));
+  strcpy(sv->string,"value");
+  s = Write_Tree(tree,NO);
+  sv->value = (char *)mCalloc((int)strlen(s)+1,sizeof(char));
+  sprintf(sv->value,"%s",s);
+  Free(s);
+
+  sv->next = NULL;
+
+
+
+  // Likelihood
+  o->next = (json_o *)mCalloc(1,sizeof(json_o));
+  o = o->next;
+
+  o->sv = (json_sv *)mCalloc(1,sizeof(json_sv));
+  sv = o->sv;
+
+  sv->value = NULL; sv->array = NULL; sv->object = NULL; o->next = NULL;
+  sv->string = (char *)mCalloc(string_len,sizeof(char));
+  strcpy(sv->string,"type");
+  sv->value = (char *)mCalloc(string_len,sizeof(char));
+  strcpy(sv->value,"t_param");
+  
+  sv->next = (json_sv *)mCalloc(1,sizeof(json_sv));
+  sv = sv->next;
+  sv->value = NULL; sv->array = NULL; sv->object = NULL; sv->next = NULL;
+  sv->string = (char *)mCalloc(string_len,sizeof(char));
+  strcpy(sv->string,"id");
+  sv->value = (char *)mCalloc(string_len,sizeof(char));
+  strcpy(sv->value,"likelihood");
+
+
+  sv->next = (json_sv *)mCalloc(1,sizeof(json_sv));
+  sv = sv->next;
+  sv->value = NULL; sv->array = NULL; sv->object = NULL; sv->next = NULL;
+  sv->string = (char *)mCalloc(string_len,sizeof(char));
+  strcpy(sv->string,"value");
+  sv->value = (char *)mCalloc(string_len,sizeof(char));
+  sprintf(sv->value,"%G",tree->c_lnL);
+
+  sv->next = NULL;
+
+  return(ret);
+}
+
+/*////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////*/
+
+void JSON_Tree_Io(t_tree *tree, FILE *where)
+{
+  // Append
+  json_o *o;
+  fpos_t pos;
+  /* char c; */
+
+  fgetpos(where,&pos);
+
+  rewind(where);
+  /* c = fgetc(where); */
+
+  /* if(c != '[') */
+  /*   { */
+  /*     PhyML_Fprintf(where,"["); */
+  /*   } */
+  /* else */
+  /*   { */
+  /*     fsetpos(where,&pos); */
+  /*     fseek(where,-1,SEEK_CUR); */
+  /*     PhyML_Fprintf(where,","); */
+  /*   } */
+
+  PhyML_Fprintf(where,"\n");
+  o = JSON_Tree_To_Object(tree);
+  JSON_Write_Object(o,where);
+  JSON_Free_Object(o);
+  /* PhyML_Fprintf(where,"]"); */
+  fflush(where);
+
+
+  // Print out latest tree + info
+  /* json_o *o; */
+
+  /* rewind(where); */
+  /* /\* PhyML_Fprintf(where,"["); *\/ */
+  /* o = JSON_Tree_To_Object(tree); */
+  /* JSON_Write_Object(o,where); */
+  /* JSON_Free_Object(o); */
+  /* /\* PhyML_Fprintf(where,"]"); *\/ */
+  /* fflush(where); */
+
+
+}
+
 /*////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////*/
 /*////////////////////////////////////////////////////////////
diff --git a/src/io.h b/src/io.h
index 0422aa8..8d066e7 100644
--- a/src/io.h
+++ b/src/io.h
@@ -94,4 +94,11 @@ void Dump_Arr_I(int* arr, int num);
 void Print_Tree_Structure(t_tree* tree);
 void Print_Node_Brief(t_node *a, t_node *d, t_tree *tree, FILE *fp);
 void Generic_Exit(const char *file, int line, const char *function);
+void JSON_Write_Object(json_o *obj, FILE *where);
+void JSON_Write_Array(json_a *array, FILE *where);
+void JSON_Write_All(json_a *array, FILE *where);
+void JSON_Tree_Io(t_tree *tree, FILE *where);
+json_o *JSON_Tree_To_Object(t_tree *tree);
+scalar_dbl *Read_Io_Weights(option *io);
+
 #endif
diff --git a/src/lk.c b/src/lk.c
index 96c2a9d..4ccefca 100644
--- a/src/lk.c
+++ b/src/lk.c
@@ -442,10 +442,8 @@ phydbl Lk(t_edge *b, t_tree *tree)
       return tree->c_lnL;
     }
   
-  if(!b) Set_Model_Parameters(tree->mod);
-  
-  Set_Br_Len_Var(tree);
-  
+  if(b == NULL) Set_Model_Parameters(tree->mod);
+    
   if(tree->mod->s_opt->skip_tree_traversal == NO)
     {
       if(!b)//Update the PMat for all edges
@@ -601,8 +599,7 @@ phydbl Lk_Core(int state, int ambiguity_check, t_edge *b, t_tree *tree)
   site_lk_cat     = .0;
   site            = tree->curr_site;
   ns              = tree->mod->ns;
-  
-  
+    
   /* Skip this if no tree traveral was required, i.e. likelihood in each class of the mixture is already up to date */
   if(tree->mod->s_opt->skip_tree_traversal == NO)
     {
@@ -677,10 +674,11 @@ phydbl Lk_Core(int state, int ambiguity_check, t_edge *b, t_tree *tree)
       Pull_Scaling_Factors(site,b,tree);
     }
 
+  
   fact_sum_scale = tree->fact_sum_scale[site];
+  
 
-
-  //Likelihood of the site; is the sum of the individual rate specific likelihoods
+  //Likelihood of the site is the sum of the individual rate specific likelihoods
   site_lk = .0;
   For(catg,tree->mod->ras->n_catg)
     {
@@ -689,6 +687,7 @@ phydbl Lk_Core(int state, int ambiguity_check, t_edge *b, t_tree *tree)
         tree->mod->ras->gamma_r_proba->v[catg]; //density
     }
   
+
   if(tree->mod->ras->invar == YES)
     {
       num_prec_issue = NO;
@@ -701,7 +700,7 @@ phydbl Lk_Core(int state, int ambiguity_check, t_edge *b, t_tree *tree)
       else
         {
           site_lk = site_lk * (1. - tree->mod->ras->pinvar->v) + inv_site_lk * tree->mod->ras->pinvar->v;
-        }          
+        }
     }
   
   log_site_lk = LOG(site_lk) - (phydbl)LOG2 * fact_sum_scale; // log_site_lk =  log(site_lk_scaled / 2^(left_subtree+right_subtree))      
@@ -973,12 +972,9 @@ phydbl Invariant_Lk(int fact_sum_scale, int site, int *num_prec_issue, t_tree *t
 
 }
 
-
-
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 /* Update partial likelihood on edge b on the side of b where
    node d lies.
 */
@@ -992,12 +988,15 @@ void Update_P_Lk(t_tree *tree, t_edge *b, t_node *d)
       return;
     }
   
+  assert(tree->is_mixt_tree == NO);
+
   if((tree->io->do_alias_subpatt == YES) &&
      (tree->update_alias_subpatt == YES))
     Alias_One_Subpatt((d==b->left)?(b->rght):(b->left),d,tree);
 
   if(d->tax) return;
 
+
 #ifdef BEAGLE
   update_beagle_partials(tree, b, d);
 #else
@@ -1058,6 +1057,14 @@ void Update_P_Lk_Generic(t_tree *tree, t_edge *b, t_node *d)
   phydbl smallest_p_lk;
   int *p_lk_loc;
 
+
+  if(tree->n_root && tree->ignore_root == YES &&
+     (d == tree->n_root->v[1] || d == tree->n_root->v[2]) &&
+     (b == tree->n_root->b[1] || b == tree->n_root->b[2]))
+    {
+      assert(FALSE);
+    }
+
   p_lk_lim_inf = (phydbl)P_LK_LIM_INF;
 
   NsNg = tree->mod->ras->n_catg * tree->mod->ns;
@@ -1305,6 +1312,13 @@ void Update_P_Lk_Nucl(t_tree *tree, t_edge *b, t_node *d)
   int *p_lk_loc;//Suppose site j, of a certain subtree, has "A" on one tip, and "C" on the other. If you come across this pattern again at site i<j, then you can simply copy the partial likelihoods
 
 
+  if(tree->n_root && tree->ignore_root == YES &&
+     (d == tree->n_root->v[1] || d == tree->n_root->v[2]) &&
+     (b == tree->n_root->b[1] || b == tree->n_root->b[2]))
+    {
+      assert(FALSE);
+    }
+
   p_lk_lim_inf = (phydbl)P_LK_LIM_INF;
 
   dim1 = tree->mod->ras->n_catg * tree->mod->ns;//Dimension of a matrix L that holds rate-specific character likelihoods. IOW, L[ij] is the likelihood of character j in rate class i
@@ -1419,16 +1433,16 @@ void Update_P_Lk_Nucl(t_tree *tree, t_edge *b, t_node *d)
                               /* For the (non-ambiguous) state at node n_v1 */
                               p1_lk1 = Pij1[catg*dim3+i*dim2+state_v1];
 
-                              assert(!isnan(p1_lk1));
+                              /* assert(!isnan(p1_lk1)); */
 
-                              /* if(isnan(p1_lk1)) */
-                              /*   { */
-                              /*     PhyML_Printf("\n== Tree %d",tree->tree_num); */
-                              /*     PhyML_Printf("\n== catg=%d dim3=%d dim2=%d i=%d state_v1=%d",catg,dim3,dim2,i,state_v1); */
-                              /*     PhyML_Printf("\n== Pij1[0] = %G l = %G",Pij1[0],b->l->v); */
-                              /*     Print_Model(tree->mod); */
-                              /*     Generic_Exit(__FILE__,__LINE__,__FUNCTION__); */
-                              /*   } */
+                              if(isnan(p1_lk1))
+                                {
+                                  PhyML_Printf("\n== Tree %d",tree->tree_num);
+                                  PhyML_Printf("\n== catg=%d dim3=%d dim2=%d i=%d state_v1=%d",catg,dim3,dim2,i,state_v1);
+                                  PhyML_Printf("\n== Pij1[0] = %G l = %G",Pij1[0],b->l->v);
+                                  Print_Model(tree->mod);
+                                  Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
+                                }
                             }
                           else
                             {
@@ -1641,6 +1655,18 @@ void Update_P_Lk_AA(t_tree *tree, t_edge *b, t_node *d)
   phydbl p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19;
   int *p_lk_loc;
 
+  assert(tree);
+  assert(b);
+  assert(d);
+
+  if(tree->n_root && tree->ignore_root == YES &&
+     (b == tree->n_root->b[1] || b == tree->n_root->b[2]))
+    {
+      PhyML_Printf("\n== Invalid call to Update_P_Lk_AA function");
+      PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__);
+      Exit("");
+    }
+
   p_lk_lim_inf = (phydbl)P_LK_LIM_INF;
 
   dim1 = tree->mod->ras->n_catg * tree->mod->ns;
@@ -1673,7 +1699,6 @@ void Update_P_Lk_AA(t_tree *tree, t_edge *b, t_node *d)
                &Pij2,&p_lk_v2,&sum_scale_v2,
                d,b,tree);
 
-
   /* For every site in the alignment */
   For(site,n_patterns)
     {
@@ -1681,31 +1706,31 @@ void Update_P_Lk_AA(t_tree *tree, t_edge *b, t_node *d)
       ambiguity_check_v1 = ambiguity_check_v2 = NO;
 
       if(!tree->mod->s_opt->greedy)
-    {
-      /* n_v1 and n_v2 are tip nodes */
-      if(n_v1 && n_v1->tax)
         {
-          /* Is the state at this tip ambiguous? */
-          ambiguity_check_v1 = n_v1->c_seq->is_ambigu[site];
-          /* if(ambiguity_check_v1 == NO) state_v1 = Get_State_From_P_Pars(n_v1->b[0]->p_lk_tip_r,site*dim2,tree); */
+          /* n_v1 and n_v2 are tip nodes */
+          if(n_v1 && n_v1->tax)
+            {
+              /* Is the state at this tip ambiguous? */
+              ambiguity_check_v1 = n_v1->c_seq->is_ambigu[site];
+              /* if(ambiguity_check_v1 == NO) state_v1 = Get_State_From_P_Pars(n_v1->b[0]->p_lk_tip_r,site*dim2,tree); */
               if(ambiguity_check_v1 == NO) state_v1 = n_v1->c_seq->d_state[site];
-        }
-
-      if(n_v2 && n_v2->tax)
-        {
-          /* Is the state at this tip ambiguous? */
-          ambiguity_check_v2 = n_v2->c_seq->is_ambigu[site];
-          /* if(ambiguity_check_v2 == NO) state_v2 = Get_State_From_P_Pars(n_v2->b[0]->p_lk_tip_r,site*dim2,tree); */
+            }
+          
+          if(n_v2 && n_v2->tax)
+            {
+              /* Is the state at this tip ambiguous? */
+              ambiguity_check_v2 = n_v2->c_seq->is_ambigu[site];
+              /* if(ambiguity_check_v2 == NO) state_v2 = Get_State_From_P_Pars(n_v2->b[0]->p_lk_tip_r,site*dim2,tree); */
               if(ambiguity_check_v2 == NO) state_v2 = n_v2->c_seq->d_state[site];
+            }
         }
-    }
-
+      
       if(tree->mod->use_m4mod)
         {
           ambiguity_check_v1 = YES;
           ambiguity_check_v2 = YES;
         }
-
+      
       if(p_lk_loc[site] < site)
         {
           Copy_P_Lk(p_lk,p_lk_loc[site],site,tree);
@@ -1790,131 +1815,132 @@ void Update_P_Lk_AA(t_tree *tree, t_edge *b, t_node *d)
                     {
                       p1_lk1 = 1.0;
                     }
-
-          p2_lk2 = .0;
-
-          /* We do exactly the same as for node n_v1 but for node n_v2 this time.*/
+                  
+                  p2_lk2 = .0;
+                  
+                  /* We do exactly the same as for node n_v1 but for node n_v2 this time.*/
                   if(n_v2)
                     {
-          /* n_v2 is a tip */
-          if((n_v2->tax) && (!tree->mod->s_opt->greedy))
-            {
-              if(ambiguity_check_v2 == NO)
-            {
-              /* For the (non-ambiguous) state at node n_v2 */
-              p2_lk2 = Pij2[catg*dim3+i*dim2+state_v2];
-            }
-              else
-            {
-              /* For all the states at node n_v2 */
-              p0  = Pij2[catg*dim3+i*dim2+ 0] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+ 0];
-              p1  = Pij2[catg*dim3+i*dim2+ 1] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+ 1];
-              p2  = Pij2[catg*dim3+i*dim2+ 2] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+ 2];
-              p3  = Pij2[catg*dim3+i*dim2+ 3] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+ 3];
-              p4  = Pij2[catg*dim3+i*dim2+ 4] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+ 4];
-              p5  = Pij2[catg*dim3+i*dim2+ 5] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+ 5];
-              p6  = Pij2[catg*dim3+i*dim2+ 6] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+ 6];
-              p7  = Pij2[catg*dim3+i*dim2+ 7] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+ 7];
-              p8  = Pij2[catg*dim3+i*dim2+ 8] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+ 8];
-              p9  = Pij2[catg*dim3+i*dim2+ 9] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+ 9];
-              p10 = Pij2[catg*dim3+i*dim2+10] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+10];
-              p11 = Pij2[catg*dim3+i*dim2+11] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+11];
-              p12 = Pij2[catg*dim3+i*dim2+12] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+12];
-              p13 = Pij2[catg*dim3+i*dim2+13] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+13];
-              p14 = Pij2[catg*dim3+i*dim2+14] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+14];
-              p15 = Pij2[catg*dim3+i*dim2+15] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+15];
-              p16 = Pij2[catg*dim3+i*dim2+16] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+16];
-              p17 = Pij2[catg*dim3+i*dim2+17] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+17];
-              p18 = Pij2[catg*dim3+i*dim2+18] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+18];
-              p19 = Pij2[catg*dim3+i*dim2+19] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+19];
-              p2_lk2 = p0+p1+p2+p3+p4+p5+p6+p7+p8+p9+p10+p11+p12+p13+p14+p15+p16+p17+p18+p19;
-
-            }
-            }
-          /* n_v2 is an internal node */
-          else
-            {
-              /* For all the states at node n_v2 */
-              p0  = Pij2[catg*dim3+i*dim2+ 0] * (phydbl)p_lk_v2[site*dim1+catg*dim2+ 0];
-              p1  = Pij2[catg*dim3+i*dim2+ 1] * (phydbl)p_lk_v2[site*dim1+catg*dim2+ 1];
-              p2  = Pij2[catg*dim3+i*dim2+ 2] * (phydbl)p_lk_v2[site*dim1+catg*dim2+ 2];
-              p3  = Pij2[catg*dim3+i*dim2+ 3] * (phydbl)p_lk_v2[site*dim1+catg*dim2+ 3];
-              p4  = Pij2[catg*dim3+i*dim2+ 4] * (phydbl)p_lk_v2[site*dim1+catg*dim2+ 4];
-              p5  = Pij2[catg*dim3+i*dim2+ 5] * (phydbl)p_lk_v2[site*dim1+catg*dim2+ 5];
-              p6  = Pij2[catg*dim3+i*dim2+ 6] * (phydbl)p_lk_v2[site*dim1+catg*dim2+ 6];
-              p7  = Pij2[catg*dim3+i*dim2+ 7] * (phydbl)p_lk_v2[site*dim1+catg*dim2+ 7];
-              p8  = Pij2[catg*dim3+i*dim2+ 8] * (phydbl)p_lk_v2[site*dim1+catg*dim2+ 8];
-              p9  = Pij2[catg*dim3+i*dim2+ 9] * (phydbl)p_lk_v2[site*dim1+catg*dim2+ 9];
-              p10 = Pij2[catg*dim3+i*dim2+10] * (phydbl)p_lk_v2[site*dim1+catg*dim2+10];
-              p11 = Pij2[catg*dim3+i*dim2+11] * (phydbl)p_lk_v2[site*dim1+catg*dim2+11];
-              p12 = Pij2[catg*dim3+i*dim2+12] * (phydbl)p_lk_v2[site*dim1+catg*dim2+12];
-              p13 = Pij2[catg*dim3+i*dim2+13] * (phydbl)p_lk_v2[site*dim1+catg*dim2+13];
-              p14 = Pij2[catg*dim3+i*dim2+14] * (phydbl)p_lk_v2[site*dim1+catg*dim2+14];
-              p15 = Pij2[catg*dim3+i*dim2+15] * (phydbl)p_lk_v2[site*dim1+catg*dim2+15];
-              p16 = Pij2[catg*dim3+i*dim2+16] * (phydbl)p_lk_v2[site*dim1+catg*dim2+16];
-              p17 = Pij2[catg*dim3+i*dim2+17] * (phydbl)p_lk_v2[site*dim1+catg*dim2+17];
-              p18 = Pij2[catg*dim3+i*dim2+18] * (phydbl)p_lk_v2[site*dim1+catg*dim2+18];
-              p19 = Pij2[catg*dim3+i*dim2+19] * (phydbl)p_lk_v2[site*dim1+catg*dim2+19];
-              p2_lk2 = p0+p1+p2+p3+p4+p5+p6+p7+p8+p9+p10+p11+p12+p13+p14+p15+p16+p17+p18+p19;
+                      /* n_v2 is a tip */
+                      if((n_v2->tax) && (!tree->mod->s_opt->greedy))
+                        {
+                          if(ambiguity_check_v2 == NO)
+                            {
+                              /* For the (non-ambiguous) state at node n_v2 */
+                              p2_lk2 = Pij2[catg*dim3+i*dim2+state_v2];
+                            }
+                          else
+                            {
+                              /* For all the states at node n_v2 */
+                              p0  = Pij2[catg*dim3+i*dim2+ 0] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+ 0];
+                              p1  = Pij2[catg*dim3+i*dim2+ 1] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+ 1];
+                              p2  = Pij2[catg*dim3+i*dim2+ 2] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+ 2];
+                              p3  = Pij2[catg*dim3+i*dim2+ 3] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+ 3];
+                              p4  = Pij2[catg*dim3+i*dim2+ 4] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+ 4];
+                              p5  = Pij2[catg*dim3+i*dim2+ 5] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+ 5];
+                              p6  = Pij2[catg*dim3+i*dim2+ 6] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+ 6];
+                              p7  = Pij2[catg*dim3+i*dim2+ 7] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+ 7];
+                              p8  = Pij2[catg*dim3+i*dim2+ 8] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+ 8];
+                              p9  = Pij2[catg*dim3+i*dim2+ 9] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+ 9];
+                              p10 = Pij2[catg*dim3+i*dim2+10] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+10];
+                              p11 = Pij2[catg*dim3+i*dim2+11] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+11];
+                              p12 = Pij2[catg*dim3+i*dim2+12] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+12];
+                              p13 = Pij2[catg*dim3+i*dim2+13] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+13];
+                              p14 = Pij2[catg*dim3+i*dim2+14] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+14];
+                              p15 = Pij2[catg*dim3+i*dim2+15] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+15];
+                              p16 = Pij2[catg*dim3+i*dim2+16] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+16];
+                              p17 = Pij2[catg*dim3+i*dim2+17] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+17];
+                              p18 = Pij2[catg*dim3+i*dim2+18] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+18];
+                              p19 = Pij2[catg*dim3+i*dim2+19] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+19];
+                              p2_lk2 = p0+p1+p2+p3+p4+p5+p6+p7+p8+p9+p10+p11+p12+p13+p14+p15+p16+p17+p18+p19;
+                              
+                            }
+                        }
+                      /* n_v2 is an internal node */
+                      else
+                        {
+                          /* For all the states at node n_v2 */
+                          p0  = Pij2[catg*dim3+i*dim2+ 0] * (phydbl)p_lk_v2[site*dim1+catg*dim2+ 0];
+                          p1  = Pij2[catg*dim3+i*dim2+ 1] * (phydbl)p_lk_v2[site*dim1+catg*dim2+ 1];
+                          p2  = Pij2[catg*dim3+i*dim2+ 2] * (phydbl)p_lk_v2[site*dim1+catg*dim2+ 2];
+                          p3  = Pij2[catg*dim3+i*dim2+ 3] * (phydbl)p_lk_v2[site*dim1+catg*dim2+ 3];
+                          p4  = Pij2[catg*dim3+i*dim2+ 4] * (phydbl)p_lk_v2[site*dim1+catg*dim2+ 4];
+                          p5  = Pij2[catg*dim3+i*dim2+ 5] * (phydbl)p_lk_v2[site*dim1+catg*dim2+ 5];
+                          p6  = Pij2[catg*dim3+i*dim2+ 6] * (phydbl)p_lk_v2[site*dim1+catg*dim2+ 6];
+                          p7  = Pij2[catg*dim3+i*dim2+ 7] * (phydbl)p_lk_v2[site*dim1+catg*dim2+ 7];
+                          p8  = Pij2[catg*dim3+i*dim2+ 8] * (phydbl)p_lk_v2[site*dim1+catg*dim2+ 8];
+                          p9  = Pij2[catg*dim3+i*dim2+ 9] * (phydbl)p_lk_v2[site*dim1+catg*dim2+ 9];
+                          p10 = Pij2[catg*dim3+i*dim2+10] * (phydbl)p_lk_v2[site*dim1+catg*dim2+10];
+                          p11 = Pij2[catg*dim3+i*dim2+11] * (phydbl)p_lk_v2[site*dim1+catg*dim2+11];
+                          p12 = Pij2[catg*dim3+i*dim2+12] * (phydbl)p_lk_v2[site*dim1+catg*dim2+12];
+                          p13 = Pij2[catg*dim3+i*dim2+13] * (phydbl)p_lk_v2[site*dim1+catg*dim2+13];
+                          p14 = Pij2[catg*dim3+i*dim2+14] * (phydbl)p_lk_v2[site*dim1+catg*dim2+14];
+                          p15 = Pij2[catg*dim3+i*dim2+15] * (phydbl)p_lk_v2[site*dim1+catg*dim2+15];
+                          p16 = Pij2[catg*dim3+i*dim2+16] * (phydbl)p_lk_v2[site*dim1+catg*dim2+16];
+                          p17 = Pij2[catg*dim3+i*dim2+17] * (phydbl)p_lk_v2[site*dim1+catg*dim2+17];
+                          p18 = Pij2[catg*dim3+i*dim2+18] * (phydbl)p_lk_v2[site*dim1+catg*dim2+18];
+                          p19 = Pij2[catg*dim3+i*dim2+19] * (phydbl)p_lk_v2[site*dim1+catg*dim2+19];
+                          p2_lk2 = p0+p1+p2+p3+p4+p5+p6+p7+p8+p9+p10+p11+p12+p13+p14+p15+p16+p17+p18+p19;
                         }
                     }
                   else
                     {
                       p2_lk2 = 1.0;
-            }
-
-          p_lk[site*dim1+catg*dim2+i] = p1_lk1 * p2_lk2;
-
-          if(p_lk[site*dim1+catg*dim2+i] < smallest_p_lk) smallest_p_lk = p_lk[site*dim1+catg*dim2+i] ;
-        }
-
-          /* Current scaling values at that site */
-          sum_scale_v1_val = (sum_scale_v1)?(sum_scale_v1[catg*n_patterns+site]):(0);
-          sum_scale_v2_val = (sum_scale_v2)?(sum_scale_v2[catg*n_patterns+site]):(0);
-
-          sum_scale[catg*n_patterns+site] = sum_scale_v1_val + sum_scale_v2_val;
-
-          /* Scaling */
-          if(smallest_p_lk < p_lk_lim_inf)
-            {
-              curr_scaler_pow = (int)(LOG(p_lk_lim_inf)-LOG(smallest_p_lk))/LOG2;
-              curr_scaler     = (phydbl)((unsigned long long)(1) << curr_scaler_pow);
-
-              /* 	      if(fabs(curr_scaler_pow) > 63 || fabs(curr_scaler_pow) > 63) */
-              /* 		{ */
-              /* 		  PhyML_Printf("\n. p_lk_lim_inf = %G smallest_p_lk = %G",p_lk_lim_inf,smallest_p_lk); */
-              /* 		  PhyML_Printf("\n. curr_scaler_pow = %d",curr_scaler_pow); */
-              /* 		  PhyML_Printf("\n. Err in file %s at line %d.",__FILE__,__LINE__); */
-              /* 		  Warn_And_Exit("\n"); */
-              /* 		} */
-
-              sum_scale[catg*n_patterns+site] += curr_scaler_pow;
-
-              do
-                {
-                  piecewise_scaler_pow = MIN(curr_scaler_pow,63);
-                  curr_scaler = (phydbl)((unsigned long long)(1) << piecewise_scaler_pow);
-                  For(i,tree->mod->ns)
+                    }
+                  
+                  p_lk[site*dim1+catg*dim2+i] = p1_lk1 * p2_lk2;
+                  
+                  if(p_lk[site*dim1+catg*dim2+i] < smallest_p_lk) smallest_p_lk = p_lk[site*dim1+catg*dim2+i] ;
+                }
+              
+              /* Current scaling values at that site */
+              sum_scale_v1_val = (sum_scale_v1)?(sum_scale_v1[catg*n_patterns+site]):(0);
+              sum_scale_v2_val = (sum_scale_v2)?(sum_scale_v2[catg*n_patterns+site]):(0);
+              
+              sum_scale[catg*n_patterns+site] = sum_scale_v1_val + sum_scale_v2_val;
+              
+              /* Scaling */
+              if(smallest_p_lk < p_lk_lim_inf)
                 {
-                  p_lk[site*dim1+catg*dim2+i] *= curr_scaler;
-
-                  if(p_lk[site*dim1+catg*dim2+i] > BIG)
+                  curr_scaler_pow = (int)(LOG(p_lk_lim_inf)-LOG(smallest_p_lk))/LOG2;
+                  curr_scaler     = (phydbl)((unsigned long long)(1) << curr_scaler_pow);
+                  
+                  /* 	      if(fabs(curr_scaler_pow) > 63 || fabs(curr_scaler_pow) > 63) */
+                  /* 		{ */
+                  /* 		  PhyML_Printf("\n. p_lk_lim_inf = %G smallest_p_lk = %G",p_lk_lim_inf,smallest_p_lk); */
+                  /* 		  PhyML_Printf("\n. curr_scaler_pow = %d",curr_scaler_pow); */
+                  /* 		  PhyML_Printf("\n. Err in file %s at line %d.",__FILE__,__LINE__); */
+                  /* 		  Warn_And_Exit("\n"); */
+                  /* 		} */
+                  
+                  sum_scale[catg*n_patterns+site] += curr_scaler_pow;
+                  
+                  do
                     {
-                      PhyML_Printf("\n. p_lk_lim_inf = %G smallest_p_lk = %G",p_lk_lim_inf,smallest_p_lk);
-                      PhyML_Printf("\n. curr_scaler_pow = %d",curr_scaler_pow);
-                      PhyML_Printf("\n. Err in file %s at line %d.",__FILE__,__LINE__);
-                      Warn_And_Exit("\n");
+                      piecewise_scaler_pow = MIN(curr_scaler_pow,63);
+                      curr_scaler = (phydbl)((unsigned long long)(1) << piecewise_scaler_pow);
+                      For(i,tree->mod->ns)
+                        {
+                          p_lk[site*dim1+catg*dim2+i] *= curr_scaler;
+                          
+                          if(p_lk[site*dim1+catg*dim2+i] > BIG)
+                            {
+                              PhyML_Printf("\n. p_lk_lim_inf = %G smallest_p_lk = %G",p_lk_lim_inf,smallest_p_lk);
+                              PhyML_Printf("\n. curr_scaler_pow = %d",curr_scaler_pow);
+                              PhyML_Printf("\n. Err in file %s at line %d.",__FILE__,__LINE__);
+                              Warn_And_Exit("\n");
+                            }
+                        }
+                      curr_scaler_pow -= piecewise_scaler_pow;
                     }
+                  while(curr_scaler_pow != 0);
                 }
-                  curr_scaler_pow -= piecewise_scaler_pow;
-                }
-              while(curr_scaler_pow != 0);
             }
         }
     }
-    }
 }
 #endif
+
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
@@ -1936,8 +1962,8 @@ matrix *ML_Dist(calign *data, t_mod *mod)
   phydbl d_max,sum;
   matrix *mat;
   calign *twodata,*tmpdata;
-  int state0, state1,len;
-  phydbl *F;
+  int state0, state1;
+  phydbl *F,len;
   eigen *eigen_struct;
 
   tmpdata         = (calign *)mCalloc(1,sizeof(calign));
@@ -1975,7 +2001,6 @@ matrix *ML_Dist(calign *data, t_mod *mod)
 
       for(k=j+1;k<data->n_otu;k++)
         {
-
           tmpdata->c_seq[1]       = data->c_seq[k];
           tmpdata->c_seq[1]->name = data->c_seq[k]->name;
           
@@ -1992,7 +2017,7 @@ matrix *ML_Dist(calign *data, t_mod *mod)
           d_max = init;
           
           For(i,mod->ns*mod->ns) F[i]=.0;
-          len = 0;
+          len = 0.0;
           For(l,twodata->c_seq[0]->len)
             {
               state0 = Assign_State(twodata->c_seq[0]->state+l*mod->io->state_len,mod->io->datatype,mod->io->state_len);
@@ -2001,21 +2026,24 @@ matrix *ML_Dist(calign *data, t_mod *mod)
               if((state0 > -1) && (state1 > -1))
                 {
                   F[mod->ns*state0+state1] += twodata->wght[l];
-                  len += (int)twodata->wght[l];
+                  len += twodata->wght[l];
                 }
             }
-          if(len > .0) {For(i,mod->ns*mod->ns) F[i] /= (phydbl)len;}
+          
+          if(len > .0) 
+            {
+              For(i,mod->ns*mod->ns) F[i] /= len;
+            }
           
           sum = 0.;
           For(i,mod->ns*mod->ns) sum += F[i];
           
-          
           /* if(sum < .001) d_max = -1.; */
           if(sum < .001) d_max = init;
           else if((sum > 1. - .001) && (sum < 1. + .001)) Opt_Dist_F(&(d_max),F,mod);
           else
             {
-              PhyML_Printf("\n== sum = %f\n",sum);
+              PhyML_Printf("\n\n== sum = %f",sum);
               PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__);
               Exit("");
             }
@@ -2028,7 +2056,7 @@ matrix *ML_Dist(calign *data, t_mod *mod)
            */
           mat->dist[j][k] = d_max;
           mat->dist[k][j] = mat->dist[j][k];
-          Free_Cseq(twodata);
+          Free_Calign(twodata);
         }
     }
   
@@ -2080,81 +2108,81 @@ phydbl Lk_Given_Two_Seq(calign *data, int numseq1, int numseq2, phydbl dist, t_m
       else if(len > mod->l_max) len = mod->l_max;
       PMat(len,mod,dim2*i,mod->Pij_rr->v);
     }
-
+  
   if(mod->io->datatype == NT)
     {
       For(i,data->c_seq[0]->len)
-    {
-      Init_Tips_At_One_Site_Nucleotides_Float(seq1->state[i],i*mod->ns,p_lk_l);
-      Init_Tips_At_One_Site_Nucleotides_Float(seq2->state[i],i*mod->ns,p_lk_r);
-    }
+        {
+          Init_Tips_At_One_Site_Nucleotides_Float(seq1->state[i],i*mod->ns,p_lk_l);
+          Init_Tips_At_One_Site_Nucleotides_Float(seq2->state[i],i*mod->ns,p_lk_r);
+        }
     }
   else if(mod->io->datatype == AA)
     {
       For(i,data->c_seq[0]->len)
-    {
-      Init_Tips_At_One_Site_AA_Float(seq1->state[i],i*mod->ns,p_lk_l);
-      Init_Tips_At_One_Site_AA_Float(seq2->state[i],i*mod->ns,p_lk_r);
-    }
+        {
+          Init_Tips_At_One_Site_AA_Float(seq1->state[i],i*mod->ns,p_lk_l);
+          Init_Tips_At_One_Site_AA_Float(seq2->state[i],i*mod->ns,p_lk_r);
+        }
     }
   else
     {
-      PhyML_Printf("\n. Not implemented yet...");
-      PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__);
+      PhyML_Printf("\n\n== Not implemented yet...");
+      PhyML_Printf("\n== Err in file %s at line %d\n\n",__FILE__,__LINE__);
       Warn_And_Exit("\n");
     }
-
-
+  
+  
   site_lk = .0;
   *loglk = 0;
-
+  
   For(i,data->c_seq[0]->len)
     {
-      if(data->wght[i])
-    {
-      site_lk = log_site_lk = .0;
-      if(!data->ambigu[i])
-        {
-          For(k,mod->ns) {if(p_lk_l[i*mod->ns+k] > .0001) break;}
-          For(l,mod->ns) {if(p_lk_r[i*mod->ns+l] > .0001) break;}
-          For(j,mod->ras->n_catg)
-        {
-          site_lk +=
-            mod->ras->gamma_r_proba->v[j] *
-            mod->e_frq->pi->v[k] *
-            p_lk_l[i*dim1+k] *
-            mod->Pij_rr->v[j*dim2+k*dim1+l] *
-            p_lk_r[i*dim1+l];
-        }
-        }
-      else
+      if(data->wght[i] > 0.0)
         {
-          For(j,mod->ras->n_catg)
-        {
-          For(k,mod->ns) /*sort sum terms ? No global effect*/
+          site_lk = log_site_lk = .0;
+          if(!data->ambigu[i])
             {
-              For(l,mod->ns)
+              For(k,mod->ns) {if(p_lk_l[i*mod->ns+k] > .0001) break;}
+              For(l,mod->ns) {if(p_lk_r[i*mod->ns+l] > .0001) break;}
+              For(j,mod->ras->n_catg)
+                {
+                  site_lk +=
+                    mod->ras->gamma_r_proba->v[j] *
+                    mod->e_frq->pi->v[k] *
+                    p_lk_l[i*dim1+k] *
+                    mod->Pij_rr->v[j*dim2+k*dim1+l] *
+                    p_lk_r[i*dim1+l];
+                }
+            }
+          else
             {
-              site_lk +=
-                mod->ras->gamma_r_proba->v[j] *
-                mod->e_frq->pi->v[k] *
-                p_lk_l[i*dim1+k] *
-                mod->Pij_rr->v[j*dim2+k*dim1+l] *
-                p_lk_r[i*dim1+l];
+              For(j,mod->ras->n_catg)
+                {
+                  For(k,mod->ns) /*sort sum terms ? No global effect*/
+                    {
+                      For(l,mod->ns)
+                        {
+                          site_lk +=
+                            mod->ras->gamma_r_proba->v[j] *
+                            mod->e_frq->pi->v[k] *
+                            p_lk_l[i*dim1+k] *
+                            mod->Pij_rr->v[j*dim2+k*dim1+l] *
+                            p_lk_r[i*dim1+l];
+                        }
+                    }
+                }
             }
+          
+          if(site_lk <= .0)
+            {
+              PhyML_Printf("\n\n== '%c' '%c'\n",seq1->state[i],seq2->state[i]);
+              Exit("\n== Err: site lk <= 0\n");
             }
-        }
-        }
-
-      if(site_lk <= .0)
-        {
-          PhyML_Printf("'%c' '%c'\n",seq1->state[i],seq2->state[i]);
-          Exit("\n. Err: site lk <= 0\n");
-        }
-
-      log_site_lk += (phydbl)LOG(site_lk);
-
-      *loglk += data->wght[i] * log_site_lk;/* sort sum terms ? No global effect*/
+          
+          log_site_lk += (phydbl)LOG(site_lk);
+          
+          *loglk += data->wght[i] * log_site_lk;/* sort sum terms ? No global effect*/
     }
     }
 
@@ -2177,14 +2205,8 @@ void Unconstraint_Lk(t_tree *tree)
   int i;
 
   tree->unconstraint_lk = .0;
-
-  For(i,tree->data->crunch_len)
-    {
-      tree->unconstraint_lk +=
-    tree->data->wght[i]*(phydbl)LOG(tree->data->wght[i]);
-    }
-  tree->unconstraint_lk -=
-    tree->data->init_len*(phydbl)LOG(tree->data->init_len);
+  For(i,tree->data->crunch_len) tree->unconstraint_lk += tree->data->wght[i]*(phydbl)LOG(tree->data->wght[i]);
+  tree->unconstraint_lk -= tree->data->init_len*(phydbl)LOG(tree->data->init_len);
 }
 
 //////////////////////////////////////////////////////////////
@@ -2339,18 +2361,23 @@ void Update_PMat_At_Given_Edge(t_edge *b_fcus, t_tree *tree)
   phydbl l_min, l_max;
   phydbl shape, scale, mean, var;
 
+  assert(b_fcus);
+  assert(tree);
+
   if(tree->is_mixt_tree)
     {
       MIXT_Update_PMat_At_Given_Edge(b_fcus,tree);
       return;
     }
 
+  if(tree->io->mod->gamma_mgf_bl == YES) Set_Br_Len_Var(b_fcus,tree);
+
   l_min = tree->mod->l_min;
   l_max = tree->mod->l_max;
 
   len = -1.0;
 
-  if(tree->mod->log_l == YES) {b_fcus->l->v = EXP(b_fcus->l->v);}
+  if(tree->mod->log_l == YES) b_fcus->l->v = EXP(b_fcus->l->v);
 
   For(i,tree->mod->ras->n_catg)
     {
@@ -2376,7 +2403,9 @@ void Update_PMat_At_Given_Edge(t_edge *b_fcus, t_tree *tree)
           
           mean = len;
           var  = MAX(0.0,b_fcus->l_var->v) * POW(tree->mod->ras->gamma_rr->v[i]*tree->mod->br_len_mult->v,2);
-          if(tree->mixt_tree)  var *= POW(tree->mixt_tree->mod->ras->gamma_rr->v[tree->mod->ras->parent_class_number],2);
+          if(tree->mixt_tree) var *= POW(tree->mixt_tree->mod->ras->gamma_rr->v[tree->mod->ras->parent_class_number],2);
+
+          /* var = 1.E-10; */
 
           if(var > tree->mod->l_var_max) var = tree->mod->l_var_max;
           if(var < tree->mod->l_var_min) var = tree->mod->l_var_min;
@@ -2398,7 +2427,6 @@ void Update_PMat_At_Given_Edge(t_edge *b_fcus, t_tree *tree)
             
             shape = mean*mean/var;
             scale = var/mean;
-            
             PMat_MGF_Gamma(b_fcus->Pij_rr+tree->mod->ns*tree->mod->ns*i,shape,scale,1.0,tree->mod);
           }
     }
@@ -2408,40 +2436,43 @@ void Update_PMat_At_Given_Edge(t_edge *b_fcus, t_tree *tree)
   //Only for some models we use Beagle to compute/update the P-matrices, for other models
   //we compute them in PhyML and explicitly set the P-matrices in BEAGLE
   if((tree->mod->io->datatype == AA || whichmodel==GTR || whichmodel==CUSTOM) && tree->mod->use_m4mod == NO)
-  {
+    {
       if(b_fcus->has_zero_br_len == YES)
         Warn_And_Exit(TODO_BEAGLE);
-
+      
       //
       update_beagle_eigen(tree->mod);
       update_beagle_ras(tree->mod);
-
+      
       //
       len = MAX(0.0, b_fcus->l->v) * tree->mod->br_len_mult->v;
-      int p_matrices[1]     = {b_fcus->Pij_rr_idx};
-      double branch_lens[1] = {len};
+      int p_matrices[1]     = b_fcus->Pij_rr_idx;
+      double branch_lens[1] = len;
       int ret = beagleUpdateTransitionMatrices(tree->b_inst,0,p_matrices,NULL,NULL,branch_lens,1);
-      if(ret<0){
+      if(ret<0)
+        {
           fprintf(stderr, "beagleUpdateTransitionMatrices() on instance %i failed:%i\n\n",tree->b_inst,ret);
           Exit("");
-      }
+        }
       //Retrieve a "local" copy of the P-matrix
       ret = beagleGetTransitionMatrix(tree->b_inst, b_fcus->Pij_rr_idx, b_fcus->Pij_rr);
-      if(ret<0){
+      if(ret<0)
+        {
           fprintf(stderr, "beagleGetTransitionMatrix() on instance %i failed:%i\n\n",tree->b_inst,ret);
           Exit("");
-      }
-  }
+        }
+    }
   else
-  {
+    {
       int ret = beagleSetTransitionMatrix(tree->b_inst, b_fcus->Pij_rr_idx, b_fcus->Pij_rr, -1);
-      if(ret<0){
+      if(ret<0)
+        {
           fprintf(stderr, "beagleSetTransitionMatrix() on instance %i failed:%i\n\n",tree->b_inst,ret);
           Exit("");
-      }
+        }
   }
 #endif
-    if(tree->mod->log_l == YES) {b_fcus->l->v = LOG(b_fcus->l->v);}
+    if(tree->mod->log_l == YES) b_fcus->l->v = LOG(b_fcus->l->v);
 
 //      Print_Model(tree->mod);
 //      Dump_Arr_D(tree->cur_site_lk, tree->n_pattern);
@@ -2493,33 +2524,33 @@ void Update_PMat_At_Given_Edge(t_edge *b_fcus, t_tree *tree)
 void Update_P_Lk_Along_A_Path(t_node **path, int path_length, t_tree *tree)
 {
   int i,j;
-
+  
   For(i,path_length-1)
     {
       For(j,3)
-    if(path[i]->v[j] == path[i+1])
-      {
-        if(path[i] == path[i]->b[j]->left)
-          {
-        Update_P_Lk(tree,path[i]->b[j],path[i]->b[j]->left);
-          }
-        else if(path[i] == path[i]->b[j]->rght)
+        if(path[i]->v[j] == path[i+1])
           {
-        Update_P_Lk(tree,path[i]->b[j],path[i]->b[j]->rght);
-          }
-        else
-          {
-        PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__);
-        Exit("");
+            if(path[i] == path[i]->b[j]->left)
+              {
+                Update_P_Lk(tree,path[i]->b[j],path[i]->b[j]->left);
+              }
+            else if(path[i] == path[i]->b[j]->rght)
+              {
+                Update_P_Lk(tree,path[i]->b[j],path[i]->b[j]->rght);
+              }
+            else
+              {
+                PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__);
+                Exit("");
+              }
+            break;
           }
-        break;
-      }
 #ifdef DEBUG
       if(j == 3)
-    {
-      PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__);
-      Exit("");
-    }
+        {
+          PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__);
+          Exit("");
+        }
 #endif
     }
 }
@@ -2534,6 +2565,11 @@ phydbl Lk_Dist(phydbl *F, phydbl dist, t_mod *mod)
   phydbl lnL,len;
   int dim1,dim2;
 
+  // Compute likelihood of the model made of the
+  // first class of the mixture.
+  if(mod->is_mixt_mod == YES) mod = mod->next;
+  assert(mod);
+
   if(mod->log_l == YES) dist = EXP(dist);
 
   For(k,mod->ras->n_catg)
@@ -2548,19 +2584,6 @@ phydbl Lk_Dist(phydbl *F, phydbl dist, t_mod *mod)
   dim2 = mod->ns;
   lnL = .0;
 
-/*   For(i,mod->ns) */
-/*     { */
-/*       For(j,mod->ns) */
-/* 	{ */
-/* 	  For(k,mod->ras->n_catg) */
-/* 	    { */
-/*  	      lnL += */
-/* 		F[dim1*k+dim2*i+j] * */
-/* 		LOG(mod->pi[i] * mod->Pij_rr[dim1*k+dim2*i+j]); */
-/* 	    } */
-/* 	} */
-/*     } */
-
   For(i,mod->ns-1)
     {
       for(j=i+1;j<mod->ns;j++)
@@ -2571,7 +2594,7 @@ phydbl Lk_Dist(phydbl *F, phydbl dist, t_mod *mod)
                 (F[dim1*k+dim2*i+j] + F[dim1*k+dim2*j+i])*
                 LOG(mod->e_frq->pi->v[i] * mod->Pij_rr->v[dim1*k+dim2*i+j]);
               /* printf("\n. f: %f Pij:%f F:%f", */
-              /*        mod->e_frq->pi->v[i],  */
+              /*        mod->e_frq->pi->v[i], */
               /*        mod->Pij_rr->v[dim1*k+dim2*i+j], */
               /*        F[dim1*k+dim2*j+i]); */
             }
@@ -2586,7 +2609,6 @@ phydbl Lk_Dist(phydbl *F, phydbl dist, t_mod *mod)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 phydbl Update_Lk_At_Given_Edge(t_edge *b_fcus, t_tree *tree)
 {
   Update_P_Lk(tree,b_fcus,b_fcus->left);
@@ -2865,7 +2887,6 @@ void Copy_Scale(int *scale, int site_from, int site_to, t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Init_P_Lk_Loc(t_tree *tree)
 {
   int i,j;
@@ -2886,10 +2907,9 @@ void Init_P_Lk_Loc(t_tree *tree)
       d = tree->a_nodes[i];
       patt_id_d = (d == d->b[0]->left)?(d->b[0]->patt_id_left):(d->b[0]->patt_id_rght);
       For(j,tree->n_pattern)
-    {
-      patt_id_d[j] = (int)tree->a_nodes[d->num]->c_seq->state[j];
-      /* patt_id_d[j] = (int)tree->data->c_seq[d->num]->state[j]; */
-    }
+        {
+          patt_id_d[j] = (int)tree->a_nodes[d->num]->c_seq->state[j];
+        }
     }
 }
 
@@ -2952,7 +2972,8 @@ phydbl Lk_Normal_Approx(t_tree *tree)
 
 phydbl Wrap_Part_Lk_At_Given_Edge(t_edge *b, t_tree *tree, supert_tree *stree)
 {
-  return PART_Lk_At_Given_Edge(b,stree);;
+  return -1.0;
+  /* return PART_Lk_At_Given_Edge(b,stree);; */
 }
 
 //////////////////////////////////////////////////////////////
@@ -2961,7 +2982,8 @@ phydbl Wrap_Part_Lk_At_Given_Edge(t_edge *b, t_tree *tree, supert_tree *stree)
 
 phydbl Wrap_Part_Lk(t_edge *b, t_tree *tree, supert_tree *stree)
 {
-  return PART_Lk(stree);
+  return -1.0;
+  /* return PART_Lk(stree); */
 }
 
 //////////////////////////////////////////////////////////////
@@ -3016,8 +3038,6 @@ phydbl Wrap_Lk_Times(t_edge *b, t_tree *tree, supert_tree *stree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
-
 phydbl Wrap_Lk_Linreg(t_edge *b, t_tree *tree, supert_tree *stree)
 {
   /* RATES_Lk_Linreg(tree); */
@@ -3501,6 +3521,7 @@ int Check_Lk_At_Given_Edge(int verbose, t_tree *tree)
       if(verbose == YES) PhyML_Printf("\n. Edge %3d %13G %f %13G",
                                       tree->a_edges[i]->num,tree->a_edges[i]->l->v,lk[i],
                                       tree->a_edges[i]->l_var->v);
+            
     }
 
   if(tree->n_root && tree->ignore_root == NO)
@@ -3582,224 +3603,189 @@ void ML_Ancestral_Sequences(t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-void ML_Ancestral_Sequences_One_Node(t_node *mixt_d, t_tree *mixt_tree)
+void ML_Ancestral_Sequences_One_Node(t_node *d, t_tree *tree)
 {
-  if(mixt_d->tax) return;
+  if(d->tax) return;
   else
     {
-      t_node *v0,*v1,*v2; // three neighbours of d
-      t_edge *b0,*b1,*b2;
-      int i,j;
-      int catg;
-      phydbl p0, p1, p2;
-      phydbl *p;
-      t_node *d,*curr_mixt_d;
-      t_tree *tree, *curr_mixt_tree;
-      int site,csite;
-      phydbl *p_lk0, *p_lk1, *p_lk2;
-      int *sum_scale0, *sum_scale1, *sum_scale2;
-      phydbl r_mat_weight_sum, e_frq_weight_sum, sum_probas;
-      phydbl *Pij0, *Pij1, *Pij2;
-      int NsNs, Ns, NsNg;
-      FILE *fp;
-
-      if(!mixt_d) return;
-
-      curr_mixt_tree = mixt_tree;
-      curr_mixt_d    = mixt_d;
-      fp             = mixt_tree->io->fp_out_ancestral;
-
-
-      do /* For each partition element */
+      if(tree->is_mixt_tree) 
         {
-          if(curr_mixt_tree->next)
-            {
-              r_mat_weight_sum = MIXT_Get_Sum_Chained_Scalar_Dbl(curr_mixt_tree->next->mod->r_mat_weight);
-              e_frq_weight_sum = MIXT_Get_Sum_Chained_Scalar_Dbl(curr_mixt_tree->next->mod->e_frq_weight);
-              sum_probas       = MIXT_Get_Sum_Of_Probas_Across_Mixtures(r_mat_weight_sum, e_frq_weight_sum, curr_mixt_tree);
-            }
-          else
-            {
-              r_mat_weight_sum = 1.;
-              e_frq_weight_sum = 1.;
-              sum_probas       = 1.;
-            }
-
-          Ns   = curr_mixt_tree->next ? curr_mixt_tree->next->mod->ns : curr_mixt_tree->mod->ns;
+          MIXT_ML_Ancestral_Sequences_One_Node(d,tree);
+          return;
+        }
+      else
+        {
+          t_node *v0,*v1,*v2; // three neighbours of d
+          t_edge *b0,*b1,*b2;
+          int i,j;
+          int catg;
+          phydbl p0, p1, p2;
+          phydbl *p;
+          int site,csite;
+          phydbl *p_lk0, *p_lk1, *p_lk2;
+          int *sum_scale0, *sum_scale1, *sum_scale2;
+          phydbl sum_probas;
+          phydbl *Pij0, *Pij1, *Pij2;
+          int NsNs, Ns, NsNg;
+          FILE *fp;
+          
+          if(!d) return;
+          
+          fp = tree->io->fp_out_ancestral;
+          assert(fp != NULL);
+                        
+          Ns   = tree->mod->ns;
           NsNs = Ns*Ns;
-          NsNg = Ns*curr_mixt_tree->mod->ras->n_catg;
-
+          NsNg = Ns*tree->mod->ras->n_catg;
+          
           p = (phydbl *)mCalloc(Ns,sizeof(phydbl));
-
-          /* For(site,curr_mixt_tree->n_pattern) // For each site in the current partition element */
-          For(site,curr_mixt_tree->data->init_len) // For each site in the current partition element
+              
+          For(site,tree->data->init_len) // For each site in the current partition element
             {
-              csite = curr_mixt_tree->data->sitepatt[site];
-
-              d    = curr_mixt_d->next ? curr_mixt_d->next : curr_mixt_d;
-              tree = curr_mixt_tree->next ? curr_mixt_tree->next : curr_mixt_tree;
-
-              For(i,tree->mod->ns) p[i] = .0;
-
-              do // For each class of the mixture model that applies to the current partition element
+              csite = tree->data->sitepatt[site];
+                                    
+              For(i,Ns) p[i] = .0;
+                  
+              v0 = d->v[0];
+              v1 = d->v[1];
+              v2 = d->v[2];
+              
+              b0 = d->b[0];
+              b1 = d->b[1];
+              b2 = d->b[2];
+              
+              Pij0 = b0->Pij_rr;
+              Pij1 = b1->Pij_rr;
+              Pij2 = b2->Pij_rr;
+              
+              if(v0 == b0->left)
+                {
+                  p_lk0 = b0->p_lk_left;
+                  sum_scale0 = b0->sum_scale_left;
+                }
+              else
+                {
+                  p_lk0 = b0->p_lk_rght;
+                  sum_scale0 = b0->sum_scale_rght;
+                }
+              
+              if(v1 == b1->left)
+                {
+                  p_lk1 = b1->p_lk_left;
+                  sum_scale1 = b1->sum_scale_left;
+                }
+              else
+                {
+                  p_lk1 = b1->p_lk_rght;
+                  sum_scale1 = b1->sum_scale_rght;
+                }
+              
+              if(v2 == b2->left)
+                {
+                  p_lk2 = b2->p_lk_left;
+                  sum_scale2 = b2->sum_scale_left;
+                }
+              else
+                {
+                  p_lk2 = b2->p_lk_rght;
+                  sum_scale2 = b2->sum_scale_rght;
+                }
+              
+              
+              For(catg,tree->mod->ras->n_catg)
                 {
-                  if(tree->is_mixt_tree == YES)
-                    {
-                      tree = tree->next;
-                      d    = d->next;
-                    }
-
-                  v0 = d->v[0];
-                  v1 = d->v[1];
-                  v2 = d->v[2];
-
-                  b0 = d->b[0];
-                  b1 = d->b[1];
-                  b2 = d->b[2];
-
-                  Pij0 = b0->Pij_rr;
-                  Pij1 = b1->Pij_rr;
-                  Pij2 = b2->Pij_rr;
-
-                  if(v0 == b0->left)
-                    {
-                      p_lk0 = b0->p_lk_left;
-                      sum_scale0 = b0->sum_scale_left;
-                    }
-                  else
-                    {
-                      p_lk0 = b0->p_lk_rght;
-                      sum_scale0 = b0->sum_scale_rght;
-                    }
-
-                  if(v1 == b1->left)
-                    {
-                      p_lk1 = b1->p_lk_left;
-                      sum_scale1 = b1->sum_scale_left;
-                    }
-                  else
-                    {
-                      p_lk1 = b1->p_lk_rght;
-                      sum_scale1 = b1->sum_scale_rght;
-                    }
-
-                  if(v2 == b2->left)
-                    {
-                      p_lk2 = b2->p_lk_left;
-                      sum_scale2 = b2->sum_scale_left;
-                    }
-                  else
-                    {
-                      p_lk2 = b2->p_lk_rght;
-                      sum_scale2 = b2->sum_scale_rght;
-                    }
-
-
-                  For(catg,tree->mod->ras->n_catg)
-                    {
-                      For(i,Ns)
-                        {
-                          p0 = .0;
-                          if(v0->tax)
-                            For(j,tree->mod->ns)
-                              {
-                                p0 += v0->b[0]->p_lk_tip_r[csite*Ns+j] * Pij0[catg*NsNs+i*Ns+j];
-
-                                /* printf("\n. p0 %d %f", */
-                                /*        v0->b[0]->p_lk_tip_r[site*Ns+j], */
-                                /*        Pij0[catg*NsNs+i*Ns+j]); */
-                              }
-                          else
-                            For(j,tree->mod->ns)
-                              {
-                                p0 += p_lk0[csite*NsNg+catg*Ns+j] * Pij0[catg*NsNs+i*Ns+j] / (phydbl)POW(2,sum_scale0[catg*curr_mixt_tree->n_pattern+csite]);
-
-                                /* p0 += p_lk0[site*NsNg+catg*Ns+j] * Pij0[catg*NsNs+i*Ns+j]; */
-
-                                /* printf("\n. p0 %f %f", */
-                                /*        p_lk0[site*NsNg+catg*Ns+j], */
-                                /*        Pij0[catg*NsNs+i*Ns+j]); */
-                              }
-                          p1 = .0;
-                          if(v1->tax)
-                            For(j,tree->mod->ns)
-                              {
-                                p1 += v1->b[0]->p_lk_tip_r[csite*Ns+j] * Pij1[catg*NsNs+i*Ns+j];
-
-                                /* printf("\n. p1 %d %f", */
-                                /*        v1->b[0]->p_lk_tip_r[site*Ns+j], */
-                                /*        Pij1[catg*NsNs+i*Ns+j]); */
-                              }
-
-                          else
-                            For(j,tree->mod->ns)
-                              {
-                                p1 += p_lk1[csite*NsNg+catg*Ns+j] * Pij1[catg*NsNs+i*Ns+j] / (phydbl)POW(2,sum_scale1[catg*curr_mixt_tree->n_pattern+csite]);
-
-                                /* p1 += p_lk1[site*NsNg+catg*Ns+j] * Pij1[catg*NsNs+i*Ns+j];  */
-
-                                /* printf("\n. p1 %f %f", */
-                                /*        p_lk1[site*NsNg+catg*Ns+j], */
-                                /*        Pij1[catg*NsNs+i*Ns+j]); */
-                             }
-
-
-                          p2 = .0;
-                          if(v2->tax)
-                            For(j,tree->mod->ns)
-                              {
-                                p2 += v2->b[0]->p_lk_tip_r[csite*Ns+j] * Pij2[catg*NsNs+i*Ns+j];
-                                /* printf("\n. p2 %d %f", */
-                                /*        v2->b[0]->p_lk_tip_r[site*Ns+j], */
-                                /*        Pij2[catg*NsNs+i*Ns+j]); */
-                              }
-                          else
-                            For(j,tree->mod->ns)
-                              {
-                                p2 += p_lk2[csite*NsNg+catg*Ns+j] * Pij2[catg*NsNs+i*Ns+j] / (phydbl)POW(2,sum_scale2[catg*curr_mixt_tree->n_pattern+csite]);
-
-                                /* p2 += p_lk2[site*NsNg+catg*Ns+j] * Pij2[catg*NsNs+i*Ns+j]; */
-
-                                /* printf("\n. p2 %f %f", */
-                                /*        p_lk2[site*NsNg+catg*Ns+j], */
-                                /*        Pij2[catg*NsNs+i*Ns+j]);  */
-                             }
-
-                          p[i] +=
-                            p0*p1*p2*
-                            tree->mod->e_frq->pi->v[i] /
-                            tree->cur_site_lk[csite] *
-                            curr_mixt_tree->mod->ras->gamma_r_proba->v[tree->mod->ras->parent_class_number] *
-                            tree->mod->r_mat_weight->v / r_mat_weight_sum *
-                            tree->mod->e_frq_weight->v / e_frq_weight_sum /
-                            sum_probas;
-
-                        }
-                    }
-
-                  PhyML_Fprintf(fp,"%4d\t%4d\t",site+1,d->num);
                   For(i,Ns)
                     {
-                      PhyML_Fprintf(fp,"%.4f\t",p[i]);
+                      p0 = .0;
+                      if(v0->tax)
+                        For(j,tree->mod->ns)
+                          {
+                            p0 += v0->b[0]->p_lk_tip_r[csite*Ns+j] * Pij0[catg*NsNs+i*Ns+j];
+                            
+                            /* printf("\n. p0 %d %f", */
+                            /*        v0->b[0]->p_lk_tip_r[site*Ns+j], */
+                            /*        Pij0[catg*NsNs+i*Ns+j]); */
+                          }
+                      else
+                        For(j,tree->mod->ns)
+                          {
+                            p0 += p_lk0[csite*NsNg+catg*Ns+j] * Pij0[catg*NsNs+i*Ns+j] / (phydbl)POW(2,sum_scale0[catg*tree->n_pattern+csite]);
+                            
+                            /* p0 += p_lk0[site*NsNg+catg*Ns+j] * Pij0[catg*NsNs+i*Ns+j]; */
+                            
+                            /* printf("\n. p0 %f %f", */
+                                    /*        p_lk0[site*NsNg+catg*Ns+j], */
+                                    /*        Pij0[catg*NsNs+i*Ns+j]); */
+                          }
+                      p1 = .0;
+                      if(v1->tax)
+                        For(j,tree->mod->ns)
+                          {
+                            p1 += v1->b[0]->p_lk_tip_r[csite*Ns+j] * Pij1[catg*NsNs+i*Ns+j];
+                            
+                            /* printf("\n. p1 %d %f", */
+                            /*        v1->b[0]->p_lk_tip_r[site*Ns+j], */
+                            /*        Pij1[catg*NsNs+i*Ns+j]); */
+                                  }
+                      
+                      else
+                        For(j,tree->mod->ns)
+                          {
+                            p1 += p_lk1[csite*NsNg+catg*Ns+j] * Pij1[catg*NsNs+i*Ns+j] / (phydbl)POW(2,sum_scale1[catg*tree->n_pattern+csite]);
+                            
+                            /* p1 += p_lk1[site*NsNg+catg*Ns+j] * Pij1[catg*NsNs+i*Ns+j];  */
+                            
+                            /* printf("\n. p1 %f %f", */
+                                    /*        p_lk1[site*NsNg+catg*Ns+j], */
+                                    /*        Pij1[catg*NsNs+i*Ns+j]); */
+                          }
+                      
+                      
+                      p2 = .0;
+                      if(v2->tax)
+                        For(j,tree->mod->ns)
+                          {
+                            p2 += v2->b[0]->p_lk_tip_r[csite*Ns+j] * Pij2[catg*NsNs+i*Ns+j];
+                            /* printf("\n. p2 %d %f", */
+                                    /*        v2->b[0]->p_lk_tip_r[site*Ns+j], */
+                                    /*        Pij2[catg*NsNs+i*Ns+j]); */
+                          }
+                      else
+                        For(j,tree->mod->ns)
+                          {
+                            p2 += p_lk2[csite*NsNg+catg*Ns+j] * Pij2[catg*NsNs+i*Ns+j] / (phydbl)POW(2,sum_scale2[catg*tree->n_pattern+csite]);
+                            
+                            /* p2 += p_lk2[site*NsNg+catg*Ns+j] * Pij2[catg*NsNs+i*Ns+j]; */
+                            
+                            /* printf("\n. p2 %f %f", */
+                            /*        p_lk2[site*NsNg+catg*Ns+j], */
+                            /*        Pij2[catg*NsNs+i*Ns+j]);  */
+                          }
+                      
+                      p[i] +=
+                        p0*p1*p2*
+                        tree->mod->e_frq->pi->v[i] /
+                        tree->cur_site_lk[csite] *
+                        tree->mod->ras->gamma_r_proba->v[catg];
+                      
                     }
-                  PhyML_Fprintf(fp,"\n");
-                  fflush(NULL);
-                  /* Exit("\n"); */
-                  
-
-                  tree = tree->next;
-                  d    = d->next;
-
-
                 }
-              while(tree && d && tree->is_mixt_tree == NO);
+              
+              PhyML_Fprintf(fp,"%4d\t%4d\t",site+1,d->num);
+              sum_probas = .0;
+              For(i,Ns)
+                {
+                  PhyML_Fprintf(fp,"%.4f\t",p[i]);
+                  sum_probas += p[i];
+                }
+              PhyML_Fprintf(fp,"\n");
+              assert(Are_Equal(sum_probas,1.0,0.01));
+              fflush(NULL);
+              /* Exit("\n"); */
             }
-
+          
           Free(p);
-          curr_mixt_tree = curr_mixt_tree->next_mixt;
-          curr_mixt_d    = curr_mixt_d->next_mixt;
         }
-      while(curr_mixt_tree != NULL);
     }
 }
 
@@ -3814,10 +3800,10 @@ void Pull_Scaling_Factors(int site,
                           t_edge *b,
                           t_tree *tree)
 {
-  int catg;
-  int *sum_scale_left_cat,*sum_scale_rght_cat;
-  int exponent;
-  phydbl max_sum_scale,min_sum_scale;
+    int catg;
+    int *sum_scale_left_cat,*sum_scale_rght_cat;
+    int exponent;
+    phydbl max_sum_scale,min_sum_scale;
   phydbl sum,tmp;
   phydbl site_lk_cat;
 
diff --git a/src/m4.c b/src/m4.c
index efbc334..e2b242d 100644
--- a/src/m4.c
+++ b/src/m4.c
@@ -127,8 +127,6 @@ int M4_main(int argc, char **argv)
 		  if((!num_data_set) && (!num_tree) && (!num_rand_tree)) Check_Memory_Amount(tree);
 
 		  Prepare_Tree_For_Lk(tree);
-
-		  if(io->in_tree == 1) Spr_Pars(tree);
 		 
 		  if(io->do_alias_subpatt)
 		    {
@@ -238,7 +236,7 @@ int M4_main(int argc, char **argv)
 
 	      if(io->n_trees > 1 && io->n_data_sets > 1) break;
 	    }
-	  Free_Cseq(cdata);
+	  Free_Calign(cdata);
 	}
       else
 	{
@@ -1455,7 +1453,7 @@ void M4_Detect_Site_Switches_Experiment(t_tree *tree)
   Free(site_lnl_cov);
   Free(site_lnl_nocov);
 
-  Free_Cseq(cpy_data);
+  Free_Calign(cpy_data);
   Free(nocov_bl);
   Free(cov_bl);
 }
diff --git a/src/main.c b/src/main.c
index e13fd42..4aa70ea 100644
--- a/src/main.c
+++ b/src/main.c
@@ -81,12 +81,12 @@ int main(int argc, char **argv)
       return(0);
     }
 
-
 #ifdef EVOLVE
   io->colalias = NO;
 #endif
 
   r_seed = (io->r_seed < 0)?(time(NULL)):(io->r_seed);
+  PhyML_Printf("\n. Random seed: %d",r_seed);
   srand(r_seed);
   io->r_seed = r_seed;
 
@@ -124,7 +124,7 @@ int main(int argc, char **argv)
 
           for(num_tree=(io->n_trees == 1)?(0):(num_data_set);num_tree < io->n_trees;num_tree++)
             {
-              if(!io->mod->s_opt->random_input_tree) io->mod->s_opt->n_rand_starts = 1;
+              if(io->mod->s_opt->random_input_tree == NO) io->mod->s_opt->n_rand_starts = 1;
 
               if(orig_random_input_tree == YES && io->n_trees > 1)
                 {
@@ -148,6 +148,7 @@ int main(int argc, char **argv)
                     case 2 :          { tree = Read_User_Tree(cdata,mod,io); break; }
                     }
 
+
                   if(io->fp_in_constraint_tree != NULL)
                     {
                       char *s;
@@ -205,11 +206,11 @@ int main(int argc, char **argv)
                       Exit("\n");
                     }
 
-
                   Prepare_Tree_For_Lk(tree);
                   Br_Len_Not_Involving_Invar(tree);
                   Unscale_Br_Len_Multiplier_Tree(tree);
 
+
 #ifdef BEAGLE
                   if(mod->bootstrap == YES)
                     {
@@ -224,13 +225,7 @@ int main(int argc, char **argv)
 #endif
 
 #ifdef PHYML
-                  if(io->in_tree == 1) Spr_Pars(tree);
-
-                  /* /\* ******************** *\/ */
-                  /* Sample_Ancestral_Seq(NO,YES,tree); */
-                  /* tree->mod->augmented = YES; */
-                  /* Lk(NULL,tree); */
-                  /* /\* ******************** *\/ */
+                  if(tree->io->print_json_trace == YES) JSON_Tree_Io(tree,tree->io->fp_out_json_trace); 
                                    
 		  if(tree->mod->s_opt->opt_topo)
 		    {
@@ -245,6 +240,7 @@ int main(int argc, char **argv)
 #ifdef BEAGLE
                       tree->b_inst = create_beagle_instance(tree, io->quiet, io);
 #endif
+
                       //Optimize Branch lengths?
                       if(tree->mod->s_opt->opt_subst_param || tree->mod->s_opt->opt_bl) {
                         Round_Optimize(tree,tree->data,ROUND_MAX);
@@ -255,7 +251,7 @@ int main(int argc, char **argv)
                     }
 
 
-                  if(tree->mod->gamma_mgf_bl) Optimum_Root_Position_IL_Model(tree);
+                  if(tree->mod->gamma_mgf_bl) Best_Root_Position_IL_Model(tree);
 
                   Set_Both_Sides(YES,tree);
                   Lk(NULL,tree);
@@ -351,7 +347,7 @@ int main(int argc, char **argv)
 
               if(io->n_trees > 1 && io->n_data_sets > 1) break;
             }
-            Free_Cseq(cdata);
+            Free_Calign(cdata);
         }
     else
         {
@@ -378,6 +374,7 @@ int main(int argc, char **argv)
   if(io->fp_out_trees)          fclose(io->fp_out_trees);
   if(io->fp_out_stats)          fclose(io->fp_out_stats);
   if(io->fp_out_trace)          fclose(io->fp_out_trace);
+  if(io->fp_out_json_trace)     fclose(io->fp_out_json_trace);
 
   if(io->fp_in_constraint_tree != NULL) Free_Tree(io->cstr_tree);
   Free_Input(io);
@@ -569,6 +566,14 @@ int main(int argc, char **argv)
   return 1;
 }
 
+#elif(DATE)
+#include "date.h"
+int main(int argc, char **argv)
+{
+  DATE_Main(argc,argv);
+  return 1;
+}
+
 #elif(CHECKPOINT)
 #include "checkpoint.h"
 int main(int argc, char **argv)
diff --git a/src/make.c b/src/make.c
index f70ebf7..51e0776 100644
--- a/src/make.c
+++ b/src/make.c
@@ -34,6 +34,7 @@ void Make_Tree_4_Lk(t_tree *tree, calign *cdata, int n_site)
     {
       For(i,2*tree->n_otu-1) Make_Edge_Lk(tree->a_edges[i],tree);
       For(i,2*tree->n_otu-2) Make_Node_Lk(tree->a_nodes[i]);
+      For(i,2*tree->n_otu-1) Make_Edge_Loc(tree->a_edges[i],tree);
 
       if(tree->mod->s_opt->greedy)
         Init_P_Lk_Tips_Double(tree);
@@ -41,6 +42,14 @@ void Make_Tree_4_Lk(t_tree *tree, calign *cdata, int n_site)
         Init_P_Lk_Tips_Int(tree);
 
       Init_P_Lk_Loc(tree);
+
+      if(tree->n_root != NULL)
+        {
+          Free_Edge_Lk_Rght(tree->n_root->b[1]);
+          Free_Edge_Lk_Rght(tree->n_root->b[2]);
+          Free_Edge_Loc_Rght(tree->n_root->b[1]);
+          Free_Edge_Loc_Rght(tree->n_root->b[2]);
+        }
     }
 }
 
@@ -53,9 +62,17 @@ void Make_Tree_4_Pars(t_tree *tree, calign *cdata, int n_site)
   int i;
   tree->site_pars = (int *)mCalloc(tree->n_pattern,sizeof(int));
   tree->step_mat = (int *)mCalloc(tree->mod->ns * tree->mod->ns,sizeof(int));
+
   For(i,2*tree->n_otu-1) Make_Edge_Pars(tree->a_edges[i],tree);
   Init_Ui_Tips(tree);
   Init_P_Pars_Tips(tree); /* Must be called after Init_Ui_Tips is called */
+
+  if(tree->n_root)
+    {
+      Free_Edge_Pars_Rght(tree->a_edges[2*tree->n_otu-3]);
+      Free_Edge_Pars_Rght(tree->a_edges[2*tree->n_otu-2]);
+    }
+
   Get_Step_Mat(tree);
 }
 
@@ -239,9 +256,7 @@ void Make_Edge_Lk_Left(t_edge *b, t_tree *tree)
       b->p_lk_left      = (phydbl *)mCalloc(tree->data->crunch_len*MAX(tree->mod->ras->n_catg,tree->mod->n_mixt_classes)*tree->mod->ns,sizeof(phydbl));
     }
 
-
   b->patt_id_left  = (int *)mCalloc(tree->data->crunch_len,sizeof(int));
-  b->p_lk_loc_left = (int *)mCalloc(tree->data->crunch_len,sizeof(int));
 }
 
 //////////////////////////////////////////////////////////////
@@ -287,12 +302,36 @@ void Make_Edge_Lk_Rght(t_edge *b, t_tree *tree)
     }
 
   b->patt_id_rght  = (int *)mCalloc(tree->data->crunch_len,sizeof(int));
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void Make_Edge_Loc(t_edge *b, t_tree *tree)
+{
+  Make_Edge_Loc_Left(b,tree);
+  Make_Edge_Loc_Rght(b,tree);
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void Make_Edge_Loc_Rght(t_edge *b, t_tree *tree)
+{
   b->p_lk_loc_rght = (int *)mCalloc(tree->data->crunch_len,sizeof(int));
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
+void Make_Edge_Loc_Left(t_edge *b, t_tree *tree)
+{
+  b->p_lk_loc_left = (int *)mCalloc(tree->data->crunch_len,sizeof(int));
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
 void Make_Edge_NNI(t_edge *b)
 {
   b->nni    = Make_NNI();
@@ -304,11 +343,12 @@ void Make_Edge_NNI(t_edge *b)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
-nni *Make_NNI()
+t_nni *Make_NNI()
 {
-  nni *a_nni;
-  a_nni = (nni *)mCalloc(1,sizeof(nni ));
+  t_nni *a_nni;
+
+  a_nni = (t_nni *)mCalloc(1,sizeof(t_nni));
+  
   Init_NNI(a_nni);
   return a_nni;
 }
@@ -327,7 +367,8 @@ t_node *Make_Node_Light(int num)
   n->score    = (phydbl *)mCalloc(3,sizeof(phydbl));
   n->s_ingrp  = (int *)mCalloc(3,sizeof(int));
   n->s_outgrp = (int *)mCalloc(3,sizeof(int));
-
+  n->cal      = (t_cal **)mCalloc(MAX_N_CAL,sizeof(t_cal *));
+ 
   Init_Node_Light(n,num);
 
   return n;
@@ -493,24 +534,18 @@ void Make_All_Tree_Edges(t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-calign *Make_Cseq(int n_otu, int crunch_len, int state_len, int init_len, char **sp_names)
+calign *Make_Calign(int n_otu, int crunch_len, int state_len, int init_len, char **sp_names)
 {
   calign *cdata;
   int j;
 
   cdata           = (calign *)mCalloc(1,sizeof(calign));
-  cdata->n_otu    = n_otu;
   cdata->c_seq    = (align **)mCalloc(n_otu,sizeof(align *));
   cdata->b_frq    = (phydbl *)mCalloc(T_MAX_ALPHABET,sizeof(phydbl));
-  cdata->wght     = (int *)mCalloc(crunch_len,sizeof(int));
+  cdata->wght     = (phydbl *)mCalloc(crunch_len,sizeof(phydbl));
   cdata->ambigu   = (short int *)mCalloc(crunch_len,sizeof(short int));
   cdata->invar    = (short int *)mCalloc(crunch_len,sizeof(short int));
   cdata->sitepatt = (int *)mCalloc(init_len,sizeof(int ));
-  cdata->format   = 0;
-
-  cdata->crunch_len = crunch_len;
-  cdata->init_len   = init_len;
-  cdata->obs_pinvar = .0;
 
   For(j,n_otu)
     {
@@ -619,10 +654,6 @@ t_mod *Make_Model_Basic()
   mod->mr                     = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl));
   Init_Scalar_Dbl(mod->mr);
 
-  mod->user_b_freq            = (vect_dbl *)mCalloc(1,sizeof(vect_dbl));
-  Init_Vect_Dbl(0,mod->user_b_freq);
-  mod->user_b_freq->v         = (phydbl *)mCalloc(T_MAX_OPTION,sizeof(phydbl));
-
   mod->e_frq_weight           = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl));
   Init_Scalar_Dbl(mod->e_frq_weight);
 
@@ -660,15 +691,16 @@ void Make_Model_Complete(t_mod *mod)
       mod->r_mat = (t_rmat *)Make_Rmat(mod->ns);
       Init_Rmat(mod->r_mat);
     }
+
   if(!mod->e_frq)
     {
       mod->e_frq = (t_efrq *)Make_Efrq(mod->ns);
-      Init_Efrq(mod->e_frq);
+      Init_Efrq(NULL,mod->e_frq);
     }
 
   Make_RAS_Complete(mod->ras);
 
-  mod->user_b_freq->len = mod->ns;
+  mod->e_frq->user_b_freq->len = mod->ns;
 
   if(mod->whichmodel < 0)
     {
@@ -757,6 +789,10 @@ t_efrq *Make_Efrq(int ns)
   e_frq->pi_unscaled->v   = (phydbl *)mCalloc(ns,sizeof(phydbl));
   e_frq->pi_unscaled->len = ns;
 
+  e_frq->user_b_freq      = (vect_dbl *)mCalloc(1,sizeof(vect_dbl));
+  Init_Vect_Dbl(0,e_frq->user_b_freq);
+  e_frq->user_b_freq->v   = (phydbl *)mCalloc(T_MAX_OPTION,sizeof(phydbl));
+
   return e_frq;
 }
 
@@ -814,9 +850,11 @@ option *Make_Input()
   io->out_boot_stats_file               = (char *)mCalloc(T_MAX_FILE,sizeof(char));
   io->out_stats_file                    = (char *)mCalloc(T_MAX_FILE,sizeof(char));
   io->out_lk_file                       = (char *)mCalloc(T_MAX_FILE,sizeof(char));
+  io->weight_file                       = (char *)mCalloc(T_MAX_FILE,sizeof(char));
   io->out_ps_file                       = (char *)mCalloc(T_MAX_FILE,sizeof(char));
   io->out_summary_file                  = (char *)mCalloc(T_MAX_FILE,sizeof(char));
   io->out_trace_file                    = (char *)mCalloc(T_MAX_FILE,sizeof(char));
+  io->out_json_trace_file               = (char *)mCalloc(T_MAX_FILE,sizeof(char));
   io->nt_or_cd                          = (char *)mCalloc(T_MAX_FILE,sizeof(char));
   io->run_id_string                     = (char *)mCalloc(T_MAX_OPTION,sizeof(char));
   io->clade_list_file                   = (char *)mCalloc(T_MAX_FILE,sizeof(char));
@@ -1086,11 +1124,11 @@ t_rate *RATES_Make_Rate_Struct(int n_otu)
       rates->survival_rank        = (phydbl *)mCalloc(2*n_otu-1,sizeof(phydbl));
       rates->survival_dur         = (phydbl *)mCalloc(2*n_otu-1,sizeof(phydbl));
       rates->calib_prob           = (phydbl *)mCalloc(2*n_otu-1,sizeof(phydbl));
-      rates->curr_nd_for_cal      = (int *)mCalloc(2*n_otu-1,sizeof(int));
       rates->t_prior_min_ori      = (phydbl *)mCalloc(2*n_otu-1,sizeof(phydbl));
       rates->t_prior_max_ori      = (phydbl *)mCalloc(2*n_otu-1,sizeof(phydbl));
       rates->times_partial_proba  = (phydbl *)mCalloc(n_otu*n_otu,sizeof(phydbl));
       rates->numb_calib_chosen    = (int *)mCalloc(n_otu*n_otu,sizeof(phydbl));
+      rates->a_cal                = (t_cal **)mCalloc(n_otu-1,sizeof(t_cal *));
     }
 
   return rates;
@@ -1099,22 +1137,36 @@ t_rate *RATES_Make_Rate_Struct(int n_otu)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-t_cal *Make_Calib(int n_otu)
+t_cal *Make_Calibration()
 {
   t_cal *calib;
-  int i;
-  i = 0;
-  calib                        = (t_cal *)mCalloc(1, sizeof(t_cal));
-  calib -> proba               = (phydbl *)mCalloc(2 * n_otu, sizeof(phydbl));
-  calib -> all_applies_to      = (t_node **)mCalloc(2 * n_otu - 1, sizeof(t_node *));
-  For(i, 2 * n_otu - 1)
-  calib -> all_applies_to[i]   = (t_node *)mCalloc(1, sizeof(t_node));
+
+  calib = (t_cal *)mCalloc(1, sizeof(t_cal));
+
   return(calib);
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
+void Make_All_Calibration(t_tree *tree)
+{
+  int i;
+  t_cal **all_cal;
+
+  assert(tree->rates);
+
+  all_cal = (t_cal **)mCalloc(2*tree->n_otu-1,sizeof(t_cal *));
+
+  For(i,2*tree->n_otu-1) all_cal[i] = Make_Calibration();
+
+  tree->rates->a_cal = all_cal;
+
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
 void Make_Rmat_Weight(t_tree *mixt_tree)
 {
   t_tree *tree, *buff_tree;
@@ -1149,18 +1201,22 @@ void Make_Rmat_Weight(t_tree *mixt_tree)
     }
   while(tree);
 
-
+  
   tree = mixt_tree->next;
   tree->mod->r_mat_weight = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl));
   Init_Scalar_Dbl(tree->mod->r_mat_weight);
   tree->mod->r_mat_weight->v = 1.0;
   curr_weight = tree->mod->r_mat_weight;
 
+
   buff_tree = tree = mixt_tree;
   do // For each mixt_tree
     {
-      if(tree->is_mixt_tree == YES) tree = tree->next;
-      
+      if(tree->is_mixt_tree == YES) 
+        {
+          tree = tree->next;
+        }
+
       buff_tree = mixt_tree->next;
       do
         {
@@ -1232,7 +1288,6 @@ void Make_Efrq_Weight(t_tree *mixt_tree)
   while(tree);
 
 
-
   tree = mixt_tree->next;
   tree->mod->e_frq_weight = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl));
   Init_Scalar_Dbl(tree->mod->e_frq_weight);
@@ -1403,7 +1458,27 @@ t_poly *Make_Poly(int n)
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
+
+t_sarea *Make_Sarea(int n_poly)
+{
+  t_sarea *s;
+  s = (t_sarea *)mCalloc(1,sizeof(t_sarea ));
+  s->a_poly = (t_poly **)mCalloc(n_poly,sizeof(t_poly *));
+  return(s);
+}
+
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
+
+t_ll *Make_Linked_List()
+{
+  t_ll *list;
+
+  // Create list if non-existing and add
+  list = (t_ll *)mCalloc(1,sizeof(t_ll));
+
+  return list;
+}
+
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
diff --git a/src/make.h b/src/make.h
index 324bac5..877ac85 100644
--- a/src/make.h
+++ b/src/make.h
@@ -27,7 +27,7 @@ void Make_Edge_Lk(t_edge *b,t_tree *tree);
 void Make_Edge_Lk_Left(t_edge *b,t_tree *tree);
 void Make_Edge_Lk_Rght(t_edge *b,t_tree *tree);
 void Make_Edge_NNI(t_edge *b);
-nni *Make_NNI();
+t_nni *Make_NNI();
 t_node *Make_Node_Light(int num);
 void Make_Node_Lk(t_node *n);
 nexcom **Make_Nexus_Com();
@@ -38,7 +38,7 @@ t_tree *Make_Tree(int n_otu);
 void Make_Tree_Path(t_tree *tree);
 void Make_All_Tree_Nodes(t_tree *tree);
 void Make_All_Tree_Edges(t_tree *tree);
-calign *Make_Cseq(int n_otu,int crunch_len,int state_len,int init_len,char **sp_names);
+calign *Make_Calign(int n_otu,int crunch_len,int state_len,int init_len,char **sp_names);
 t_treelist *Make_Treelist(int list_size);
 t_opt *Make_Optimiz();
 void Make_Custom_Model(t_mod *mod);
@@ -60,7 +60,7 @@ t_string *Make_String(int len);
 t_mcmc *MCMC_Make_MCMC_Struct();
 void Make_Tree_4_Lk(t_tree *tree,calign *cdata,int n_site);
 t_rate *RATES_Make_Rate_Struct(int n_otu);
-t_cal *Make_Calib();
+t_cal *Make_Calibration();
 void Make_Efrq_Weight(t_tree *mixt_tree);
 void Make_Rmat_Weight(t_tree *mixt_tree);
 t_geo *GEO_Make_Geo_Basic();
@@ -71,5 +71,11 @@ t_dsk *PHYREX_Make_Disk_Event(int n_dim, int n_otu);
 t_ldsk *PHYREX_Make_Lindisk_Node(int n_dim);
 void PHYREX_Make_Lindisk_Next(t_ldsk *t);
 t_poly *Make_Poly(int n);
+void Make_All_Calibration(t_tree *tree);
+t_sarea *Make_Sarea(int n_poly);
+void Make_Edge_Loc(t_edge *b, t_tree *tree);
+void Make_Edge_Loc_Rght(t_edge *b, t_tree *tree);
+void Make_Edge_Loc_Left(t_edge *b, t_tree *tree);
+t_ll *Make_Linked_List();
 
 #endif
diff --git a/src/mcmc.c b/src/mcmc.c
index 0909182..409119e 100644
--- a/src/mcmc.c
+++ b/src/mcmc.c
@@ -295,8 +295,8 @@ void MCMC(t_tree *tree)
       	  if(tree->mcmc->is == NO || tree->rates->model_log_rates == YES)
       	    {
               MCMC_Root_Time(tree);
-	      MCMC_One_Time(tree->n_root,tree->n_root->v[first],YES,tree);
-	      MCMC_One_Time(tree->n_root,tree->n_root->v[secod],YES,tree);
+	      MCMC_Time_Recur(tree->n_root,tree->n_root->v[first],YES,tree);
+	      MCMC_Time_Recur(tree->n_root,tree->n_root->v[secod],YES,tree);
       	    }
       	  else
       	    {
@@ -1064,7 +1064,21 @@ void MCMC_One_Node_Rate(t_node *a, t_node *d, int traversal, t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-void MCMC_One_Time(t_node *a, t_node *d, int traversal, t_tree *tree)
+void MCMC_Time_All(t_tree *tree)
+{
+  Set_Both_Sides(YES,tree);     
+  if(tree->mcmc->use_data == YES) Lk(NULL,tree);
+  Set_Both_Sides(NO,tree);     
+  
+  MCMC_Root_Time(tree);
+  MCMC_Time_Recur(tree->n_root,tree->n_root->v[1],YES,tree);
+  MCMC_Time_Recur(tree->n_root,tree->n_root->v[2],YES,tree);
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void MCMC_Time_Recur(t_node *a, t_node *d, int traversal, t_tree *tree)
 {
   phydbl u;
   phydbl t_min,t_max;
@@ -1080,6 +1094,8 @@ void MCMC_One_Time(t_node *a, t_node *d, int traversal, t_tree *tree)
   phydbl K;
   int move_num;
   
+  /* printf("\n IN ONE: %f",tree->rates->c_lnL_times); */
+
   if(d->tax) return; /* Won't change time at tip */
 
   /* if(FABS(tree->rates->t_prior_min[d->num] - tree->rates->t_prior_max[d->num]) < 1.E-10) return; */
@@ -1124,26 +1140,15 @@ void MCMC_One_Time(t_node *a, t_node *d, int traversal, t_tree *tree)
   t2 = tree->rates->nd_t[v2->num];
   t3 = tree->rates->nd_t[v3->num];
 
-
-  /* t_min = MAX(t0,tree->rates->t_prior_min[d->num]);        */
-  /* t_max = MIN(MIN(t2,t3),tree->rates->t_prior_max[d->num]);*/
-
   t_min = t0;
   t_max = MIN(t2,t3);
 
   t_min += tree->rates->min_dt;
   t_max -= tree->rates->min_dt;
 
-  if(t_min > t_max) 
-    {
-      PhyML_Printf("\n== t_min = %f t_max = %f",t_min,t_max);
-      PhyML_Printf("\n== prior_min = %f prior_max = %f",tree->rates->t_prior_min[d->num],tree->rates->t_prior_max[d->num]);
-      PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__);
-      /* Exit("\n"); */
-    }
- 
-  MCMC_Make_Move(&t1_cur,&t1_new,t_min,t_max,&ratio,K,tree->mcmc->move_type[move_num]);
-  
+  assert(t_min < t_max);
+     
+  MCMC_Make_Move(&t1_cur,&t1_new,t_min,t_max,&ratio,K,tree->mcmc->move_type[move_num]);  
 
   if(t1_new > t_min && t1_new < t_max) 
     {
@@ -1152,7 +1157,7 @@ void MCMC_One_Time(t_node *a, t_node *d, int traversal, t_tree *tree)
       new_lnL_time = TIMES_Lk_Times(tree);
       ratio += (new_lnL_time - cur_lnL_time);
 
-      if(isinf(new_lnL_time) == NO) // Proposed value of t is inside its boundary
+      if(!(isinf(FABS(new_lnL_time)) == YES || isnan(new_lnL_time) == YES))
         {
           /* Update branch lengths */
           tree->rates->br_do_updt[d->num]  = YES;
@@ -1163,6 +1168,10 @@ void MCMC_One_Time(t_node *a, t_node *d, int traversal, t_tree *tree)
           new_lnL_rate = RATES_Lk_Rates(tree);
           ratio += (new_lnL_rate - cur_lnL_rate);
 
+          /* printf("\nONE cur_lnL_time: %f new_lnL_time: %f cur_t: %f new_t: %f\n",cur_lnL_time,new_lnL_time,t1_cur,t1_new); */
+          /* Print_Node(tree->n_root,tree->n_root->v[1],tree); */
+          /* Print_Node(tree->n_root,tree->n_root->v[2],tree); */
+          
           if(tree->mcmc->use_data)
             {
               if(tree->io->lk_approx == EXACT)
@@ -1209,13 +1218,12 @@ void MCMC_One_Time(t_node *a, t_node *d, int traversal, t_tree *tree)
 	           
       if(u > alpha) /* Reject */
 	{
-          //if(d -> num == 7) PhyML_Printf("\n. t_cur = %f t_rej = %f", t1_cur, t1_new);
 	  tree->rates->nd_t[d->num] = t1_cur;
-	  tree->c_lnL              = cur_lnL_data;
-	  tree->rates->c_lnL_rates = cur_lnL_rate;
-	  tree->rates->c_lnL_times = cur_lnL_time;
+	  tree->c_lnL               = cur_lnL_data;
+	  tree->rates->c_lnL_rates  = cur_lnL_rate;
+	  tree->rates->c_lnL_times  = TIMES_Lk_Times(tree);
           
-          if(isinf(new_lnL_time) == NO)
+          if(!(isinf(FABS(new_lnL_time)) == YES || isnan(new_lnL_time) == YES))
             {
               Restore_Br_Len(tree);
               RATES_Reset_Rates(tree);
@@ -1229,6 +1237,23 @@ void MCMC_One_Time(t_node *a, t_node *d, int traversal, t_tree *tree)
                   Update_P_Lk(tree,b1,d);
                 }
             }
+          else
+            {
+              Print_Node(tree->n_root,tree->n_root->v[1],tree);
+              Print_Node(tree->n_root,tree->n_root->v[2],tree);              
+              assert(FALSE);
+            }
+
+          
+          if(Are_Equal(tree->rates->c_lnL_times,cur_lnL_time,1.E-3) == NO)
+            {
+              PhyML_Printf("\n\n");
+              PhyML_Printf("\n. moved node %d from %f to %f\n",d->num,t1_cur,t1_new);
+              Print_Node(tree->n_root,tree->n_root->v[1],tree);
+              Print_Node(tree->n_root,tree->n_root->v[2],tree);              
+              PhyML_Printf("\n== new_glnL: %f cur_glnL: %f",tree->rates->c_lnL_times,cur_lnL_time);
+              Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
+            }
 	}
       else
 	{
@@ -1268,6 +1293,8 @@ void MCMC_One_Time(t_node *a, t_node *d, int traversal, t_tree *tree)
   
   tree->mcmc->run_move[move_num]++;
 
+  /* printf("\n OUT ONE: %f",tree->rates->c_lnL_times); */
+
   if(traversal == YES)
     {
       if(d->tax == YES) return;
@@ -1277,7 +1304,7 @@ void MCMC_One_Time(t_node *a, t_node *d, int traversal, t_tree *tree)
 	    {
 	      if(tree->io->lk_approx == EXACT && tree->mcmc->use_data) Update_P_Lk(tree,d->b[i],d);
 	      /* if(tree->io->lk_approx == EXACT && tree->mcmc->use_data) {tree->both_sides = YES; Lk(tree); } */
-	      MCMC_One_Time(d,d->v[i],YES,tree);
+	      MCMC_Time_Recur(d,d->v[i],YES,tree);
 	    }
       if(tree->io->lk_approx == EXACT && tree->mcmc->use_data) Update_P_Lk(tree,b1,d);
       /* if(tree->io->lk_approx == EXACT && tree->mcmc->use_data) {tree->both_sides = YES; Lk(tree); } */
@@ -1535,6 +1562,8 @@ void MCMC_Root_Time(t_tree *tree)
   int move_num;
   t_node *root;
 
+  /* printf("\n IN ROOT: %f",tree->rates->c_lnL_times); */
+
   root = tree->n_root;
 
   if(FABS(tree->rates->t_prior_min[root->num] - tree->rates->t_prior_max[root->num]) < 1.E-10) return;
@@ -1594,6 +1623,10 @@ void MCMC_Root_Time(t_tree *tree)
       new_lnL_rate = RATES_Lk_Rates(tree);
       new_lnL_time = TIMES_Lk_Times(tree); 
 
+      /* printf("\nROOT cur_lnL_time: %f new_lnL_time: %f\n",cur_lnL_time,new_lnL_time); */
+      /* Print_Node(tree->n_root,tree->n_root->v[1],tree); */
+      /* Print_Node(tree->n_root,tree->n_root->v[2],tree); */
+
       if(tree->mcmc->use_data) ratio += (new_lnL_data - cur_lnL_data);
       ratio += (new_lnL_rate - cur_lnL_rate);
       ratio += (new_lnL_time - cur_lnL_time);
@@ -1605,12 +1638,21 @@ void MCMC_Root_Time(t_tree *tree)
       if(u > alpha) /* Reject */
 	{
 	  tree->rates->nd_t[root->num] = t1_cur;
-	  tree->c_lnL              = cur_lnL_data;
-	  tree->rates->c_lnL_rates = cur_lnL_rate;
-	  tree->rates->c_lnL_times = cur_lnL_time;
+	  tree->c_lnL                  = cur_lnL_data;
+	  tree->rates->c_lnL_rates     = cur_lnL_rate;
+	  tree->rates->c_lnL_times     = TIMES_Lk_Times(tree); // required as some t_prior_min/max have been modified 
 	  Restore_Br_Len(tree);
 	  RATES_Reset_Rates(tree);
 	  RATES_Reset_Times(tree);
+          
+          if(Are_Equal(tree->rates->c_lnL_times,cur_lnL_time,1.E-3) == NO)
+            {
+              PhyML_Printf("\n\n");
+              Print_Node(tree->n_root,tree->n_root->v[1],tree);
+              Print_Node(tree->n_root,tree->n_root->v[2],tree);
+              PhyML_Printf("\n== new_glnL: %f cur_glnL: %f",tree->rates->c_lnL_times,cur_lnL_time);
+              Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
+            }
 	}
       else
 	{
@@ -1625,7 +1667,7 @@ void MCMC_Root_Time(t_tree *tree)
 	  PhyML_Printf("\n== t_min=%f t_max=%f",t_min,t_max);
 	  PhyML_Printf("\n== (t1-t0)=%f (t2-t1)=%f",t1_cur-t0,t2-t1_cur);
 	  PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__);
-	  /*       Exit("\n"); */
+          /* Exit("\n"); */
 	}
       if(t1_new > MIN(t2,t3))
 	{
@@ -1634,17 +1676,18 @@ void MCMC_Root_Time(t_tree *tree)
 	  PhyML_Printf("\n== t_min=%f t_max=%f",t_min,t_max);
 	  PhyML_Printf("\n== (t1-t0)=%f (t2-t1)=%f",t1_cur-t0,t2-t1_cur);
 	  PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__);
-	  /*       Exit("\n"); */
+          /* Exit("\n"); */
 	}
       
       if(isnan(t1_new))
 	{
 	  PhyML_Printf("\n== run=%d",tree->mcmc->run);
-	  PhyML_Printf("\n== Err/ in file %s at line %d\n",__FILE__,__LINE__);
-	  /*       Exit("\n"); */
+	  PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__);
+          /* Exit("\n"); */
 	}
     }
-  
+    
+  /* printf("\n OUT ROOT: %f",tree->rates->c_lnL_times); */
   tree->mcmc->run_move[move_num]++;
 
 }
@@ -1661,7 +1704,9 @@ void MCMC_Tree_Height(t_tree *tree)
   phydbl cur_lnL_time,new_lnL_time;
   phydbl floor;
   int n_nodes;
-  
+      
+  /* printf("\n IN SCALE: %f",tree->rates->c_lnL_times); */
+
   if(FABS(tree->rates->t_prior_max[tree->n_root->num] - tree->rates->t_prior_min[tree->n_root->num]) < 1.E-10) return;
 
   RATES_Record_Times(tree);
@@ -1677,7 +1722,7 @@ void MCMC_Tree_Height(t_tree *tree)
   
   u = Uni();
   mult = EXP(K*(u-0.5));
- 
+
  /* WARNING: It must not be floor = tree->rates->t_prior_max[tree->n_root->num]; 
      floor is the maximum value a node height can take when one ignores the 
      calibration nodes, i.e., floor is set by the height of the tips
@@ -1687,18 +1732,6 @@ void MCMC_Tree_Height(t_tree *tree)
   /* floor = tree->rates->t_prior_max[tree->n_root->num]; */
 
   Scale_Subtree_Height(tree->n_root,mult,floor,&n_nodes,tree);
-
-  /* For(i,2*tree->n_otu-1) */
-  /*   { */
-  /*     if(tree->rates->nd_t[i] > tree->rates->t_prior_max[i] || */
-  /* 	 tree->rates->nd_t[i] < tree->rates->t_prior_min[i]) */
-  /* 	{ */
-  /* 	  RATES_Reset_Times(tree); */
-  /* 	  Restore_Br_Len(tree); */
-  /* 	  tree->mcmc->run_move[tree->mcmc->num_move_tree_height]++; */
-  /*         return; */
-  /* 	} */
-  /*   } */
   
   For(i,2*tree->n_otu-2) tree->rates->br_do_updt[i] = YES;
   RATES_Update_Cur_Bl(tree);
@@ -1707,7 +1740,6 @@ void MCMC_Tree_Height(t_tree *tree)
   new_lnL_rate = RATES_Lk_Rates(tree);
   new_lnL_time = TIMES_Lk_Times(tree);
  
-
   /* The Hastings ratio is actually mult^(n) when changing the absolute
      node heights. When considering the relative heights, this ratio combined
      to the Jacobian for the change of variable ends up to being equal to mult. 
@@ -1733,19 +1765,37 @@ void MCMC_Tree_Height(t_tree *tree)
   /* !!!!!!!!!!!! */
   /* ratio += LOG(Dexp(FABS(new_height-floor),1./10.) / Dexp(FABS(cur_height-floor),1./10.)); */
   
+  /* printf("\nSCALE cur_lnL_time: %f new_lnL_time: %f cur_lnL_rate: %f new_lnL_rate: %f cur_lnL_data: %f new_lnL_data: %f  ratio: %f\n", */
+  /*        cur_lnL_time,new_lnL_time, */
+  /*        cur_lnL_rate,new_lnL_rate, */
+  /*        cur_lnL_data,new_lnL_data,          */
+  /*        EXP(ratio)); */
+  /* Print_Node(tree->n_root,tree->n_root->v[1],tree); */
+  /* Print_Node(tree->n_root,tree->n_root->v[2],tree); */
+
+
   ratio = EXP(ratio);
   alpha = MIN(1.,ratio);
   u = Uni();
 
   /* printf("\n. cur_lnL_time: %f new_lnL_time: %f",cur_lnL_time,new_lnL_time); */
+  /* Print_Node(tree->n_root,tree->n_root->v[1],tree); */
+  /* Print_Node(tree->n_root,tree->n_root->v[2],tree); */
   
   if(u > alpha)
     {
       RATES_Reset_Times(tree);
       Restore_Br_Len(tree);
-      tree->c_lnL = cur_lnL_data;
+      tree->rates->c_lnL_times = TIMES_Lk_Times(tree); // Required in order to set t_prior_min/max to their original values
+      tree->c_lnL              = cur_lnL_data;
       tree->rates->c_lnL_rates = cur_lnL_rate;
-      tree->rates->c_lnL_times = cur_lnL_time;
+
+      if(Are_Equal(tree->rates->c_lnL_times,cur_lnL_time,1.E-3) == NO)
+        {
+          PhyML_Printf("\n== new_glnL: %f cur_glnL: %f",tree->rates->c_lnL_times,cur_lnL_time);
+          Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
+        }
+      /* printf("\n. REJECT\n"); */
     }
   else
     {
@@ -1754,6 +1804,8 @@ void MCMC_Tree_Height(t_tree *tree)
       /* printf("\n. ACCEPT\n"); */
     }
 
+  /* printf("\n OUT SCALE: %f",tree->rates->c_lnL_times); */
+
   tree->mcmc->run_move[tree->mcmc->num_move_tree_height]++;
   tree->mcmc->run_move[tree->mcmc->num_move_nd_t+tree->n_root->num-tree->n_otu]++;
 }
@@ -3390,10 +3442,12 @@ void MCMC_Randomize_Node_Times(t_tree *tree)
   
   tree->rates->nd_t[tree->n_root->num] = u;
 
+  printf("\n. ROOT: %f %f %d",t_inf,t_sup,tree->n_root->num);
+  printf("\n. ROOT: %f",u);
+
   MCMC_Randomize_Node_Times_Top_Down(tree->n_root,tree->n_root->v[2],tree);
   MCMC_Randomize_Node_Times_Top_Down(tree->n_root,tree->n_root->v[1],tree);
 
-
   min_node = -1;
   iter = 0;
   do
@@ -3428,7 +3482,6 @@ void MCMC_Randomize_Node_Times(t_tree *tree)
       MCMC_Randomize_Node_Times_Bottom_Up(tree->n_root,tree->n_root->v[2],tree);
       MCMC_Randomize_Node_Times_Bottom_Up(tree->n_root,tree->n_root->v[1],tree);
       
-
       iter++;
     }
   while(iter < 1000);
@@ -4084,24 +4137,29 @@ void MCMC_Covarion_Switch(t_tree *tree)
 
 void MCMC_Birth_Rate(t_tree *tree)
 {
- 
-  /* printf("\n. BIRTH cur_lnL_time: %f ",tree->rates->c_lnL_times); */
-
-#ifdef INVITEE
-  tree->rates->update_time_norm_const = YES;
-#endif
-
+  /* PhyML_Printf("\n IN BIRTH: %f",tree->rates->c_lnL_times); */
   MCMC_Single_Param_Generic(&(tree->rates->birth_rate),
 			    tree->rates->birth_rate_min,
 			    tree->rates->birth_rate_max,
 			    tree->mcmc->num_move_birth_rate,
 			    &(tree->rates->c_lnL_times),NULL,
 			    Wrap_Lk_Times,NULL,tree->mcmc->move_type[tree->mcmc->num_move_birth_rate],NO,NULL,tree,NULL); 
+  /* PhyML_Printf("\n OUT BIRTH: %f",tree->rates->c_lnL_times); */
+}
 
-#ifdef INVITEE
-  TIMES_Lk_Times(tree); 
-  tree->rates->update_time_norm_const = NO;
-#endif
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void MCMC_Death_Rate(t_tree *tree)
+{
+  /* PhyML_Printf("\n IN DEATH: %f %f",TIMES_Lk_Times(tree),tree->rates->death_rate); */
+  MCMC_Single_Param_Generic(&(tree->rates->death_rate),
+			    tree->rates->death_rate_min,
+			    tree->rates->death_rate_max,
+			    tree->mcmc->num_move_death_rate,
+			    &(tree->rates->c_lnL_times),NULL,
+			    Wrap_Lk_Times,NULL,tree->mcmc->move_type[tree->mcmc->num_move_death_rate],NO,NULL,tree,NULL); 
+  /* PhyML_Printf("\n OUT DEATH: %f",tree->rates->c_lnL_times); */
 }
 
 //////////////////////////////////////////////////////////////
@@ -4186,7 +4244,6 @@ void MCMC_Nu(t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void MCMC_All_Rates(t_tree *tree)
 {
   phydbl cur_lnL_data, new_lnL_data, cur_lnL_rate;
@@ -4264,6 +4321,177 @@ void MCMC_Sim_Rate(t_node *a, t_node *d, t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
+void MCMC_Prune_Regraft(t_tree *tree)
+{
+  phydbl u,alpha,ratio;
+  phydbl cur_glnL, new_glnL;
+  phydbl cur_alnL, new_alnL;
+  int i,prune_idx,n_iter,n_regraft_nd,regraft_idx;
+  phydbl time_daughter;
+  int rnd_dir,dir_v1,dir_v2;
+  t_node *prune,*prune_daughter,*regraft_nd;
+  t_ll *regraft_nd_list;
+  t_edge *target, *ori_target, *residual,*regraft_edge;
+
+  n_iter = MAX(1,(int)(tree->n_otu/5));
+  regraft_nd_list = NULL;
+
+  while(n_iter--)
+    {
+      tree->mcmc->run_move[tree->mcmc->num_move_spr]++;
+  
+      new_glnL       = tree->rates->c_lnL_times;
+      cur_glnL       = tree->rates->c_lnL_times;
+      new_alnL       = tree->c_lnL;
+      cur_alnL       = tree->c_lnL;
+      ratio          = 0.0;
+
+      /* Record edge lengths */
+      Record_Br_Len(tree);
+
+      // Select prune node (any internal node except the root)
+      i = 0;
+      do
+        {
+          prune_idx = Rand_Int(tree->n_otu,2*tree->n_otu-2);
+          i++;
+          assert(i<1000);
+        }
+      while(tree->a_nodes[prune_idx] == tree->n_root);
+
+      prune = tree->a_nodes[prune_idx];
+
+      assert(prune && prune->tax == NO);
+
+      // Select a daughter of prune node
+      dir_v1 = dir_v2 = -1;
+      For(i,3) 
+        if(prune->v[i] != prune->anc)
+          {
+            if(dir_v1 < 0) dir_v1 = i;
+            else           dir_v2 = i;
+          }
+      
+      u = Uni();
+      if(u < 0.5) rnd_dir = dir_v1;
+      else        rnd_dir = dir_v2;
+      
+      prune_daughter = prune->v[rnd_dir];
+      time_daughter  = tree->rates->nd_t[prune_daughter->num];
+
+
+
+      // Get the list of potential regraft nodes (oldest node on regraft edge)
+      regraft_nd_list = Make_Linked_List();
+      Init_Linked_List(regraft_nd_list);
+      For(i,3) 
+        if(i != rnd_dir) 
+          {
+            List_Of_Regraft_Nodes(prune,
+                                  prune->v[i],
+                                  time_daughter,
+                                  regraft_nd_list,
+                                  tree);
+          }
+      
+
+      // Number of regraft nodes
+      n_regraft_nd = Linked_List_Len(regraft_nd_list);
+      
+
+      // Randomly select one (uniform)
+      regraft_idx = Rand_Int(0,n_regraft_nd-1);
+
+      regraft_nd = Linked_List_Elem(regraft_idx,regraft_nd_list);
+
+      Free_Linked_List(regraft_nd_list);
+
+
+      // Select a daughter of selected regraft node
+      dir_v1 = dir_v2 = -1;
+      For(i,3)
+        if(regraft_nd->v[i] != regraft_nd->anc)
+          {
+            if(dir_v1 < 0) dir_v1 = i;
+            else           dir_v2 = i;
+          }
+      
+      u = Uni();
+      if(u < 0.5) rnd_dir = dir_v1;
+      else        rnd_dir = dir_v2;
+
+      regraft_edge = regraft_nd->b[rnd_dir];
+
+      printf("\n. prune: %d prune_daughter: %d regraft: %d %d root: %d root->v[1]: %d root->v[2]: %d\n",
+             prune->num,
+             prune_daughter->num,
+             regraft_edge->left->num,
+             regraft_edge->rght->num,
+             tree->n_root->num,
+             tree->n_root->v[1]->num,
+             tree->n_root->v[2]->num);
+      
+
+      // Prune
+      target = residual = NULL;
+      Prune_Subtree(prune,prune_daughter,&target,&residual,tree);
+      ori_target = target;
+      // Regraft
+      Graft_Subtree(regraft_edge,prune,residual,tree);
+      
+      if(tree->mcmc->use_data == YES)      
+        {
+          Set_Both_Sides(NO,tree);
+          new_alnL = Lk(NULL,tree);
+        }
+
+      new_glnL = TIMES_Lk_Times(tree); 
+      
+      ratio += (new_alnL - cur_alnL);
+      ratio += (new_glnL - cur_glnL);
+
+      ratio = EXP(ratio);
+      alpha = MIN(1.,ratio);
+  
+      printf("\n. new_alnL: %f cur_alnL: %f new_glnL: %f cur_glnL: %f len: %d\n",
+             new_alnL,cur_alnL,
+             new_glnL,cur_glnL,
+             n_regraft_nd);
+
+      /* Always accept move */
+      if(tree->mcmc->always_yes == YES && new_glnL > UNLIKELY) alpha = 1.0;
+      
+      u = Uni();
+            
+      if(u > alpha)
+        {
+          // Reject
+          Prune_Subtree(prune,prune_daughter,&target,&residual,tree);
+          Graft_Subtree(ori_target,prune,residual,tree);
+          // Restore edge lengths
+          Restore_Br_Len(tree);
+          tree->c_lnL = cur_alnL;
+          tree->rates->c_lnL_times = cur_glnL;
+
+          printf("\n. reject");
+          /* !!!!!!!!!!!!!! */
+          new_alnL = Lk(NULL,tree); /* Not necessary. Remove once tested */
+          if(Are_Equal(new_alnL,cur_alnL,1.E-3) == NO)
+            {
+              PhyML_Printf("\n== new_alnL: %f cur_alnL: %f",new_alnL,cur_alnL);
+              Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
+            }
+        }
+      else
+        {
+          tree->mcmc->acc_move[tree->mcmc->num_move_spr]++;
+        }
+    }
+}
+  
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
 void MCMC_Complete_MCMC(t_mcmc *mcmc, t_tree *tree)
 {
   int i;
@@ -4294,6 +4522,8 @@ void MCMC_Complete_MCMC(t_mcmc *mcmc, t_tree *tree)
   mcmc->num_move_cov_rates                = mcmc->n_moves; mcmc->n_moves += (tree->mod->m4mod ? 2*tree->mod->m4mod->n_h : 1);
   mcmc->num_move_cov_switch               = mcmc->n_moves; mcmc->n_moves += 1;
   mcmc->num_move_birth_rate               = mcmc->n_moves; mcmc->n_moves += 1;
+  mcmc->num_move_spr                      = mcmc->n_moves; mcmc->n_moves += 1;
+  mcmc->num_move_death_rate               = mcmc->n_moves; mcmc->n_moves += 1;
   mcmc->num_move_updown_t_br              = mcmc->n_moves; mcmc->n_moves += 1;
   mcmc->num_move_jump_calibration         = mcmc->n_moves; mcmc->n_moves += 1;
   mcmc->num_move_geo_lambda               = mcmc->n_moves; mcmc->n_moves += 1;
@@ -4355,6 +4585,7 @@ void MCMC_Complete_MCMC(t_mcmc *mcmc, t_tree *tree)
   strcpy(mcmc->move_name[mcmc->num_move_tree_height],"tree_height");
   strcpy(mcmc->move_name[mcmc->num_move_subtree_height],"subtree_height");
   strcpy(mcmc->move_name[mcmc->num_move_kappa],"kappa");
+  strcpy(mcmc->move_name[mcmc->num_move_spr],"spr");
   strcpy(mcmc->move_name[mcmc->num_move_tree_rates],"tree_rates");
   strcpy(mcmc->move_name[mcmc->num_move_subtree_rates],"subtree_rates");
   strcpy(mcmc->move_name[mcmc->num_move_updown_nu_cr],"updown_nu_cr");
@@ -4365,6 +4596,7 @@ void MCMC_Complete_MCMC(t_mcmc *mcmc, t_tree *tree)
     strcpy(mcmc->move_name[i],"cov_rates");  
   strcpy(mcmc->move_name[mcmc->num_move_cov_switch],"cov_switch");
   strcpy(mcmc->move_name[mcmc->num_move_birth_rate],"birth_rate");
+  strcpy(mcmc->move_name[mcmc->num_move_death_rate],"death_rate");
   strcpy(mcmc->move_name[mcmc->num_move_updown_t_br],"updown_t_br");
   strcpy(mcmc->move_name[mcmc->num_move_jump_calibration],"jump_calibration");
   strcpy(mcmc->move_name[mcmc->num_move_geo_lambda],"geo_lambda");
@@ -4420,6 +4652,7 @@ void MCMC_Complete_MCMC(t_mcmc *mcmc, t_tree *tree)
   for(i=mcmc->num_move_cov_rates;i<mcmc->num_move_cov_rates+(tree->mod->m4mod ? 2*tree->mod->m4mod->n_h : 1);i++) mcmc->move_type[i] = MCMC_MOVE_SCALE_THORNE;
   mcmc->move_type[mcmc->num_move_cov_switch] = MCMC_MOVE_SCALE_THORNE;
   mcmc->move_type[mcmc->num_move_birth_rate] = MCMC_MOVE_SCALE_THORNE;
+  mcmc->move_type[mcmc->num_move_death_rate] = MCMC_MOVE_SCALE_THORNE;
   mcmc->move_type[mcmc->num_move_updown_t_br] = MCMC_MOVE_SCALE_THORNE;
   mcmc->move_type[mcmc->num_move_jump_calibration] = MCMC_MOVE_SCALE_THORNE;
   mcmc->move_type[mcmc->num_move_geo_lambda] = MCMC_MOVE_SCALE_THORNE;
@@ -4479,6 +4712,7 @@ void MCMC_Complete_MCMC(t_mcmc *mcmc, t_tree *tree)
   mcmc->move_weight[mcmc->num_move_subtree_height]   = 0.0;
   mcmc->move_weight[mcmc->num_move_nu]               = 2.0;
   mcmc->move_weight[mcmc->num_move_kappa]            = 0.5;
+  mcmc->move_weight[mcmc->num_move_spr]              = 1.0;
   mcmc->move_weight[mcmc->num_move_tree_rates]       = 1.0;
   mcmc->move_weight[mcmc->num_move_subtree_rates]    = 0.5;
   mcmc->move_weight[mcmc->num_move_updown_nu_cr]     = 0.0;
@@ -4488,6 +4722,7 @@ void MCMC_Complete_MCMC(t_mcmc *mcmc, t_tree *tree)
   for(i=mcmc->num_move_cov_rates;i<mcmc->num_move_cov_rates+(tree->mod->m4mod ? 2*tree->mod->m4mod->n_h : 1);i++) mcmc->move_weight[i] = 0.5*(1./(tree->mod->m4mod ? (phydbl)tree->mod->m4mod->n_h : 1));
   mcmc->move_weight[mcmc->num_move_cov_switch]            = 1.0;
   mcmc->move_weight[mcmc->num_move_birth_rate]            = 2.0;
+  mcmc->move_weight[mcmc->num_move_death_rate]            = 2.0;
   mcmc->move_weight[mcmc->num_move_updown_t_br]           = 1.0;
 #if defined (INVITEE)
   mcmc->move_weight[mcmc->num_move_jump_calibration]      = 0.1;
@@ -4502,6 +4737,7 @@ void MCMC_Complete_MCMC(t_mcmc *mcmc, t_tree *tree)
   mcmc->move_weight[mcmc->num_move_geo_dum]               = 1.0;
 
 # if defined (PHYREX)
+
   mcmc->move_weight[mcmc->num_move_phyrex_lbda]                  = 5.0;
   mcmc->move_weight[mcmc->num_move_phyrex_mu]                    = 8.0;
   mcmc->move_weight[mcmc->num_move_phyrex_rad]                   = 5.0;
@@ -4594,7 +4830,6 @@ void MCMC_Complete_MCMC(t_mcmc *mcmc, t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void MCMC_Initialize_Param_Val(t_mcmc *mcmc, t_tree *tree)
 {
   /* int i; */
@@ -4619,7 +4854,6 @@ void MCMC_Initialize_Param_Val(t_mcmc *mcmc, t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void MCMC_Copy_To_New_Param_Val(t_mcmc *mcmc, t_tree *tree)
 {
   mcmc->sampled_val[mcmc->num_move_nu*mcmc->sample_size+mcmc->sample_num]          = tree->rates->nu;
@@ -4627,6 +4861,7 @@ void MCMC_Copy_To_New_Param_Val(t_mcmc *mcmc, t_tree *tree)
   mcmc->sampled_val[mcmc->num_move_tree_height*mcmc->sample_size+mcmc->sample_num] = tree->rates->nd_t[tree->n_root->num];
   mcmc->sampled_val[mcmc->num_move_kappa*mcmc->sample_size+mcmc->sample_num]       = tree->mod ? tree->mod->kappa->v : -1.;
   mcmc->sampled_val[mcmc->num_move_birth_rate*mcmc->sample_size+mcmc->sample_num]  = tree->rates->birth_rate;
+  mcmc->sampled_val[mcmc->num_move_death_rate*mcmc->sample_size+mcmc->sample_num]  = tree->rates->death_rate;
 
   /* For(i,2*tree->n_otu-2) */
   /*   mcmc->sampled_val[(mcmc->num_move_br_r+i)*mcmc->sample_size+mcmc->sample_num] = tree->rates->br_r[i]; */
@@ -7918,10 +8153,8 @@ void MCMC_PHYREX_Indel_Hit_Serial(t_tree *tree)
             }
         }
 
-
       else /* Remove disk */
 
-
         {
           if(disk->ldsk == NULL || (disk->ldsk != NULL && disk->ldsk->n_next > 1)) continue;
 
@@ -8004,8 +8237,8 @@ void MCMC_PHYREX_Indel_Hit_Serial(t_tree *tree)
             }
           else
             {
-              Free_Disk(disk);
               Free_Ldisk(disk->ldsk);
+              Free_Disk(disk);
               tree->mcmc->acc_move[tree->mcmc->num_move_phyrex_indel_hit_serial]++;
             }
         }
@@ -8186,4 +8419,3 @@ void MCMC_PHYREX_Indel_Disk_Serial(t_tree *tree)
 ////////////////////////////////////////////////////////////*/
 /*////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////*/
-
diff --git a/src/mcmc.h b/src/mcmc.h
index e8baf3e..44fc4e4 100644
--- a/src/mcmc.h
+++ b/src/mcmc.h
@@ -62,7 +62,7 @@ void MCMC_Stick_Rates(t_tree *tree);
 void MCMC_Stick_Rates_Pre(t_node *a, t_node *d, t_tree *tree);
 void MCMC_Times_Global(t_tree *tree);
 void MCMC_Times_Local(t_tree *tree);
-void MCMC_One_Time(t_node *a, t_node *d, int traversal, t_tree *tree);
+void MCMC_Time_Recur(t_node *a, t_node *d, int traversal, t_tree *tree);
 void MCMC_Rates_Global(t_tree *tree);
 void MCMC_Rates_Local(t_tree *tree);
 void MCMC_Rates_Pre(t_node *a, t_node *d, t_tree *tree);
@@ -180,4 +180,7 @@ void MCMC_PHYREX_Ldsk_Multi(t_tree *tree);
 void MCMC_PHYREX_Ldsk_Given_Disk(t_tree *tree);
 void MCMC_PHYREX_Disk_Given_Ldsk(t_tree *tree);
 void MCMC_PHYREX_Ldsk_And_Disk(t_tree *tree);
+void MCMC_Death_Rate(t_tree *tree);
+void MCMC_Time_All(t_tree *tree);
+void MCMC_Prune_Regraft(t_tree *tree);
 #endif
diff --git a/src/mg.c b/src/mg.c
index ae3b8fc..a9c51c7 100644
--- a/src/mg.c
+++ b/src/mg.c
@@ -27,2823 +27,3 @@ the GNU public licence.  See http://www.opensource.org for details.
 //////////////////////////////////////////////////////////////
 
 
-int PART_main(int argc, char **argv)
-{
-  option *io;
-  char *s_tree;
-  FILE *fp_phyml_tree,*fp_phyml_stats,*fp_phyml_lk;
-  int part;
-  time_t t_beg,t_end;
-  div_t hour,min;
-  int r_seed;
-  int i;
-
-  fflush(NULL);
-  io = (option *)Get_Input(argc,argv);
-  r_seed = (io->r_seed < 0)?(time(NULL)):(io->r_seed);
-  srand(r_seed);
-  fp_phyml_stats = Openfile(io->out_stats_file,io->out_stats_file_open_mode);
-  PhyML_Fprintf(fp_phyml_stats,"\n- PHYML %s -\n\n", VERSION);
-  fp_phyml_tree = Openfile(io->out_tree_file,io->out_tree_file_open_mode);
-  fp_phyml_lk = fopen(io->out_lk_file,"w");
-
-  time(&t_beg);
-
-  if(io->multigene)
-    {
-      align ***data;
-      calign **cdata;
-      t_mod **mod;
-      matrix **mat;
-      t_treelist *treelist;
-      supert_tree *st;
-
-      data  = (align ***)  mCalloc(io->n_part,sizeof(align **));
-      cdata = (calign **)mCalloc(io->n_part,sizeof(calign *));
-      mod   = (t_mod **) mCalloc(io->n_part,sizeof(t_mod *));
-      mat   = (matrix **)mCalloc(io->n_part,sizeof(matrix *));
-
-      /* Read the sequences (for each partition) */
-      For(part,io->n_part)
-	{
-	  Make_Model_Complete(io->st->optionlist[part]->mod); /* Complete model for each data part */
-	  data[part] = Get_Seq(io->st->optionlist[part]);
-	  Make_Model_Complete(io->st->optionlist[part]->mod);
-	  Set_Model_Name(io->st->optionlist[part]->mod);
-	  mod[part]  = io->st->optionlist[part]->mod;
-
-	  PhyML_Printf("\n. Data part [#%d]\n",part+1);
-	  PhyML_Printf("\n. Compressing sequences...\n");
-	  cdata[part] = Compact_Data(data[part],io->st->optionlist[part]);
-	  fclose(io->st->optionlist[part]->fp_in_align);
-	  Free_Seq(data[part],cdata[part]->n_otu);
-	  Init_Model(cdata[part],mod[part],io->st->optionlist[part]);
-	  Check_Ambiguities(cdata[part],
-			    io->st->optionlist[part]->mod->io->datatype,
-			    io->st->optionlist[part]->mod->io->state_len);
-	}
-
-      PART_Make_Supert_tree_Full(io->st,io,cdata);
-      st = io->st;
-      treelist = st->treelist;
-      Fill_Dir_Table(st->tree);
-      Update_Dirs(st->tree);
-
-      For(part,io->n_part)
-	{
-	  st->curr_cdata = cdata[part];
-	  if(!PART_Get_Species_Found_In_St(st,cdata[part])) break;
-	  treelist->tree[part] = Make_Tree_From_Scratch(st->tree->n_otu,NULL);
-	  Copy_Tree_Topology_With_Labels(st->tree,treelist->tree[part]);
- 	  treelist->tree[part]->num_curr_branch_available = 0;
-	  Connect_Edges_To_Nodes_Recur(treelist->tree[part]->a_nodes[0],
-				       treelist->tree[part]->a_nodes[0]->v[0],
-				       treelist->tree[part]);
-	  PART_Prune_St_Topo(treelist->tree[part],cdata[part],st);
-
-	  if(treelist->tree[part]->n_otu != cdata[part]->n_otu)
-	    {
-	      PhyML_Printf("\n. Problem with sequence file '%s'\n",io->st->optionlist[part]->in_align_file);
-	      PhyML_Printf("\n. # taxa found in supertree restricted to '%s' taxa = %d\n",
-		     io->st->optionlist[part]->in_align_file,
-		     treelist->tree[part]->n_otu);
-	      PhyML_Printf("\n. # sequences in '%s' = %d\n",
-		     io->st->optionlist[part]->in_align_file,
-		     cdata[part]->n_otu);
-	      Exit("\n");
-	    }
-
-	  treelist->tree[part]->dp         = part;
-	  treelist->tree[part]->n_otu      = cdata[part]->n_otu;
-	  treelist->tree[part]->mod        = mod[part];
-	  treelist->tree[part]->io         = io->st->optionlist[part];
-	  treelist->tree[part]->data       = cdata[part];
-	  treelist->tree[part]->n_pattern  = treelist->tree[part]->data->crunch_len/
-	                                     treelist->tree[part]->io->state_len;
-
-          Set_Both_Sides(YES,treelist->tree[part]);
-	  Connect_CSeqs_To_Nodes(cdata[part],io->st->optionlist[part],treelist->tree[part]);
-	  Fill_Dir_Table(treelist->tree[part]);
-	  Update_Dirs(treelist->tree[part]);
-	  Make_Tree_4_Lk(treelist->tree[part],cdata[part],cdata[part]->init_len);
-	  Make_Tree_4_Pars(treelist->tree[part],cdata[part],cdata[part]->init_len);
-	  treelist->tree[part]->triplet_struct = Make_Triplet_Struct(treelist->tree[part]->mod);
-          Init_Triplet_Struct(treelist->tree[part]->triplet_struct);
-	}
-
-      if(part != io->n_part)
-	{
-	  PhyML_Printf("\n. Sequence data part found in '%s' has one or more taxa not found in the '%s' tree file\n",
-		 io->st->optionlist[part]->in_align_file,
-		 io->in_tree_file);
-	  Exit("\n");
-	}
-
-      PART_Check_Extra_Taxa(st);
-	
-      st->tree->c_lnL = .0;
-      For(part,io->n_part)
-	{
-	  Lk(NULL,treelist->tree[part]);
-/* 	  Get_List_Of_Reachable_Tips(treelist->tree[part]); */
-	  PART_Match_St_Nodes_In_Gt(treelist->tree[part],st);
-	  PART_Match_St_Edges_In_Gt(treelist->tree[part],st);
-	  PART_Map_St_Nodes_In_Gt(treelist->tree[part],st);
-	  PART_Map_St_Edges_In_Gt(treelist->tree[part],st);
-	  PART_Map_Gt_Edges_In_St(treelist->tree[part],st);
-	  st->tree->c_lnL += treelist->tree[part]->c_lnL;
-	}
-
-      PART_Initialise_Bl_Partition(st);
-      PART_Set_Bl(st->bl,st);
-
-      time(&(st->tree->t_beg));
-      time(&(st->tree->t_current));
-      PhyML_Printf("\n. (%5d sec) [00] [%10.2f] [%5d]\n",
-	     (int)(st->tree->t_current-st->tree->t_beg),
-	     PART_Lk(st),
-	     PART_Pars(st));
-
-
-      int n_iter=0;
-      do
-	{
-	  PART_Optimize_Br_Len_Serie(st->tree->a_nodes[0],
-				   st->tree->a_nodes[0]->v[0],
-				   st->tree->a_nodes[0]->b[0],
-				   st);
-
-          Set_Both_Sides(YES,st->tree);
-	  PART_Lk(st);
-	  PhyML_Printf("\n. %f",st->tree->c_lnL);
-/* 	  For(part,st->n_part) PhyML_Printf("\n. %s",Write_Tree(st->treelist->tree[part],NO)); */
-	  n_iter++;
-	}while(n_iter < 5);
-/*       Exit("\n"); */
-
-
-/*       PART_Lk(st); */
-/*       PhyML_Printf("\n> %f",st->tree->c_lnL); */
-/*       For(i,2*st->tree->n_otu-3) */
-/* 	{ */
-/* 	  if((!st->tree->a_edges[i]->left->tax) && (!st->tree->a_edges[i]->rght->tax)) */
-/* 	    { */
-/* 	      PART_NNI(st->tree->a_edges[i],st); */
-/* 	    } */
-/* 	} */
-
-      
-/*       if(io->mod->s_opt->topo_search == NNI_MOVE) */
-      PART_Simu(st);
-/*       else */
-/*       PART_Speed_Spr(st); */
-
-
-      time(&t_end);
-
-      hour = div(t_end-t_beg,3600);
-      min  = div(t_end-t_beg,60  );
-
-      min.quot -= hour.quot*60;
-
-
-      PhyML_Fprintf(fp_phyml_stats,"\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\n");
-      PhyML_Fprintf(fp_phyml_stats,"\n. Number of partitions = %d\n\n",st->n_part);
-      PhyML_Fprintf(fp_phyml_stats,"\n. Full data set -- lnL = %f\n\n",st->tree->c_lnL);
-      PhyML_Fprintf(fp_phyml_stats,"\n. Tree search algorithm : %s\n\n",(io->mod->s_opt->topo_search == NNI_MOVE)?("NNIs"):("SPRs"));
-      PhyML_Fprintf(fp_phyml_stats,"\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\n\n");
-      For(part,io->n_part)
-	{
-	  Print_Fp_Out(fp_phyml_stats,t_beg,t_end,st->treelist->tree[part],
-		       io->st->optionlist[part],1,1,YES);
-	}
-
-
-      PhyML_Printf("\n\n. Time used %dh%dm%ds\n", hour.quot,min.quot,(int)(t_end-t_beg)%60);
-      PhyML_Printf("\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\n");
-
-      For(i,2*st->tree->n_otu-3) st->tree->a_edges[i]->l->v = 0.1;
-      s_tree = Write_Tree(st->tree,NO);
-      PhyML_Fprintf(fp_phyml_tree,"Supertree\n");
-      PhyML_Fprintf(fp_phyml_tree,"%s\n",s_tree);
-      Free(s_tree);
-      For(part,st->n_part)
-	{
-	  PhyML_Fprintf(fp_phyml_tree,"Gene tree number %d\n",part+1);
-	  s_tree = Write_Tree(st->treelist->tree[part],NO);
-	  PhyML_Fprintf(fp_phyml_tree,"%s\n",s_tree);
-	  Free(s_tree);
-	}
-
-
-      For(part,st->n_part)
-	{
-	  if(io->mod->s_opt->topo_search == SPR_MOVE) Free_Spr_List(treelist->tree[part]);
-	  Free_Tree_Lk(treelist->tree[part]);
-	  Free_Tree_Pars(treelist->tree[part]);
-	  Free_Triplet(treelist->tree[part]->triplet_struct);
-	  Free_Tree(treelist->tree[part]);
-	  Free_Cseq(cdata[part]);
-	  Free_Model(mod[part]);
-	  Free_Input(io->st->optionlist[part]);
-
-	}
-
-      if(io->mod->s_opt->topo_search == SPR_MOVE) Free_Spr_List(st->tree);
-      Free(mat);
-      Free(mod);
-      Free(data);
-      Free(cdata);
-      Free(treelist->tree);
-      Free(treelist);
-      Free_St(st);
-    }
-
-
-  if(io->fp_in_align ) fclose(io->fp_in_align);
-  if(io->fp_in_tree) fclose(io->fp_in_tree);
-
-
-  Free_Model(io->mod);
-  Free_Input(io);
-
-  fclose(fp_phyml_lk);
-  fclose(fp_phyml_tree);
-  fclose(fp_phyml_stats);
-
-
-  return 0;
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-void PART_Print_Nodes(t_node *a, t_node *d, supert_tree *st)
-{
-  int i;
-  PhyML_Printf(">>>>>>>>>>>>>>>>>>>>\n");
-  PhyML_Printf("num t_node = %d\n",d->num);
-  if(d->tax) PhyML_Printf("name='%s'\n",d->name);
-  else
-    {
-      PhyML_Printf("n_of_reachable_tips : \n");
-      For(i,3)
-	{
-/* 	  PhyML_Printf("dir%d=%d; ",i,st->n_of_reachable_tips[st->num_data_of_interest][d->num][i]); */
-/* 	  For(j,st->n_of_reachable_tips[st->num_data_of_interest][d->num][i]) */
-/* 	    { */
-/* 	      PhyML_Printf("%s ", */
-/* 		     st->list_of_reachable_tips[st->num_data_of_interest][d->num][i][j]->name); */
-/* 	    } */
-	  
-	  PhyML_Printf("\n");
-	}
-    }
-  PhyML_Printf("<<<<<<<<<<<<<<<<<<<\n\n");
-  if(d->tax) return;
-  else
-    {
-      For(i,3) if(d->v[i] != a) PART_Print_Nodes(d,d->v[i],st);
-    }
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-supert_tree *PART_Make_Supert_tree_Light(option *input)
-{
-  supert_tree *st;
-
-  st = (supert_tree *)mCalloc(1,sizeof(supert_tree));
-  st->optionlist = (option **)mCalloc(input->n_part,sizeof(option *));
-  st->bl_partition = (int *)mCalloc(input->n_part,sizeof(int ));
-  return st;
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-void PART_Make_Supert_tree_Full(supert_tree *st, option *io, calign **data)
-{
-  int i,j,k;
-
-  if(io->in_tree == 2)
-    {
-      PhyML_Printf("\n. Reading user tree...\n");
-      rewind(io->fp_in_tree);
-      
-      st->tree = Read_Tree_File_Phylip(io->fp_in_tree);
-      
-      if(!st->tree->has_branch_lengths)
-	{
-	  PhyML_Printf("\n. Branch lengths are all set to 0.1...\n");
-	  For(i,2*st->tree->n_otu-3) st->tree->a_edges[i]->l->v = 0.1;
-	}
-    }
-  else
-    {
-      Warn_And_Exit("\n. A user-defined input tree is needed\n");
-    }
-
-  st->tree->io      = io;
-  st->treelist      = (t_treelist *)Make_Treelist(io->n_part);
-  st->n_part          = io->n_part;
-  st->tree->mod     = io->mod;
-  st->lock_br_len   = 0;
-
-  st->map_st_node_in_gt = (t_node *****)mCalloc(st->n_part,sizeof(t_node ****));
-  For(i,st->n_part) 
-    {
-      st->map_st_node_in_gt[i] = (t_node ****)mCalloc(2*st->tree->n_otu-2,sizeof(t_node ***));
-      For(j,2*st->tree->n_otu-2) 
-	{
-	  st->map_st_node_in_gt[i][j] = (t_node ***)mCalloc(3,sizeof(t_node **));
-	  For(k,3) st->map_st_node_in_gt[i][j][k] = (t_node **)mCalloc(2,sizeof(t_node *));
-	}
-    }
-
-  st->map_st_edge_in_gt = (t_edge ***)mCalloc(st->n_part,sizeof(t_edge **));
-  For(i,st->n_part) st->map_st_edge_in_gt[i] = (t_edge **)mCalloc(2*st->tree->n_otu-3,sizeof(t_edge *));
-
-  st->map_gt_edge_in_st = (t_edge ****)mCalloc(st->n_part,sizeof(t_edge ***));
-  For(i,st->n_part)
-    {
-      st->map_gt_edge_in_st[i] = (t_edge ***)mCalloc(2*st->tree->n_otu-3,sizeof(t_edge **));
-      For(j,2*st->tree->n_otu-3) st->map_gt_edge_in_st[i][j] = (t_edge **)mCalloc(2*st->tree->n_otu-3,sizeof(t_edge *));
-    }
-
-  st->size_map_gt_edge_in_st = (int **)mCalloc(st->n_part,sizeof(int *));
-  For(i,st->n_part) st->size_map_gt_edge_in_st[i] = (int *)mCalloc(2*st->tree->n_otu-3,sizeof(int));
-
-
-  st->match_st_edge_in_gt = (t_edge ***)mCalloc(st->n_part,sizeof(t_edge **));
-  For(i,st->n_part) st->match_st_edge_in_gt[i] = (t_edge **)mCalloc(2*st->tree->n_otu-3,sizeof(t_edge *));
-
-  st->match_gt_edge_in_st = (t_edge ***)mCalloc(st->n_part,sizeof(t_edge **));
-  For(i,st->n_part) st->match_gt_edge_in_st[i] = (t_edge **)mCalloc(2*st->tree->n_otu-3,sizeof(t_edge *));
-
-  st->bl = (phydbl **)mCalloc(st->n_part,sizeof(phydbl *));
-  For(i,st->n_part) st->bl[i] = (phydbl *)mCalloc(2*st->tree->n_otu-3,sizeof(phydbl));
-
-  st->bl_cpy = (phydbl **)mCalloc(st->n_part,sizeof(phydbl *));
-  For(i,st->n_part) st->bl_cpy[i] = (phydbl *)mCalloc(2*st->tree->n_otu-3,sizeof(phydbl));
-
-  st->bl0 = (phydbl **)mCalloc(st->n_part,sizeof(phydbl *));
-  For(i,st->n_part) st->bl0[i] = (phydbl *)mCalloc(2*st->tree->n_otu-3,sizeof(phydbl));
-
-  st->bl1 = (phydbl **)mCalloc(st->n_part,sizeof(phydbl *));
-  For(i,st->n_part) st->bl1[i] = (phydbl *)mCalloc(2*st->tree->n_otu-3,sizeof(phydbl));
-
-  st->bl2 = (phydbl **)mCalloc(st->n_part,sizeof(phydbl *));
-  For(i,st->n_part) st->bl2[i] = (phydbl *)mCalloc(2*st->tree->n_otu-3,sizeof(phydbl));
-
-  st->s_mod = (t_mod **)mCalloc(st->n_part,sizeof(t_mod *));
-
-  For(i,2*st->tree->n_otu-3) Make_Edge_NNI(st->tree->a_edges[i]);
-
-  st->match_st_node_in_gt = (t_node ***)mCalloc(io->n_part,sizeof(t_node **));
-  For(i,io->n_part) st->match_st_node_in_gt[i] = (t_node **)mCalloc(2*st->tree->n_otu-2,sizeof(t_node *));
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-void PART_Prune_St_Topo(t_tree *tree, calign *data, supert_tree *st)
-{
-  int i,j,not_found;
-  int curr_ext_node, curr_int_node, curr_br, n_pruned_nodes;;
-  t_node **pruned_nodes;
-  t_edge **residual_edges;
-
-  pruned_nodes   = (t_node **)mCalloc(st->tree->n_otu,sizeof(t_node *));
-  residual_edges = (t_edge **)mCalloc(st->tree->n_otu,sizeof(t_edge *));
-
-  n_pruned_nodes = 0;
-  For(i,st->tree->n_otu)
-    {
-      For(j,data->n_otu)
-	{
-	  if(!strcmp(data->c_seq[j]->name,st->tree->a_nodes[i]->name))
-	    break;
-	}
-
-      not_found = 1;
-      if(j == data->n_otu)
-	{
-	  For(j,tree->n_otu)
-	    {
-	      if(!strcmp(tree->a_nodes[j]->name,st->tree->a_nodes[i]->name))
-		{
-		  Prune_Subtree(tree->a_nodes[j]->v[0],
-				tree->a_nodes[j],
-				NULL,&(residual_edges[n_pruned_nodes]),
-				tree);
-
-		  pruned_nodes[n_pruned_nodes] = tree->a_nodes[j];
-		  n_pruned_nodes++;
-		  not_found = 0;
-		  break;
-		}	      
-	    }
-
-
-	  if(not_found)	    
-	    {
-	      PhyML_Printf("\n. Taxon '%s'",st->tree->a_nodes[i]->name);
-	      PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__);
-	      Warn_And_Exit("");
-	    }
-	}
-    }
-
-  Free(tree->t_dir);
-
-  tree->n_otu -= n_pruned_nodes;
-
-  curr_ext_node = 0;
-  curr_int_node = tree->n_otu;  
-  curr_br = 0;
-  For(i,st->tree->n_otu)
-    {
-      For(j,n_pruned_nodes)
-	{
-	  if(!strcmp(pruned_nodes[j]->name,st->tree->a_nodes[i]->name))
-	    break;
-	}
-      if(j == n_pruned_nodes) /* That t_node still belongs to the tree */
-	{
-	  Reassign_Node_Nums(tree->a_nodes[i],tree->a_nodes[i]->v[0], 
-			     &curr_ext_node, &curr_int_node,tree);
-	  break;
-	}
-    }
-  
-  Reassign_Edge_Nums(tree->a_nodes[0],tree->a_nodes[0]->v[0],&curr_br,tree);
-
-  tree->t_dir = (short int *)mCalloc((2*tree->n_otu-2)*(2*tree->n_otu-2),sizeof(short int));
-
-  For(i,n_pruned_nodes) 
-    {
-      Free_Edge(residual_edges[i]);
-      Free_Edge(pruned_nodes[i]->b[0]);
-      Free_Node(pruned_nodes[i]->v[0]);
-      Free_Node(pruned_nodes[i]);
-    }
-
-  Free(pruned_nodes);
-  Free(residual_edges);
-
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-void PART_Match_St_Nodes_In_Gt(t_tree *gt, supert_tree *st)
-{
-  int i,j;
-
-  For(i,2*st->tree->n_otu-2) st->match_st_node_in_gt[gt->dp][i] = NULL; /* don't forget that step ! */
-
-  /* Map tips */
-  For(i,st->tree->n_otu)
-    {
-      For(j,gt->n_otu)
-	{
-	  if(!strcmp(st->tree->a_nodes[i]->name,gt->a_nodes[j]->name))
-	    {
-	      st->match_st_node_in_gt[gt->dp][st->tree->a_nodes[i]->num] = gt->a_nodes[j];
-	      break;
-	    }
-	}
-    }
-
-#ifdef DEBUG
-  /* Checking that the results are correct so far */
-  int n_matches;
-  n_matches = 0;
-  For(i,2*st->tree->n_otu-2)
-    if(st->match_st_node_in_gt[gt->dp][i])
-      n_matches++;
-
-  if(n_matches != gt->n_otu)
-    {
-      PhyML_Printf("\n");
-      PhyML_Printf("\n. n_matches = %d 2*gt->n_otu-2 = %d\n",n_matches,2*gt->n_otu-2);
-      PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__);
-      Warn_And_Exit("");
-    }
-#endif
-
-
-  /* Map internal nodes */
-  For(i,st->tree->n_otu)
-    {
-      if(st->match_st_node_in_gt[gt->dp][st->tree->a_nodes[i]->num])
-	{
-	  PART_Match_St_Nodes_In_Gt_Recurr(st->match_st_node_in_gt[gt->dp][st->tree->a_nodes[i]->num],
-					 st->match_st_node_in_gt[gt->dp][st->tree->a_nodes[i]->num]->v[0],
-					 st->tree->a_nodes[i],
-					 st->tree->a_nodes[i]->v[0],
-					 gt,
-					 st);
-	  break;
-	}
-    }
-  
-
-
-#ifdef DEBUG
-  /* Checking that the results are correct */
-  n_matches = 0;
-  For(i,2*st->tree->n_otu-2) 
-    if(st->match_st_node_in_gt[gt->dp][st->tree->a_nodes[i]->num])
-	n_matches++;
-
-  if(n_matches != 2*gt->n_otu-2)
-    {
-      int j;
-      PhyML_Printf("\n");
-      PhyML_Printf("\n. n_matches = %d 2*gt->n_otu-2 = %d\n",n_matches,2*gt->n_otu-2);
-      For(j,2*gt->n_otu-2)
-	{
-	  For(i,2*st->tree->n_otu-2) 
-	    if(st->match_st_node_in_gt[gt->dp][i] == gt->a_nodes[j])
-	      break;
-
- 	  if(i == 2*st->tree->n_otu-2)
-	    {
-	      PhyML_Printf("\n. Gt %3d t_node %3d (%3d %3d %3d) (%s %s %s) (%f %f %f) does not match\n",
-		     gt->dp,
-		     gt->a_nodes[j]->num,
-		     gt->a_nodes[j]->v[0] ? gt->a_nodes[j]->v[0]->num : -1,
-		     gt->a_nodes[j]->v[1] ? gt->a_nodes[j]->v[1]->num : -1,
-		     gt->a_nodes[j]->v[2] ? gt->a_nodes[j]->v[2]->num : -1,
-		     gt->a_nodes[j]->v[0]->tax ? gt->a_nodes[j]->v[0]->name : NULL,
-		     gt->a_nodes[j]->v[1]->tax ? gt->a_nodes[j]->v[1]->name : NULL,
-		     gt->a_nodes[j]->v[2]->tax ? gt->a_nodes[j]->v[2]->name : NULL,
-		     gt->a_nodes[j]->v[0] ? gt->a_nodes[j]->b[0]->l->v : -1.,
-		     gt->a_nodes[j]->v[1] ? gt->a_nodes[j]->b[1]->l->v : -1.,
-		     gt->a_nodes[j]->v[2] ? gt->a_nodes[j]->b[2]->l->v : -1.);
-	    }
-	}
-
-      PhyML_Printf("oooooooo\n");
-      Print_Node(st->tree->a_nodes[0],
-		 st->tree->a_nodes[0]->v[0],
-		 st->tree);
-      PhyML_Printf(">>>>>>>\n");
-      For(i,st->n_part)
-	{
-	  Print_Node(st->treelist->tree[i]->a_nodes[0],
-		     st->treelist->tree[i]->a_nodes[0]->v[0],
-		     st->treelist->tree[i]);
-	  PhyML_Printf("<<<<<<<\n");
-	}
-      PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__);
-      Warn_And_Exit("");
-    }
-#endif
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-void PART_Match_St_Nodes_In_Gt_Recurr(t_node *a_gt, t_node *d_gt, t_node *a_st, t_node *d_st, t_tree *gt, supert_tree *st)
-{
-  int i,j,k;
-  int *score_d_st;
-
-
-  if((d_gt->tax) || (d_st->tax)) return;
-  else
-    {
-      score_d_st = (int *)mCalloc(3,sizeof(int));
-      
-      /* Might be wrong. Check function Match_Nodes_In_Small_Tree */
-      For(i,3)
-	{
-	  For(j,3)
-	    {
-	      For(k,d_st->bip_size[j])
-		{
-		  if(!strcmp(d_gt->bip_node[i][0]->name,d_st->bip_node[j][k]->name))
-		    {
-		      score_d_st[j] += 1;
-		      break;
-		    }
-		}
-	    }
-	}
-
-
-      if((score_d_st[0] == 2) && (score_d_st[1] == 2) && (score_d_st[2] == 2))
-	{
-	  st->match_st_node_in_gt[gt->dp][d_st->num] = d_gt;
-
-	  For(i,3)
-	    {
-	      if(d_gt->v[i] != a_gt)
-		{
-		  For(j,3)
-		    {		      
-
-		      if(score_d_st[j] != 3)
-			{
-			  PART_Match_St_Nodes_In_Gt_Recurr(d_gt,d_gt->v[i],d_st,d_st->v[j],gt,st);
-			  break;
-			}
-
-/* 		      For(k,d_st->n_of_reachable_tips[j]) */
-/* 			if(!strcmp(d_gt->list_of_reachable_tips[i][0]->name, */
-/* 				   d_st->list_of_reachable_tips[j][k]->name)) */
-/* 			  { */
-/* 			    PART_Match_St_Nodes_In_Gt_Recurr(d_gt,d_gt->v[i],d_st,d_st->v[j],gt,st); */
-/* 			    break; */
-/* 			  } */
-/* 		      if(k != d_st->n_of_reachable_tips[j]) break; */
-		    }
-		}
-	    }
-	}
-      else
-	{
-	  For(i,3)
-	    if(d_st->v[i] != a_st)
-	      PART_Match_St_Nodes_In_Gt_Recurr(a_gt,d_gt,d_st,d_st->v[i],gt,st);
-	}
-      Free(score_d_st);	
-    }
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-void PART_Match_St_Edges_In_Gt(t_tree *gt, supert_tree *st)
-{
-  int i;
-
-  For(i,2*st->tree->n_otu-3) 
-    {
-      st->match_st_edge_in_gt[gt->dp][i] = NULL; 
-      st->match_gt_edge_in_st[gt->dp][i] = NULL;
-    }
-
-  For(i,st->tree->n_otu) 
-    if(st->match_st_node_in_gt[gt->dp][i])
-      {
-	PART_Match_St_Edges_In_Gt_Recurr(st->match_st_node_in_gt[gt->dp][i],
-				       st->match_st_node_in_gt[gt->dp][i]->v[0],
-				       st->tree->a_nodes[i],
-				       st->tree->a_nodes[i]->v[0],
-				       gt,st);
-	break;
-      }
-
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-void PART_Match_St_Edges_In_Gt_Recurr(t_node *a_gt, t_node *d_gt, t_node *a_st, t_node *d_st, t_tree *gt, supert_tree *st)
-{
-  t_edge *b_gt, *b_st;
-  int i,j;
-
-  b_gt = b_st = NULL;
-
-  if((st->match_st_node_in_gt[gt->dp][a_st->num] == a_gt) &&
-     (st->match_st_node_in_gt[gt->dp][d_st->num] == d_gt))
-    {
-      For(i,3) if((a_st->v[i]) && (a_st->v[i] == d_st)) {b_st = a_st->b[i]; break;}
-      For(i,3) if((a_gt->v[i]) && (a_gt->v[i] == d_gt)) {b_gt = a_gt->b[i]; break;}
-
-      st->match_st_edge_in_gt[gt->dp][b_st->num] = b_gt;
-      st->match_gt_edge_in_st[gt->dp][b_gt->num] = b_st;
-    }
-
-
-  if(!d_gt)
-    {
-      PhyML_Printf("\n");
-      PhyML_Printf("\n. a_gt->num = %d\n",a_gt->num);
-      PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__);
-      Warn_And_Exit("");
-    }
-
-  if(d_gt->tax || d_st->tax) return;
-  else
-    {
-      if(st->match_st_node_in_gt[gt->dp][d_st->num] == d_gt)
-	{
-	  For(i,3)
-	    {
-	      if(d_gt->v[i] != a_gt)
-		{
-		  For(j,3)
-		    {
-/* 		      For(k,d_st->n_of_reachable_tips[j]) */
-/* 			if(!strcmp(d_gt->list_of_reachable_tips[i][0]->name,d_st->list_of_reachable_tips[j][k]->name)) */
-			  {
-			    PART_Match_St_Edges_In_Gt_Recurr(d_gt,d_gt->v[i],d_st,d_st->v[j],gt,st);
-			    break;
-			  }
-/* 		      if(k != d_st->n_of_reachable_tips[j]) break; */
-		    }
-		}
-	    }
-	}
-      else
-	{
-	  For(i,3)
-	    if(d_st->v[i] != a_st)
-	      PART_Match_St_Edges_In_Gt_Recurr(a_gt,d_gt,d_st,d_st->v[i],gt,st);
-	}
-    }
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-void PART_Simu(supert_tree *st)
-{
-  int i,j,step,n_without_swap,it_lim_without_swap;
-  t_edge **sorted_b,*st_b,**tested_b;
-  int n_neg,n_tested,each;
-  phydbl lambda,old_loglk;
-
-  sorted_b = (t_edge **)mCalloc(st->tree->n_otu-3,sizeof(t_edge *));
-  tested_b = (t_edge **)mCalloc(st->tree->n_otu-3,sizeof(t_edge *));
-
-  For(i,st->n_part) Update_Dirs(st->treelist->tree[i]);
-  Update_Dirs(st->tree);
-
-  each                = 4;
-  step                = 0;
-  lambda              = .75;
-  n_tested            = 0;
-  n_without_swap      = 0;
-  old_loglk           = UNLIKELY; 
-  it_lim_without_swap = 2;
-  st_b                = NULL; 
-  do
-    {
-      For(i,st->n_part) Check_Dirs(st->treelist->tree[i]);
-
-      ++step;     
-      each--;
-
-/*       PART_Print_Bl(st); */
-
-      /* Compute the likelihood of the supertreee */
-      st->tree->c_lnL  = PART_Lk(st);
-      st->tree->c_pars = PART_Pars(st);
-/*       For(i,st->n_part) PhyML_Printf("\n. %s",Write_Tree(st->treelist->tree[i],NO)); */
-/*       PhyML_Printf("\n"); */
-
-      time(&(st->tree->t_current));
-      PhyML_Printf("\n. (%5d sec) [tot lnL=%15.5f] [# swaps=%3d]",
-	     (int)(st->tree->t_current-st->tree->t_beg),
-	     st->tree->c_lnL,n_tested);
-/*       For(i,st->n_part) PhyML_Printf("\n[gt %3d lnL=%15.5f]",i,st->treelist->tree[i]->c_lnL); */
-      
-      if((FABS(old_loglk-st->tree->c_lnL) < st->tree->mod->s_opt->min_diff_lk_global) || 
-	 (n_without_swap > it_lim_without_swap)) break;
-
-      if(st->tree->c_lnL < old_loglk)
-	{
-	  PhyML_Printf("\n. Moving backward (topology + branch lengths) \n");
-	  
-	  if(!PART_Mov_Backward_Topo_Bl(st,old_loglk,tested_b,n_tested))
-	    Warn_And_Exit("\n. Err: mov_back failed\n");
-
-	  if(!st->tree->n_swap) n_neg = 0;
-	    
-	  PART_Record_Br_Len(st);
-	  For(i,st->n_part) Optimiz_All_Free_Param(st->treelist->tree[i],0);
-	}
-      else 
-	{
-	  if(!each)
-	    {
-	      each = 4;
-	      /* Markov model parameters are free to vary across data partitions */
-	      For(i,st->n_part) Optimiz_All_Free_Param(st->treelist->tree[i],0);	      
-	      For(i,st->n_part) Set_Both_Sides(YES,st->treelist->tree[i]);
-	      st->tree->c_lnL  = PART_Lk(st);
-	      st->tree->c_pars = PART_Pars(st);
-	    }
-	  
-	  old_loglk = st->tree->c_lnL;
-	  
-
-	  For(i,2*st->tree->n_otu-3) Init_NNI(st->tree->a_edges[i]->nni);
-
-	  /* Test NNIs */
-	  For(i,2*st->tree->n_otu-3)
-	    {
-	      st_b = st->tree->a_edges[i];
-	      if((!st_b->left->tax) && (!st_b->rght->tax)) PART_NNI(st_b,st);
-	    }
-	  
-	  /* Optimise external branch lengths */
-	  For(i,2*st->tree->n_otu-3)
-	    {
-	      st_b = st->tree->a_edges[i];
-	      if((st_b->left->tax) || (st_b->rght->tax))
-		{
-		  PART_Record_Br_Len(st);
-		  PART_Br_Len_Brent(st_b,0,st);
-		  For(j,st->n_part) st->bl0[st->bl_partition[j]][st_b->num] = st->bl[st->bl_partition[j]][st_b->num];
-		  st_b->nni->score     = .0;
-		  st_b->nni->best_conf =  0;
-		  PART_Restore_Br_Len(st);
-		  PART_Lk_At_Given_Edge(st_b,st);
-		}
-	    }
-
-	  /* Select and sort swaps */
-	  n_neg = 0;
-	  Select_Edges_To_Swap(st->tree,sorted_b,&n_neg);
-	  Sort_Edges_NNI_Score(st->tree,sorted_b,n_neg);	  
-
-	  n_tested = 0;
-	  For(i,(int)CEIL((phydbl)n_neg*(lambda)))
-	    tested_b[n_tested++] = sorted_b[i];
-
-	  if(n_tested > 0) n_without_swap = 0;
-	  else             n_without_swap++;
-
-	  PART_Record_Br_Len(st);
-	  
-	  /* Apply swaps */
-	  PART_Make_N_Swap(tested_b,0,n_tested,st);
-
-	  /* Update branch lengths (all edges first and then swaped edges) */
-	  PART_Update_Bl(lambda,st);
-	  PART_Update_Bl_Swaped(tested_b,n_tested,st);
-
-	    
-	}
-    }
-  while(1);
-  
-  PhyML_Printf("\n\n. End of PART_Simu \n");
-  Free(sorted_b);
-  Free(tested_b);
-
-  if((n_without_swap > it_lim_without_swap))
-    {
-      PhyML_Printf("\n. Last optimization step...\n");
-      For(i,st->n_part) Round_Optimize(st->treelist->tree[i],st->treelist->tree[i]->data,ROUND_MAX);
-      st->tree->c_lnL = PART_Lk(st);
-      PART_Simu(st);
-    }
-}
-
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-int PART_Mov_Backward_Topo_Bl(supert_tree *st, phydbl lk_old, t_edge **tested_b, int n_tested)
-{
-  int i,j,step,beg,end;
-  t_edge *st_b;
-  phydbl **l_init;
-  int dim;
-
-  l_init = (phydbl **)mCalloc(st->n_part,sizeof(phydbl *));
-  For(i,st->n_part) l_init[i] = (phydbl *)mCalloc(2*st->tree->n_otu-3,sizeof(phydbl ));
-
-  For(i,2*st->tree->n_otu-3) For(j,st->n_part) l_init[st->bl_partition[j]][i] = st->bl[st->bl_partition[j]][i];
-
-  step = 2;
-  do
-    {
-      For(i,2*st->tree->n_otu-3)
-	{
-	  For(j,st->n_part)
-	    {
-	      st->bl[st->bl_partition[j]][i] = st->bl_cpy[st->bl_partition[j]][i] + 
-		(1./step) * (l_init[st->bl_partition[j]][i] - st->bl_cpy[st->bl_partition[j]][i]);
-/* 	      st->bl[st->bl_partition[j]][i] = st->bl_cpy[st->bl_partition[j]][i]; */
-	    }
-	}
-      
-      beg = (int)FLOOR((phydbl)n_tested/(step-1));
-      end = 0;
-      st_b = NULL;
-      dim = 2*st->tree->n_otu-2;
-
-      for(i=beg-1;i>=end;i--)
-	{
-	  st_b = tested_b[i];
-
-	  PART_Swap(st_b->nni->swap_node_v2->v[st->tree->t_dir[st_b->nni->swap_node_v2->num*dim+st_b->nni->swap_node_v1->num]],
-		  st_b->nni->swap_node_v2,
-		  st_b->nni->swap_node_v3,
-		  st_b->nni->swap_node_v3->v[st->tree->t_dir[st_b->nni->swap_node_v3->num*dim+st_b->nni->swap_node_v4->num]],
-		  st);
-
-	  Swap(st_b->nni->swap_node_v2->v[st->tree->t_dir[st_b->nni->swap_node_v2->num*dim+st_b->nni->swap_node_v1->num]],
-	       st_b->nni->swap_node_v2,
-	       st_b->nni->swap_node_v3,
-	       st_b->nni->swap_node_v3->v[st->tree->t_dir[st_b->nni->swap_node_v3->num*dim+st_b->nni->swap_node_v4->num]],
-	       st->tree);
-
-	  PART_Do_Mapping(st);
-
-	}
-
-      beg = 0;
-      end = (int)FLOOR((phydbl)n_tested/step);
-      st_b = NULL;
-      dim = 2*st->tree->n_otu-2;
-
-      for(i=beg;i<end;i++)
-	{
-	  st_b = tested_b[i];
-	  
-	  PART_Swap(st_b->nni->swap_node_v2->v[st->tree->t_dir[st_b->nni->swap_node_v2->num*dim+st_b->nni->swap_node_v1->num]],
-		  st_b->nni->swap_node_v2,
-		  st_b->nni->swap_node_v3,
-		  st_b->nni->swap_node_v3->v[st->tree->t_dir[st_b->nni->swap_node_v3->num*dim+st_b->nni->swap_node_v4->num]],
-		  st);
-
-	  Swap(st_b->nni->swap_node_v2->v[st->tree->t_dir[st_b->nni->swap_node_v2->num*dim+st_b->nni->swap_node_v1->num]],
-	       st_b->nni->swap_node_v2,
-	       st_b->nni->swap_node_v3,
-	       st_b->nni->swap_node_v3->v[st->tree->t_dir[st_b->nni->swap_node_v3->num*dim+st_b->nni->swap_node_v4->num]],
-	       st->tree);
-
-	  PART_Do_Mapping(st);
-
-	}
-     
-      if(!end) st->tree->n_swap = 0;      
-
-      PART_Lk(st);
-
-      PhyML_Printf("\n. lnL = %15.5f",st->tree->c_lnL);
-      step++;
-    }
-  while((st->tree->c_lnL < lk_old) && (step < 100));
-
-  if(step == 100)
-    {
-      For(i,2*st->tree->n_otu-3) For(j,st->n_part)
-	st->bl[st->bl_partition[j]][i] = st->bl_cpy[st->bl_partition[j]][i];
-    }
-
-  st->tree->n_swap = 0;
-  For(i,2*st->tree->n_otu-3) 
-    {
-      if(st->tree->a_edges[i]->nni->score < 0.0) st->tree->n_swap++;
-      st->tree->a_edges[i]->nni->score = +1.0;
-    }
-
-  PART_Lk(st);
-
-  if(st->tree->c_lnL > lk_old)                                                    return  1;
-  else if(FABS(st->tree->c_lnL-lk_old) < st->tree->mod->s_opt->min_diff_lk_local) return -1;
-  else                                                                            return  0;
-
-  For(i,st->n_part) Free(l_init[i]);
-  Free(l_init);
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-void PART_Check_Extra_Taxa(supert_tree *st)
-{
-  int i,j,k;
-  int sum;
-  int *st_taxa;
-
-  st_taxa = (int *)mCalloc(st->tree->n_otu,sizeof(int));
-
-  For(i,st->tree->n_otu)
-    {
-      For(j,st->n_part)
-	{
-	  For(k,st->treelist->tree[j]->n_otu) 
-	    if(!strcmp(st->treelist->tree[j]->a_nodes[k]->name,st->tree->a_nodes[i]->name)) break;
-	  if(k != st->treelist->tree[j]->n_otu) { st_taxa[i] = 1; break; }
-	}
-    }
-
-  sum = 0;
-  For(i,st->tree->n_otu) if(st_taxa[i]) sum++;
-  if(sum != st->tree->n_otu) 
-    {
-      PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__);
-      Warn_And_Exit("");
-    }
-  Free(st_taxa);
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-int PART_Get_Species_Found_In_St(supert_tree *st, calign *data)
-{
-  int i,j;
-  
-  For(i,data->n_otu)
-    {
-      For(j,st->tree->n_otu)
-	{
-	  if(!strcmp(data->c_seq[i]->name,st->tree->a_nodes[j]->name))
-	    {
-	      break;
-	    }
-	}
-      if(j == st->tree->n_otu) return 0;
-    }
-  return 1;
-
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-void PART_Map_St_Nodes_In_Gt(t_tree *gt, supert_tree *st)
-{
-  int i;
-
-  For(i,2*st->tree->n_otu-2)
-    {
-      st->map_st_node_in_gt[gt->dp][i][0][0] = NULL;
-      st->map_st_node_in_gt[gt->dp][i][1][0] = NULL;
-      st->map_st_node_in_gt[gt->dp][i][2][0] = NULL;
-
-      st->map_st_node_in_gt[gt->dp][i][0][1] = NULL;
-      st->map_st_node_in_gt[gt->dp][i][1][1] = NULL;
-      st->map_st_node_in_gt[gt->dp][i][2][1] = NULL;
-    }
-
-  
-  /* Root */
-  PART_Map_St_Nodes_In_Gt_One_Edge(st->tree->a_nodes[0]->v[0],
-				 st->tree->a_nodes[0],
-				 st->tree->a_nodes[0]->b[0],
-				 gt,st);
-
-  /* Internal nodes */
-  PART_Map_St_Nodes_In_Gt_Post(st->tree->a_nodes[0],st->tree->a_nodes[0]->v[0],gt,st);
-  PART_Map_St_Nodes_In_Gt_Pre (st->tree->a_nodes[0],st->tree->a_nodes[0]->v[0],gt,st);
-  
-  /* Root */
-  PART_Map_St_Nodes_In_Gt_One_Edge(st->tree->a_nodes[0],
-				 st->tree->a_nodes[0]->v[0],
-				 st->tree->a_nodes[0]->b[0],
-				 gt,st);
-  
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-void PART_Map_St_Nodes_In_Gt_Post(t_node *a_st, t_node *d_st, t_tree *gt, supert_tree *st)
-{
-  int i;
-
-  if(d_st->tax) return;
-  else
-    {
-      For(i,3)
-	if(d_st->v[i] != a_st)
-	  PART_Map_St_Nodes_In_Gt_Post(d_st,d_st->v[i],gt,st);
-      
-      For(i,3)
-	if(d_st->v[i] != a_st)
-	  {
-	    PART_Map_St_Nodes_In_Gt_One_Edge(d_st,d_st->v[i],d_st->b[i],gt,st);
-	  }
-    }
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-void PART_Map_St_Nodes_In_Gt_Pre(t_node *a_st, t_node *d_st, t_tree *gt, supert_tree *st)
-{
-  int i;
-
-  if(d_st->tax) return;
-  else
-    {
-      For(i,3)
-	{
-	  if(d_st->v[i] != a_st)
-	    {	      
-	      PART_Map_St_Nodes_In_Gt_One_Edge(d_st->v[i],d_st,d_st->b[i],gt,st);
-	      PART_Map_St_Nodes_In_Gt_Pre(d_st,d_st->v[i],gt,st);
-	    }
-	}
-    }
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-void PART_Map_St_Nodes_In_Gt_One_Edge(t_node *a_st, t_node *d_st, t_edge *b_st, t_tree *gt, supert_tree *st)
-{
-  if(d_st->tax)
-    {
-#ifdef DEBUG
-      if(b_st->rght != d_st)
-	{
-	  PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__);
-	  Warn_And_Exit("");
-	}
-#endif
-      
-      st->map_st_node_in_gt[gt->dp][d_st->num][0][0] = st->match_st_node_in_gt[gt->dp][d_st->num];
-    }
-  else
-    {
-      t_node **list_of_nodes_d, **list_of_nodes_v1, **list_of_nodes_v2;
-      int dir1, dir2;
-      int i;
-
-      list_of_nodes_d  = NULL;
-      list_of_nodes_v1 = NULL;
-      list_of_nodes_v2 = NULL;
-
-      dir1 = dir2 = -1;
-      For(i,3) 
-	{
-	  if(d_st->v[i] != a_st) (dir1 < 0)?(dir1 = i):(dir2 = i);
-	  else list_of_nodes_d = st->map_st_node_in_gt[gt->dp][d_st->num][i];
-	}
-
-      For(i,3) 
-	if((d_st->v[dir1]->v[i]) && (d_st->v[dir1]->v[i] == d_st)) 
-	  {
-	    list_of_nodes_v1 = st->map_st_node_in_gt[gt->dp][d_st->v[dir1]->num][i];
-	    break;
-	  }
-
-      For(i,3) 
-	if((d_st->v[dir2]->v[i]) && (d_st->v[dir2]->v[i] == d_st)) 
-	  {
-	    list_of_nodes_v2 = st->map_st_node_in_gt[gt->dp][d_st->v[dir2]->num][i];
-	    break;
-	  }
-
-      /* d_st matches one t_node in gt */
-      if(st->match_st_node_in_gt[gt->dp][d_st->num])
-	{
-	  list_of_nodes_d[0] = st->match_st_node_in_gt[gt->dp][d_st->num];
-	  list_of_nodes_d[1] = NULL;
-	}
-      else
-	{
-	  /* list_of_nodes = union of  list_of_nodes_v1  &  list_of_nodes_v2 */
-	  
-	  if(!list_of_nodes_v1[0])
-	    {
-	      list_of_nodes_d[0] = list_of_nodes_v2[0];
-	      list_of_nodes_d[1] = list_of_nodes_v2[1];
-	    }
-	  else if(!list_of_nodes_v2[0])
-	    {
-	      list_of_nodes_d[0] = list_of_nodes_v1[0];
-	      list_of_nodes_d[1] = list_of_nodes_v1[1];
-	    }
-	  else
-	    {
-	      list_of_nodes_d[0] = list_of_nodes_v1[0];
-	      list_of_nodes_d[1] = list_of_nodes_v2[0];
-
-	      if(list_of_nodes_v1[1] || list_of_nodes_v2[1])
-		{
-		  Print_Node(st->tree->a_nodes[0],
-			     st->tree->a_nodes[0]->v[0],
-			     st->tree);
-		  
-		  PhyML_Printf("\n\n--------------------------\n\n");
-		  Print_Node(gt->a_nodes[0],
-			     gt->a_nodes[0]->v[0],
-			     gt);
-
-		  PhyML_Printf("\n\n--------------------------\n\n");
-		  
-		  PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__);
-		  Warn_And_Exit("");
-		}
-	    }
-	}
-    }
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-void PART_Map_St_Edges_In_Gt(t_tree *gt, supert_tree *st)
-{
-  int i,j;
-  t_edge *st_b;
-  t_node *gt_a, *gt_d;
-  
-  gt_a = NULL;
-  gt_d = NULL;
-
-  For(i,2*st->tree->n_otu-3) st->map_st_edge_in_gt[gt->dp][i] = NULL;
-
-  For(i,2*st->tree->n_otu-3)
-    {
-      st_b = st->tree->a_edges[i];
-
-      if(!st->map_st_node_in_gt[gt->dp][st_b->left->num][st_b->l_r][0])
-	{
-	  gt_a = st->map_st_node_in_gt[gt->dp][st_b->rght->num][st_b->r_l][0];
-	  gt_d = st->map_st_node_in_gt[gt->dp][st_b->rght->num][st_b->r_l][1];
-
-	  For(j,3)
-	    {
-	      if((gt_a->v[j]) && (gt_a->v[j] == gt_d))
-		{
-		  st->map_st_edge_in_gt[gt->dp][st_b->num] = gt_a->b[j];
-		  break;
-		}
-	    }
-	}
-      else if(!st->map_st_node_in_gt[gt->dp][st_b->rght->num][st_b->r_l][0])
-	{
-	  gt_a = st->map_st_node_in_gt[gt->dp][st_b->left->num][st_b->l_r][0];
-	  gt_d = st->map_st_node_in_gt[gt->dp][st_b->left->num][st_b->l_r][1];
-
-	  For(j,3)
-	    {
-	      if((gt_a->v[j]) && (gt_a->v[j] == gt_d))
-		{
-		  st->map_st_edge_in_gt[gt->dp][st_b->num] = gt_a->b[j];
-		  break;
-		}
-	    }
-	}
-      else
-	{	  
-	  gt_a = st->map_st_node_in_gt[gt->dp][st_b->left->num][st_b->l_r][0];
-	  gt_d = st->map_st_node_in_gt[gt->dp][st_b->rght->num][st_b->r_l][0];
-
-	  #ifdef DEBUG
-	  if((!gt_a) || (!gt_d))
-	    {
-	      PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__);
-	      Warn_And_Exit("");
-	    }
-	  #endif
-
-	  For(j,3)
-	    {
-	      if((gt_a->v[j]) && (gt_a->v[j] == gt_d))
-		{
-		  st->map_st_edge_in_gt[gt->dp][st_b->num] = gt_a->b[j];
-		  break;
-		}
-	    }
-	}
-    }
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-void PART_Map_Gt_Edges_In_St(t_tree *gt, supert_tree *st)
-{
-  int i;
-  t_edge *st_b, *gt_b;
-  
-  For(i,2*st->tree->n_otu-3) st->size_map_gt_edge_in_st[gt->dp][i] = 0;
-
-  st_b = NULL;
-  gt_b = NULL;
-  For(i,2*st->tree->n_otu-3)
-    {
-      st_b = st->tree->a_edges[i];
-      gt_b = st->map_st_edge_in_gt[gt->dp][st_b->num];
-
-      if(gt_b)
-	{
-	  st->map_gt_edge_in_st[gt->dp][gt_b->num][st->size_map_gt_edge_in_st[gt->dp][gt_b->num]] = st_b;
-	  st->size_map_gt_edge_in_st[gt->dp][gt_b->num]++;
-	}
-    }
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-int PART_Pars(supert_tree *st)
-{
-  int i;
-  
-  st->tree->c_pars = 0;
-  For(i,st->n_part) 
-    {
-      Set_Both_Sides(YES,st->treelist->tree[i]);	  
-      Pars(NULL,st->treelist->tree[i]);
-      st->tree->c_pars += st->treelist->tree[i]->c_pars;
-    }
-
-  return st->tree->c_pars;
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-int PART_Spr(phydbl init_lnL, supert_tree *st)
-{
-  int gt;
-  int i;
-  t_edge *pruned;
-  int best_move;
-  t_node *gt_a, *gt_d;
-
-  st->tree->n_root     = st->tree->a_nodes[0];
-  pruned               = NULL;
-  gt_a                 = NULL;
-  gt_d                 = NULL;
-  
-  Set_Both_Sides(YES,st->tree);
-
-  For(i,2*st->tree->n_otu-3)
-    {
-      pruned            = st->tree->a_edges[i];
-      st->tree->n_moves = 0;
-
-      Reset_Spr_List(st->tree);
-      For(gt,st->n_part) Reset_Spr_List(st->treelist->tree[gt]);
-      
-      if(!pruned->rght->tax)
-	{
-	  For(gt,st->n_part)
-	    {
-	      /* Check constraints at prune site on gt tree */
- 	      gt_a = st->map_st_node_in_gt[gt][pruned->rght->num][pruned->r_l][0];
- 	      gt_d = st->map_st_node_in_gt[gt][pruned->left->num][pruned->l_r][0];
-
-	      if((gt_a) && (gt_d) && (!st->map_st_edge_in_gt[gt][pruned->num]->rght->tax))
-		{
-		  Test_All_Spr_Targets(st->map_st_edge_in_gt[gt][pruned->num],
-				       st->map_st_edge_in_gt[gt][pruned->num]->rght,
-				       st->treelist->tree[gt]);
-		}
-	    }
-	}
-
-      if(!pruned->left->tax)
-	{
-	  For(gt,st->n_part)
-	    {
-	      /* Check constraints at prune site on gt tree */	      
- 	      gt_a = st->map_st_node_in_gt[gt][pruned->rght->num][pruned->r_l][0];
- 	      gt_d = st->map_st_node_in_gt[gt][pruned->left->num][pruned->l_r][0];
-
-	      if((gt_a) && (gt_d) && (!st->map_st_edge_in_gt[gt][pruned->num]->left->tax))
-		{
-		  Test_All_Spr_Targets(st->map_st_edge_in_gt[gt][pruned->num],
-				       st->map_st_edge_in_gt[gt][pruned->num]->left,
-				       st->treelist->tree[gt]);
-		}
-	    }
-	}
-
-      
-      if(!pruned->left->tax)
-	{
-	  PART_Test_All_Spr_Targets(st->tree->a_edges[i],
-				  st->tree->a_edges[i]->left,
-				  st);      
-	}
-      
-      if(!pruned->rght->tax)
-	{
-	  PART_Test_All_Spr_Targets(st->tree->a_edges[i],
-				  st->tree->a_edges[i]->rght,
-				  st);      
-	}
-
-
-      if(st->tree->n_moves)
-	{
-	  best_move = PART_Test_List_Of_Regraft_Pos(st->tree->spr_list,
-						  (int)CEIL(0.1*(st->tree->n_moves)),
-						  st);	  
-	  
-	  if(st->tree->spr_list[best_move]->lnL > init_lnL)
-	    {
-	      PART_Try_One_Spr_Move(st->tree->spr_list[best_move],st);
-	    }
-	  else
-	    {
-              Set_Both_Sides(YES,st->tree);
-	      st->tree->c_lnL  = PART_Lk(st);
-	      st->tree->c_pars = PART_Pars(st);	      
-	    }
-	}
-    }
-  return 1;
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-void PART_Speed_Spr(supert_tree *st)
-{
-  int step;
-  int gt;
-  phydbl old_lnL;
-
-  Make_Spr_List(st->tree);
-  For(gt,st->n_part) Make_Spr_List(st->treelist->tree[gt]);
-
-  Set_Both_Sides(YES,st->tree); 
-  For(gt,st->n_part) 
-    {
-      Set_Both_Sides(YES,st->treelist->tree[gt]);
-      Record_Br_Len(st->treelist->tree[gt]);
-    }
-  
-  st->tree->c_pars = PART_Pars(st);
-  st->tree->c_lnL  = PART_Lk(st);
-  
-
-  st->tree->best_lnL = st->tree->c_lnL;
-  old_lnL            = st->tree->c_lnL;
-  step               = 0;
-  do
-    {
-      ++step;
-
-      PhyML_Printf("\n. Starting a SPR cycle... \n");
-
-      old_lnL = st->tree->c_lnL;
-
-      st->tree->n_improvements         = 0;
-      st->tree->perform_spr_right_away = 1;
-      PART_Spr(UNLIKELY,st);
-
- 
-      time(&(st->tree->t_current));      
-      PhyML_Printf("\n. (%5d sec) [00] [%10.2f] [%5d]\n",
-	     (int)(st->tree->t_current-st->tree->t_beg),
-	     PART_Lk(st),PART_Pars(st));
-
-      /* Optimise parameters of the Markov t_mod */
-      For(gt,st->n_part) Optimiz_All_Free_Param(st->treelist->tree[gt],
-					      st->treelist->tree[gt]->mod->s_opt->print);
-
-      time(&(st->tree->t_current));      
-      PhyML_Printf("\n. (%5d sec) [ 0] [%10.2f] [%5d]\n",
-	     (int)(st->tree->t_current-st->tree->t_beg),
-	     PART_Lk(st),PART_Pars(st));
-
-      /* Optimise branch lengths */
-      For(gt,st->n_part)
-	{
-	  Optimize_Br_Len_Serie(st->treelist->tree[gt]);
-	}
-
-
-      /* Update partial likelihoods & parsimony */
-      Set_Both_Sides(YES,st->tree); 
-      st->tree->c_pars = PART_Pars(st);
-      st->tree->c_lnL  = PART_Lk(st);
-      
-      
-      time(&(st->tree->t_current));      
-      PhyML_Printf("\n. (%5d sec) [**] [%10.2f] [%5d]\n",
-	     (int)(st->tree->t_current-st->tree->t_beg),
-	     st->tree->c_lnL,st->tree->c_pars);
-
-      /* Record the current best log-likleihood  */
-      st->tree->best_lnL = st->tree->c_lnL;
-
-      if(st->tree->c_lnL < old_lnL)
-	{
-	  PhyML_Printf("\n. old_lnL = %f c_lnL = %f\n",old_lnL,st->tree->c_lnL); 
-	  PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__);
-	  Warn_And_Exit("");
-	}
-
-      /* Record the current best branch lengths  */
-      For(gt,st->n_part) Record_Br_Len(st->treelist->tree[gt]);
-
-      /* Exit if no improvements after complete optimization */
-      if((!st->tree->n_improvements) || 
-	 (FABS(old_lnL-st->tree->c_lnL) < st->tree->mod->s_opt->min_diff_lk_global)) break;
-            
-    }while(1);
-  
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-
-void PART_Test_All_Spr_Targets(t_edge *pruned, t_node *n_link, supert_tree *st)
-{
-  int i,j;
-
-  For(i,3)
-    {
-      if(n_link->b[i] != pruned)
-	{
-	  For(j,3)
-	    {
-	      if((n_link->v[i]->v[j]) && (n_link->v[i]->v[j] != n_link))
-		{
-		  PART_Test_One_Spr_Target_Recur(n_link->v[i],n_link->v[i]->v[j],n_link->v[i]->b[j],pruned,n_link,st);
-		}
-	    }
-	}
-    }
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-void PART_Test_One_Spr_Target_Recur(t_node *a, t_node *d, t_edge *target, t_edge *pruned, t_node *n_link, supert_tree *st)
-{
-
-  PART_Test_One_Spr_Target(pruned,target,n_link,st);
-
-  if(d->tax) return;
-  else
-    {
-      int i;
-
-      For(i,3)
-	if(d->v[i] != a)
-	  {
-	    PART_Test_One_Spr_Target_Recur(d,d->v[i],d->b[i],pruned,n_link,st);
-	  }
-    }
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-void PART_Test_One_Spr_Target(t_edge *st_p, t_edge *st_t, t_node *n_link, supert_tree *st) 
-{
-  int gt, move;
-
-  st->tree->n_moves++;
-  st->tree->spr_list[st->tree->size_spr_list]->b_target      = st_t;
-  st->tree->spr_list[st->tree->size_spr_list]->n_link        = n_link;
-  st->tree->spr_list[st->tree->size_spr_list]->n_opp_to_link = (n_link == st_p->left)?(st_p->rght):(st_p->left);
-  st->tree->spr_list[st->tree->size_spr_list]->b_opp_to_link = st_p;
-  st->tree->spr_list[st->tree->size_spr_list]->pars          = 0;
-
-  For(gt,st->n_part)
-    {
-      move = Map_Spr_Move(st_p,st_t,n_link,st->treelist->tree[gt],st);
-      
-      if(move > -1)
-	st->tree->spr_list[st->tree->size_spr_list]->pars += st->treelist->tree[gt]->spr_list[move]->pars;
-      else if(move == -1 || move == -2)
-	st->tree->spr_list[st->tree->size_spr_list]->pars += st->treelist->tree[gt]->c_pars;
-    }
-
-  Include_One_Spr_To_List_Of_Spr(st->tree->spr_list[st->tree->size_spr_list],st->tree);
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-int Map_Spr_Move(t_edge *st_pruned, t_edge *st_target, t_node *st_link, t_tree *gt, supert_tree *st)
-{
-  int i;
-  t_edge *gt_pruned, *gt_target;
-  t_node *gt_link, *gt_a, *gt_d;
-
-  gt_pruned = NULL;
-  gt_target = NULL;
-  gt_link   = NULL;
-  gt_a      = NULL;
-  gt_d      = NULL;
-
-  /* Check contraints at prune and regraft sites on the gt tree */
-
-  /* st_pruned is not on a path that matches a branch in gt */
-  gt_a = st->map_st_node_in_gt[gt->dp][st_pruned->left->num][st_pruned->l_r][0];
-  gt_d = st->map_st_node_in_gt[gt->dp][st_pruned->rght->num][st_pruned->r_l][0];
-
-  if((!gt_a) || (!gt_d)) return -1;
-  else
-    {
-      /* which gt nodes matches st_link ? */
-      gt_link = (st_pruned->left == st_link)?(gt_a):(gt_d);
-      
-      if(gt_link->tax) return -1;
-      else
-	{
-	  gt_pruned = st->map_st_edge_in_gt[gt->dp][st_pruned->num];
-	  gt_target = st->map_st_edge_in_gt[gt->dp][st_target->num];
-	   
-	  if((gt_pruned->left == gt_target->left) ||
-	     (gt_pruned->left == gt_target->rght) ||
-	     (gt_pruned->rght == gt_target->left) ||
-	     (gt_pruned->rght == gt_target->rght)) return -1;
-	  else
-	    {
-	      For(i,gt->size_spr_list)
-		{
-		  if((gt_pruned == gt->spr_list[i]->b_opp_to_link) && (gt_target == gt->spr_list[i]->b_target))
-		    return i;
-		}
-	    }
-	}
-    }
-  return -2;
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-int PART_Test_List_Of_Regraft_Pos(t_spr **st_spr_list, int list_size, supert_tree *st)
-{
-
-  int i,j,best_move;
-  t_spr *move;
-  t_edge *init_target, *b_residual;
-  phydbl best_lnL, init_lnL;
-  int dir_v0, dir_v1, dir_v2;
-  int gt;
-  int move_num;
-  
-
-  best_lnL = UNLIKELY;
-  init_target = b_residual = NULL;
-  best_move = -1;
-
-#ifdef DEBUG
-  if(!list_size)
-    {
-      PhyML_Printf("\n\n. List size is 0 !");
-      PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__);
-      Warn_And_Exit(""); 
-    }
-#endif
-  
-  init_lnL = UNLIKELY;
-
-  For(i,list_size)
-    {
-      st->tree->spr_list[i]->lnL = .0;
-
-      For(gt,st->n_part) 
-	{
-	  move_num = Map_Spr_Move(st->tree->spr_list[i]->b_opp_to_link,
-				  st->tree->spr_list[i]->b_target,
-				  st->tree->spr_list[i]->n_link,
-				  st->treelist->tree[gt],st);
-
-	  if(move_num > -1)
-	    {
-	      move = st->treelist->tree[gt]->spr_list[move_num];
-
-	      if(move->b_target)
-		{
-		  init_lnL = st->treelist->tree[gt]->c_lnL;
-
-		  /* Record t_edge lengths */
-		  Record_Br_Len(st->treelist->tree[gt]);
-		  
-		  /* Prune subtree */
-		  Prune_Subtree(move->n_link,
-				move->n_opp_to_link,			    
-				&init_target,
-				&b_residual,
-				st->treelist->tree[gt]);
-
-		  /* Rough optimisation of the branch length */
-		  Fast_Br_Len(init_target,st->treelist->tree[gt],0);
-		  
-		  /* Update the change proba matrix at prune position */
-		  Update_PMat_At_Given_Edge(init_target,st->treelist->tree[gt]);
-	      
-		  /* Update partial likelihood along the path from the prune to
-		     the regraft position */
-		  Update_P_Lk_Along_A_Path(move->path,move->depth_path,st->treelist->tree[gt]);
-
-		  /* Regraft subtree */
-		  Graft_Subtree(move->b_target,move->n_link,b_residual,st->treelist->tree[gt]);
-	      
-		  /* Estimate the three t_edge lengths at the regraft site */
-		  Triple_Dist(move->n_link,st->treelist->tree[gt],-1);
-	      
-		  /* Update the transition proba matrices along edges defining 
-		     the regraft site */
-		  For(j,3)
-		    if(move->n_link->v[j] != move->n_opp_to_link)
-		      Update_PMat_At_Given_Edge(move->n_link->b[j],st->treelist->tree[gt]);
-	      
-		  /* Compute the likelihood */
-		  Update_P_Lk(st->treelist->tree[gt],
-			      move->b_opp_to_link,
-			      move->n_link);
-		  
-		  move->lnL = Lk(move->b_opp_to_link,st->treelist->tree[gt]);
-
-		  
-		  st->tree->spr_list[i]->lnL += move->lnL;
-
-		  /* Record branch lengths */
-		  dir_v1 = dir_v2 = dir_v0 = -1;
-		  For(j,3)
-		    {
-		      if(move->n_link->v[j] == move->n_opp_to_link) dir_v0 = j;
-		      else if(dir_v1 < 0)                           dir_v1 = j;
-		      else                                          dir_v2 = j;
-		    }
-		  
-		  move->l0 = move->n_link->b[dir_v0]->l->v;
-		  
-		  if(move->n_link->v[dir_v1]->num > move->n_link->v[dir_v2]->num)
-		    {
-		      move->l1 = move->n_link->b[dir_v2]->l->v;
-		      move->l2 = move->n_link->b[dir_v1]->l->v;
-		    }
-		  else
-		    {
-		      move->l1 = move->n_link->b[dir_v1]->l->v;
-		      move->l2 = move->n_link->b[dir_v2]->l->v;
-		    }
-		  	  
-		  /* Regraft the subtree at its original position */
-		  Prune_Subtree(move->n_link,
-				move->n_opp_to_link,
-				&move->b_target,
-				&b_residual,
-				st->treelist->tree[gt]);
-		  
-		  Graft_Subtree(init_target,
-				move->n_link,
-				b_residual,
-				st->treelist->tree[gt]);
-		  
-		  /* Restore branch lengths */
-		  Restore_Br_Len(st->treelist->tree[gt]);
-	      
-		  /* Update relevant change proba matrices */
-		  Update_PMat_At_Given_Edge(move->b_target,st->treelist->tree[gt]);
-		  For(j,3) Update_PMat_At_Given_Edge(move->n_link->b[j],st->treelist->tree[gt]);
-		  
-		  /* Update relevant partial likelihoods */
-		  For(j,3) Update_P_Lk(st->treelist->tree[gt],move->n_link->b[j],move->n_link);
-		  
-		  st->treelist->tree[gt]->c_lnL = init_lnL;
-		}
-	    }
-	  else
-	    {
-	      st->tree->spr_list[i]->lnL += st->treelist->tree[gt]->c_lnL;
-	    }
-	}
-
-      if(st->tree->spr_list[i]->lnL > best_lnL)
-	{
-	  best_lnL  = st->tree->spr_list[i]->lnL;
-	  best_move = i;
-	}
-    }
-
-  return best_move;  
-
-}
-
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-int PART_Try_One_Spr_Move(t_spr *st_move, supert_tree *st)
-{
-  int j;
-  t_spr **gt_move;
-  t_edge **init_target, **b_residual;
-  int dir_v0, dir_v1, dir_v2;
-  int gt;
-  int gt_move_num;
-  int n_moves;
-
-  
-  init_target = (t_edge **)mCalloc(st->n_part,sizeof(t_edge *));
-  b_residual  = (t_edge **)mCalloc(st->n_part,sizeof(t_edge *));
-  gt_move     = (t_spr **)mCalloc(st->n_part,sizeof(t_spr *));
-
-
-  n_moves = 0;
-  For(gt,st->n_part) 
-    {
-      gt_move_num = Map_Spr_Move(st_move->b_opp_to_link,
-				 st_move->b_target,
-				 st_move->n_link,
-				 st->treelist->tree[gt],st);
-      
-      if(gt_move_num > -1)
-	{
-	  n_moves++;
-
-	  gt_move[gt] = st->treelist->tree[gt]->spr_list[gt_move_num];
-	  
-	  if(gt_move[gt]->b_target)
-	    {
-	      /* Record t_edge lengths */
-	      Record_Br_Len(st->treelist->tree[gt]);
-
-	      /* Prune subtree */
-	      Prune_Subtree(gt_move[gt]->n_link,
-			    gt_move[gt]->n_opp_to_link,
-			    &(init_target[gt]),
-			    &(b_residual[gt]),
-			    st->treelist->tree[gt]);
-	      
-	      /* Rough optimisation of the branch length */
-	      Fast_Br_Len(init_target[gt],st->treelist->tree[gt],0);
-	      
-	      /* Update the change proba matrix at prune position */
-	      Update_PMat_At_Given_Edge(init_target[gt],st->treelist->tree[gt]); /* TO DO : NECESSARY ?? */
-	      
-	      /* Update partial likelihood along the path from the prune to
-		 the regraft position */
-	      Update_P_Lk_Along_A_Path(gt_move[gt]->path,gt_move[gt]->depth_path,st->treelist->tree[gt]); /* TO DO : NECESSARY ?? */
-	      
-	      /* Regraft subtree */
-	      Graft_Subtree(gt_move[gt]->b_target,gt_move[gt]->n_link,b_residual[gt],st->treelist->tree[gt]);
-	      
-	      dir_v1 = dir_v2 = dir_v0 = -1;
-	      For(j,3)
-		{
-		  if(gt_move[gt]->n_link->v[j] == gt_move[gt]->n_opp_to_link) dir_v0 = j;
-		  else if(dir_v1 < 0)                                         dir_v1 = j;
-		  else                                                        dir_v2 = j;
-		}
-	      
-	      gt_move[gt]->n_link->b[dir_v0]->l->v = gt_move[gt]->l0;
-		  
-	      if(gt_move[gt]->n_link->v[dir_v1]->num > gt_move[gt]->n_link->v[dir_v2]->num)
-		{
-		  gt_move[gt]->n_link->b[dir_v2]->l->v = gt_move[gt]->l1;
-		  gt_move[gt]->n_link->b[dir_v1]->l->v = gt_move[gt]->l2;
-		}
-	      else
-		{
-		  gt_move[gt]->n_link->b[dir_v1]->l->v = gt_move[gt]->l1;
-		  gt_move[gt]->n_link->b[dir_v2]->l->v = gt_move[gt]->l2;
-		}
-	    }
-	}
-    }
-  
-
-  if(n_moves)
-    {
-      if(st_move->lnL > st->tree->best_lnL)
-	{
-	  t_edge *st_target, *st_residual;
-
-	  /* Apply the move on the super-tree */
-	  Prune_Subtree(st_move->n_link,
-			st_move->n_opp_to_link,
-			&st_target,
-			&st_residual,
-			st->tree);
-	  
-	  Graft_Subtree(st_move->b_target,
-			st_move->n_link,
-			st_residual,
-			st->tree);
-	  
-	  	  
-	  /* Map gt and st nodes and edges */
-	  PART_Do_Mapping(st);
-
-	  time(&(st->tree->t_current));
-
-	  Set_Both_Sides(YES,st->tree);	  
-	  st->tree->c_lnL      = PART_Lk(st);
-	  st->tree->c_pars     = PART_Pars(st);
-	  
-	  
-	  if(FABS(st->tree->c_lnL - st_move->lnL) > st->tree->mod->s_opt->min_diff_lk_local)
-	    {
-	      PhyML_Printf("\n. st->tree->c_lnL = %f st_move->lnL = %f\n",
-		     st->tree->c_lnL,st_move->lnL);
-
-	      For(gt,st->n_part)
-		{
-		  PhyML_Printf("\n. truth -> %f ; move -> %f",
-			       Lk(NULL,st->treelist->tree[gt]),
-			       gt_move[gt] ? gt_move[gt]->lnL : -1.);
-		}
-	    }
-	  
-	  PhyML_Printf("\n. (%5d sec) [+ ] [%10.2f] [%5d] -- ",
-		 (int)(st->tree->t_current - st->tree->t_beg),
-		 st->tree->c_lnL,st->tree->c_pars);	  
-	  
-	  For(gt,st->n_part)
-	    PhyML_Printf("[%10.2f] ",st->treelist->tree[gt]->c_lnL);
-	  
-	  
-	  st->tree->n_improvements++;
-	  st->tree->best_lnL = st->tree->c_lnL;
-	  For(gt,st->n_part) Record_Br_Len(st->treelist->tree[gt]);
-	  
-	  Free(init_target);
-	  Free(b_residual);
-	  Free(gt_move);
-	  
-	  return 1;
-	}
-/*       else */
-/* 	{ */
-/* 	  For(gt,st->n_part)  */
-/* 	    { */
-/* 	      if(gt_move[gt]) */
-/* 		{ */
-/* 		  Lk(st->treelist->tree[gt]); */
-/* 		  Fast_Br_Len_Recur(st->treelist->tree[gt]->a_nodes[0], */
-/* 				    st->treelist->tree[gt]->a_nodes[0]->v[0], */
-/* 				    st->treelist->tree[gt]->a_nodes[0]->b[0], */
-/* 				    st->treelist->tree[gt]); */
-/* 		} */
-/* 	    } */
-	  
-/* 	  time(&(st->tree->t_current)); */
-/* 	  st->tree->both_sides = 1; */
-/* 	  st->tree->c_lnL      = PART_Lk(st); */
-	  
-/* 	  if(st->tree->c_lnL > st->tree->best_lnL) */
-/* 	    { */
-/* 	      t_edge *st_target, *st_residual; */
-	      
-/* 	      /\* Apply the move on the super-tree *\/ */
-/* 	      Prune_Subtree(st_move->n_link, */
-/* 			    st_move->n_opp_to_link,			     */
-/* 			    &st_target, */
-/* 			    &st_residual, */
-/* 			    st->tree); */
-	      
-/* 	      Graft_Subtree(st_move->b_target, */
-/* 			    st_move->n_link, */
-/* 			    st_residual, */
-/* 			    st->tree); */
-	      
-	      
-/* 	      /\* Map gt and st nodes and edges *\/ */
-/* 	      PART_Do_Mapping(st); */
-
-
-/* 	      st->tree->c_pars = PART_Pars(st); */
-/* 	      PhyML_Printf("\n. (%5d sec) [++] [%10.2f] [%5d] -- ", */
-/* 		     (int)(st->tree->t_current-st->tree->t_beg), */
-/* 		     st->tree->c_lnL, */
-/* 		     st->tree->c_pars); */
-/* 	      For(gt,st->n_part) */
-/* 		PhyML_Printf("[%10.2f] ",st->treelist->tree[gt]->c_lnL); */
-	      
-/* 	      st->tree->n_improvements++; */
-/* 	      st->tree->best_lnL = st->tree->c_lnL; */
-/* 	      For(gt,st->n_part) Record_Br_Len(st->treelist->tree[gt]); */
-
-/* 	      Free(init_target); */
-/* 	      Free(b_residual); */
-/* 	      Free(gt_move); */
-
-/* 	      return 1; */
-/* 	    } */
-/* 	} */
-    }
-  
-  For(gt,st->n_part) 
-    {
-      if(gt_move[gt])
-	{	  
-	  /* Regraft the subtree at its original position */
-	  Prune_Subtree(gt_move[gt]->n_link,
-			gt_move[gt]->n_opp_to_link,
-			&(gt_move[gt]->b_target),
-			&(b_residual[gt]),
-			st->treelist->tree[gt]);
-
-	  Graft_Subtree(init_target[gt],
-			gt_move[gt]->n_link,
-			b_residual[gt],
-			st->treelist->tree[gt]);	  
-
-	  /* Restore branch lengths */
-	  Restore_Br_Len(st->treelist->tree[gt]);
-	}
-    }
-  
-  Set_Both_Sides(YES,st->tree);
-  st->tree->c_lnL      = PART_Lk(st);
-  st->tree->c_pars     = PART_Pars(st);
-
-  time(&(st->tree->t_current));
-  
-  PhyML_Printf("\n. (%5d sec) [--] [%10.2f] [%5d] -- ",
-	 (int)(st->tree->t_current - st->tree->t_beg),
-	 st->tree->c_lnL,st->tree->c_pars);	  
-  
-  For(gt,st->n_part) PhyML_Printf("[%10.2f] ",st->treelist->tree[gt]->c_lnL);
-
-  Free(init_target);
-  Free(b_residual);
-  Free(gt_move);
-
-  return 0;
-
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-void PART_NNI(t_edge *st_b, supert_tree *st)
-{  
-  t_node *v1, *v2, *v3, *v4;
-  phydbl lk0_opt, lk1_opt, lk2_opt;
-  int i,j;
-  phydbl *init_bl;
-  t_edge **map_edge_bef_swap, **map_edge_aft_swap;
-
-
-  init_bl = (phydbl *)mCalloc(st->n_bl_part,sizeof(phydbl));
-  map_edge_bef_swap = (t_edge **)mCalloc(st->n_part,sizeof(t_edge *));
-  map_edge_aft_swap = (t_edge **)mCalloc(st->n_part,sizeof(t_edge *));
-
-
-  v1 = st_b->left->v[st_b->l_v1];
-  v2 = st_b->left->v[st_b->l_v2];
-  v3 = st_b->rght->v[st_b->r_v1];
-  v4 = st_b->rght->v[st_b->r_v2];
-
-  lk0_opt  = lk1_opt  = lk2_opt  = UNLIKELY;
-
-  if(v1->num < v2->num)
-    {
-      Check_Dirs(st->tree);
-      PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__);
-      Warn_And_Exit("");
-    }
-
-  if(v3->num < v4->num)
-    {
-      Check_Dirs(st->tree);
-      PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__);
-      Warn_And_Exit("");
-    }
-
-  
-/*   PhyML_Printf("oooooooo\n"); */
-/*   Print_Node(st->tree->a_nodes[0], */
-/* 	     st->tree->a_nodes[0]->v[0], */
-/* 	     st->tree); */
-/*   PhyML_Printf(">>>>>>>\n"); */
-/*   For(i,st->n_part) */
-/*     { */
-/*       Print_Node(st->treelist->tree[i]->a_nodes[0], */
-/* 		 st->treelist->tree[i]->a_nodes[0]->v[0], */
-/* 		 st->treelist->tree[i]); */
-/*       PhyML_Printf("<<<<<<<\n"); */
-/*     } */
-
-  
-  PART_Record_Br_Len(st);
-
-  For(i,st->n_part) map_edge_bef_swap[i] = NULL;
-  For(i,st->n_part) if(st->map_st_edge_in_gt[i][st_b->num]) map_edge_bef_swap[i] = st->map_st_edge_in_gt[i][st_b->num];
-
-  /* First alternative topological configuration */
-  /* Swap */
-  PART_Swap(v2,st_b->left,st_b->rght,v3,st);
-  Swap(v2,st_b->left,st_b->rght,v3,st->tree);
-  PART_Do_Mapping(st);
-  PART_Set_Bl(st->bl,st);
-  For(i,st->n_part) map_edge_aft_swap[i] = NULL;
-  For(i,st->n_part) if(st->map_st_edge_in_gt[i][st_b->num]) map_edge_aft_swap[i] = st->map_st_edge_in_gt[i][st_b->num];
-  For(i,st->n_part) if(map_edge_bef_swap[i]) Update_PMat_At_Given_Edge(map_edge_bef_swap[i],st->treelist->tree[i]);
-  For(i,st->n_part) if(map_edge_aft_swap[i]) Update_PMat_At_Given_Edge(map_edge_aft_swap[i],st->treelist->tree[i]);
-  For(i,st->n_part) if(map_edge_bef_swap[i] && map_edge_aft_swap[i]) 
-    {
-      For(j,3) if((map_edge_aft_swap[i]->left->v[j]) && 
-		  (map_edge_aft_swap[i]->left->b[j] == map_edge_bef_swap[i]) &&
-		  (map_edge_aft_swap[i] != map_edge_bef_swap[i])) 
-	Update_P_Lk(st->treelist->tree[i],
-		    map_edge_aft_swap[i],
-		    map_edge_aft_swap[i]->left);
-      For(j,3) if((map_edge_aft_swap[i]->rght->v[j]) && 
-		  (map_edge_aft_swap[i]->rght->b[j] == map_edge_bef_swap[i]) &&
-		  (map_edge_aft_swap[i] != map_edge_bef_swap[i])) 
-	Update_P_Lk(st->treelist->tree[i],
-		    map_edge_aft_swap[i],
-		    map_edge_aft_swap[i]->rght);
-    }
-  PART_Update_Lk_At_Given_Edge(st_b,st);
-  lk1_opt  = PART_Br_Len_Brent(st_b,0,st);
-  For(i,st->n_part) st->bl1[st->bl_partition[i]][st_b->num] = st->bl[st->bl_partition[i]][st_b->num];
-  /* Unswap */
-  PART_Swap(v3,st_b->left,st_b->rght,v2,st);
-  Swap(v3,st_b->left,st_b->rght,v2,st->tree);
-  PART_Do_Mapping(st);
-  PART_Restore_Br_Len(st);
-  PART_Set_Bl(st->bl,st);
-  For(i,st->n_part) if(map_edge_bef_swap[i]) Update_PMat_At_Given_Edge(map_edge_bef_swap[i],st->treelist->tree[i]);
-  For(i,st->n_part) if(map_edge_aft_swap[i]) Update_PMat_At_Given_Edge(map_edge_aft_swap[i],st->treelist->tree[i]);
-  For(i,st->n_part) if(map_edge_bef_swap[i] && map_edge_aft_swap[i]) 
-    {
-      For(j,3) if((map_edge_aft_swap[i]->left->v[j]) && 
-		  (map_edge_aft_swap[i]->left->b[j] == map_edge_bef_swap[i]) &&
-		  (map_edge_aft_swap[i] != map_edge_bef_swap[i])) 
-	Update_P_Lk(st->treelist->tree[i],
-		    map_edge_aft_swap[i],
-		    map_edge_aft_swap[i]->left);
-      For(j,3) if((map_edge_aft_swap[i]->rght->v[j]) && 
-		  (map_edge_aft_swap[i]->rght->b[j] == map_edge_bef_swap[i]) &&
-		  (map_edge_aft_swap[i] != map_edge_bef_swap[i])) 
-	Update_P_Lk(st->treelist->tree[i],
-		    map_edge_aft_swap[i],
-		    map_edge_aft_swap[i]->rght);
-    }
-
-
-
-
-  /* Second alternative topological configuration */
-  /* Swap */
-  PART_Swap(v2,st_b->left,st_b->rght,v4,st);
-  Swap(v2,st_b->left,st_b->rght,v4,st->tree);
-  PART_Do_Mapping(st);
-  PART_Set_Bl(st->bl,st);
-  For(i,st->n_part) map_edge_aft_swap[i] = NULL;
-  For(i,st->n_part) if(st->map_st_edge_in_gt[i][st_b->num]) map_edge_aft_swap[i] = st->map_st_edge_in_gt[i][st_b->num];
-  For(i,st->n_part) if(map_edge_bef_swap[i]) Update_PMat_At_Given_Edge(map_edge_bef_swap[i],st->treelist->tree[i]);
-  For(i,st->n_part) if(map_edge_aft_swap[i]) Update_PMat_At_Given_Edge(map_edge_aft_swap[i],st->treelist->tree[i]);
-  For(i,st->n_part) if(map_edge_bef_swap[i] && map_edge_aft_swap[i]) 
-    {
-      For(j,3) if((map_edge_aft_swap[i]->left->v[j]) && 
-		  (map_edge_aft_swap[i]->left->b[j] == map_edge_bef_swap[i]) &&
-		  (map_edge_aft_swap[i] != map_edge_bef_swap[i])) 
-	Update_P_Lk(st->treelist->tree[i],
-		    map_edge_aft_swap[i],
-		    map_edge_aft_swap[i]->left);
-      For(j,3) if((map_edge_aft_swap[i]->rght->v[j]) && 
-		  (map_edge_aft_swap[i]->rght->b[j] == map_edge_bef_swap[i]) &&
-		  (map_edge_aft_swap[i] != map_edge_bef_swap[i])) 
-	Update_P_Lk(st->treelist->tree[i],
-		    map_edge_aft_swap[i],
-		    map_edge_aft_swap[i]->rght);
-    }
-
-  PART_Update_Lk_At_Given_Edge(st_b,st);
-  lk2_opt  = PART_Br_Len_Brent(st_b,0,st);
-  For(i,st->n_part) st->bl2[st->bl_partition[i]][st_b->num] = st->bl[st->bl_partition[i]][st_b->num];
-  /*   PhyML_Printf("\n. lk2_init = %f lk2_opt = %f",lk2_init,lk2_opt); */
-  /* Unswap */
-  PART_Swap(v4,st_b->left,st_b->rght,v2,st);
-  Swap(v4,st_b->left,st_b->rght,v2,st->tree);
-  PART_Do_Mapping(st);
-  PART_Restore_Br_Len(st);
-  PART_Set_Bl(st->bl,st);
-  For(i,st->n_part) if(map_edge_bef_swap[i]) Update_PMat_At_Given_Edge(map_edge_bef_swap[i],st->treelist->tree[i]);
-  For(i,st->n_part) if(map_edge_aft_swap[i]) Update_PMat_At_Given_Edge(map_edge_aft_swap[i],st->treelist->tree[i]);
-  For(i,st->n_part) if(map_edge_bef_swap[i] && map_edge_aft_swap[i]) 
-    {
-      For(j,3) if((map_edge_aft_swap[i]->left->v[j]) && 
-		  (map_edge_aft_swap[i]->left->b[j] == map_edge_bef_swap[i]) &&
-		  (map_edge_aft_swap[i] != map_edge_bef_swap[i])) 
-	Update_P_Lk(st->treelist->tree[i],
-		    map_edge_aft_swap[i],
-		    map_edge_aft_swap[i]->left);
-      For(j,3) if((map_edge_aft_swap[i]->rght->v[j]) && 
-		  (map_edge_aft_swap[i]->rght->b[j] == map_edge_bef_swap[i]) &&
-		  (map_edge_aft_swap[i] != map_edge_bef_swap[i])) 
-	Update_P_Lk(st->treelist->tree[i],
-		    map_edge_aft_swap[i],
-		    map_edge_aft_swap[i]->rght);
-    }
-
-
-  /* Back to the initial topological configuration 
-   * and branch lengths.
-   */
-  PART_Do_Mapping(st);
-  PART_Set_Bl(st->bl,st);
-  PART_Restore_Br_Len(st);
-  For(i,st->n_part) map_edge_aft_swap[i] = NULL;
-  For(i,st->n_part) if(st->map_st_edge_in_gt[i][st_b->num]) map_edge_aft_swap[i] = st->map_st_edge_in_gt[i][st_b->num];
-  For(i,st->n_part) if(map_edge_bef_swap[i]) Update_PMat_At_Given_Edge(map_edge_bef_swap[i],st->treelist->tree[i]);
-  For(i,st->n_part) if(map_edge_aft_swap[i]) Update_PMat_At_Given_Edge(map_edge_aft_swap[i],st->treelist->tree[i]);
-  PART_Update_Lk_At_Given_Edge(st_b,st);
-  lk0_opt  = PART_Br_Len_Brent(st_b,0,st);
-  For(i,st->n_part) st->bl0[st->bl_partition[i]][st_b->num] = st->bl[st->bl_partition[i]][st_b->num];
-
-  PART_Restore_Br_Len(st);
-  PART_Set_Bl(st->bl,st);
-  For(i,st->n_part) if(map_edge_bef_swap[i]) Update_PMat_At_Given_Edge(map_edge_bef_swap[i],st->treelist->tree[i]);
-  For(i,st->n_part) if(map_edge_aft_swap[i]) Update_PMat_At_Given_Edge(map_edge_aft_swap[i],st->treelist->tree[i]);
-  PART_Update_Lk_At_Given_Edge(st_b,st);
-
-
-
-/*   For(i,2*st->tree->n_otu-3) */
-/*     PhyML_Printf("\n. 3 Edge %3d --> lnL=%f",i,PART_Lk_At_Given_Edge(st->tree->a_edges[i],st)); */
-
-
-
-  st_b->nni->lk0 = lk0_opt;
-  st_b->nni->lk1 = lk1_opt;
-  st_b->nni->lk2 = lk2_opt;
-
-  st_b->nni->score = lk0_opt - MAX(lk1_opt,lk2_opt);
-
-  if((st_b->nni->score <  st->tree->mod->s_opt->min_diff_lk_local) &&
-     (st_b->nni->score > -st->tree->mod->s_opt->min_diff_lk_local))
-    {
-      st_b->nni->score = .0;
-      st_b->nni->lk1   = st_b->nni->lk0;
-      st_b->nni->lk2   = st_b->nni->lk0;
-     }
-
-  PART_Restore_Br_Len(st);
-  PART_Update_Lk_At_Given_Edge(st_b,st); /* to replace by PART_Update_PMat_At_Given_Edge(st_b,st); */
-/*   PhyML_Printf("\n. lk_end = %f",st->tree->c_lnL); */
-/*   For(i,2*st->tree->n_otu-3) PhyML_Printf("\n. %f",PART_Lk_At_Given_Edge(st->tree->a_edges[i],st)); */
-/*   PhyML_Printf("\n. lk_end = %f",PART_Lk(st)); */
-/*   PhyML_Printf("\n"); */
-
-/*   PhyML_Printf("\n. Edge %3d, score = %20f",st_b->num,st_b->nni->score); */
-
-  if(st_b->num == 90)
-    PhyML_Printf("\n. v1=%d v2=%d v3=%d v4=%d left-%d right-%d",
-	   v1->num,
-	   v2->num,
-	   v3->num,
-	   v4->num,
-	   st_b->left->num,
-	   st_b->rght->num);
-
-
-
-  if(lk0_opt > MAX(lk1_opt,lk2_opt))
-    {
-      st_b->nni->best_conf = 0;
-      st_b->nni->swap_node_v1 = NULL;
-      st_b->nni->swap_node_v2 = NULL;
-      st_b->nni->swap_node_v3 = NULL;
-      st_b->nni->swap_node_v4 = NULL;
-    }
-  else if(lk1_opt > MAX(lk0_opt,lk2_opt))
-    {
-      st_b->nni->best_conf    = 1;
-      st_b->nni->swap_node_v1 = v2;
-      st_b->nni->swap_node_v2 = st_b->left;
-      st_b->nni->swap_node_v3 = st_b->rght;
-      st_b->nni->swap_node_v4 = v3;
-    }
-  else if(lk2_opt > MAX(lk0_opt,lk1_opt))
-    {
-      st_b->nni->best_conf    = 2;
-      st_b->nni->swap_node_v1 = v2;
-      st_b->nni->swap_node_v2 = st_b->left;
-      st_b->nni->swap_node_v3 = st_b->rght;
-      st_b->nni->swap_node_v4 = v4;
-    }
-  else
-    {
-      st_b->nni->score        = +1.0;
-      st_b->nni->best_conf    = 0;
-      st_b->nni->swap_node_v1 = NULL;
-      st_b->nni->swap_node_v2 = NULL;
-      st_b->nni->swap_node_v3 = NULL;
-      st_b->nni->swap_node_v4 = NULL;
-    }
-  
-  Free(init_bl);
-  Free(map_edge_aft_swap);
-  Free(map_edge_bef_swap);
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-void PART_Swap(t_node *st_a, t_node *st_b, t_node *st_c, t_node *st_d, supert_tree *st)
-{
-  int i,j;
-  t_node *gt_a, *gt_b, *gt_c, *gt_d;
-  int ab, ba, cd, dc, bc;
-
-  ab = ba = cd = dc = bc = -1;
-
-  For(i,3) if(st_a->v[i] == st_b) { ab = i; break; }
-  For(i,3) if(st_b->v[i] == st_a) { ba = i; break; }
-  For(i,3) if(st_c->v[i] == st_d) { cd = i; break; }
-  For(i,3) if(st_d->v[i] == st_c) { dc = i; break; }
-  For(i,3) if(st_b->v[i] == st_c) { bc = i; break; }
-
-  if(ab < 0 || ba < 0 || cd < 0 || dc < 0)
-    {
-      PhyML_Printf("\n. Nodes %d %d %d %d\n",st_a->num,st_b->num,st_c->num,st_d->num);
-      PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__);
-      Warn_And_Exit("");
-    }
-
-  gt_a = gt_b = gt_c = gt_d = NULL;
-  
-  For(i,st->n_part)
-    {
-      gt_b = st->match_st_node_in_gt[i][st_b->num];
-      gt_c = st->match_st_node_in_gt[i][st_c->num];
-      
-      if(gt_b && gt_c) /* The st t_edge with st_b and st_c at its extremities
-			* matches an t_edge in gt 
-		        */
-	{
-#ifdef DEBUG
-	  For(j,3) if((gt_b->v[j]) && (gt_b->v[j] == gt_c)) break;
-	  if(j == 3)
-	    {
-	      PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__);
-	      Warn_And_Exit("");
-	    }
-#endif
-	  gt_a = st->map_st_node_in_gt[i][st_a->num][ab][0];
-	  gt_d = st->map_st_node_in_gt[i][st_d->num][dc][0];
-	  Swap(gt_a,gt_b,gt_c,gt_d,st->treelist->tree[i]);
-	}
-    }
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-void PART_Set_Bl(phydbl **bl, supert_tree *st)
-{
-  int i,j;
-  t_edge *gt_b;
-
-  gt_b = NULL;
-						
-  /* Set all the actual branch lengths to 0.0 
-   */
-  For(i,st->n_part)
-    {
-      For(j,2*st->treelist->tree[i]->n_otu-3)
-	{
-	  gt_b = st->treelist->tree[i]->a_edges[j];
-	  gt_b->l->v = .0;
-	}
-    }
-
-  /* Update every branch length 
-   */  
-  For(i,2*st->tree->n_otu-3)
-    {
-      For(j,st->n_part)
-	{
-	  gt_b = st->map_st_edge_in_gt[j][i];	
-	  
-	  /* Need to make sure that st->tree->a_edges[i] is on an existing path in gt */
-	  if((st->map_st_node_in_gt[j][st->tree->a_edges[i]->left->num][st->tree->a_edges[i]->l_r][0]) &&
-	     (st->map_st_node_in_gt[j][st->tree->a_edges[i]->rght->num][st->tree->a_edges[i]->r_l][0]))
-	    {
-	      gt_b->l->v += bl[st->bl_partition[j]][i];
-	    }
-	}
-    }
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-void PART_Record_Br_Len(supert_tree *st)
-{
-  int i,j;
-  For(i,st->n_part) For(j,2*st->tree->n_otu-3) st->bl_cpy[i][j] = st->bl[i][j];
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-void PART_Restore_Br_Len(supert_tree *st)
-{
-  int i,j;
-  For(i,st->n_part) For(j,2*st->tree->n_otu-3) st->bl[i][j] = st->bl_cpy[i][j];
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-phydbl PART_Lk(supert_tree *st)
-{
-  int i;
-
-  PART_Do_Mapping(st);
-  PART_Set_Bl(st->bl,st);  
-
-  st->tree->c_lnL = .0;
-  For(i,st->n_part) 
-    {
-      Set_Both_Sides(YES,st->treelist->tree[i]);	  
-      Lk(NULL,st->treelist->tree[i]);
-/*       PhyML_Printf("\n. Tree %3d lnL = %f",i+1,st->treelist->tree[i]->c_lnL); */
-      st->tree->c_lnL += st->treelist->tree[i]->c_lnL;
-    }
-  return st->tree->c_lnL;
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-phydbl PART_Lk_At_Given_Edge(t_edge *st_b, supert_tree *st)
-{
-  int i;
-  t_edge *gt_b;
-  phydbl lnL;
-
-  PART_Set_Bl(st->bl,st);
-
-  gt_b = NULL;
-  st->tree->c_lnL = .0;
-  lnL = .0;
-  For(i,st->n_part)
-    {      
-      gt_b = st->map_st_edge_in_gt[i][st_b->num];
-      lnL = Lk(gt_b,st->treelist->tree[i]);
-      st->tree->c_lnL += lnL;
-/*       PhyML_Printf("\n. gt %d st t_edge %d gt t_edge %d lnL=%f l=%f ",i,st_b->num,gt_b->num,lnL,gt_b->l->v); */
-    }
-  return st->tree->c_lnL;
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-phydbl PART_Update_Lk_At_Given_Edge(t_edge *st_b, supert_tree *st)
-{
-  int i;
-  t_edge *gt_b;
-
-  PART_Set_Bl(st->bl,st);
-  
-  gt_b = NULL;
-  st->tree->c_lnL = .0;
-  For(i,st->n_part)
-    {
-      gt_b = st->map_st_edge_in_gt[i][st_b->num];
-      if(gt_b) st->tree->c_lnL += Update_Lk_At_Given_Edge(gt_b,st->treelist->tree[i]);
-      else     st->tree->c_lnL += st->treelist->tree[i]->c_lnL;
-    }
-  return st->tree->c_lnL;
-}
-
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-void PART_Fill_Model_Partitions_Table(supert_tree *st)
-{
-  int i,j;
-  char *c;
-  char *abc;
-  int lig, col;
-  int n_groups;
-  int *encountered_vals;
-
-  c = (char *)mCalloc(10,sizeof(char));
-  abc = (char *)mCalloc(20,sizeof(char));
-  encountered_vals = (int *)mCalloc(st->n_part,sizeof(int));
-
-  strcpy(abc,"ABCDEFGHIJKLMNOP\0");
-
-  PhyML_Printf("\n\n\n");
-  lig = col = 0;
-  while(1)
-    {
-      PhyML_Printf("\n\n");
-      For(i,st->n_part)
-	PhyML_Printf(". Data set %3d : %s\n",i+1,st->optionlist[i]->in_align_file);
-
-      PhyML_Printf("\n. Data set             ");
-      For(i,st->n_part) PhyML_Printf("%3d ",i+1);
-      PhyML_Printf("\n. -A- t_edge lengths     ");
-      For(i,st->n_part) PhyML_Printf("%3d ",st->bl_partition[i]);
-
-      if(lig == 1) break;
-
-      PhyML_Printf("\n. (%c-%2d)> ",abc[lig],col+1);
-      Getstring_Stdin(c);
-      
-      switch(lig)
-	{
-	case 0 :
-	  {
-	    st->bl_partition[col] = atoi(c);
-	    break;
-	  }
-	default :
-	  {
-	    break;
-	  }
-	}
-
-      col++;
-
-      if(col == st->n_part)
-	{
-	  col = 0;
-	  lig++;
-	}
-    }
-    
-  n_groups = 0;
-  For(i,st->n_part) 
-    {
-      For(j,n_groups)
-	if(encountered_vals[j] == st->bl_partition[i])
-	  break;
-
-      if(j == n_groups) 
-	{
-	  encountered_vals[n_groups] = st->bl_partition[i];
-	  n_groups++;
-	}
-      st->bl_partition[i] = j;
-    }
-  
-  st->n_bl_part = n_groups;
-
-  Free(encountered_vals);
-  Free(c);
-  Free(abc);
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-phydbl PART_Br_Len_Brent(t_edge *st_b, int quickdirty, supert_tree *st)
-{
-  phydbl ax,  cx;
-  int part;
-  phydbl cur_l;
-
-
-  For(part,st->n_bl_part)
-    {
-      cur_l = st->bl[part][st_b->num];
-      
-      ax = 10.*cur_l;
-      cx = st->tree->mod->l_min;
-
-      Generic_Brent_Lk(&(st->bl[part][st_b->num]),
-		       ax,cx,
-		       st->tree->mod->s_opt->min_diff_lk_local,
-		       st->tree->mod->s_opt->brent_it_max,
-		       st->tree->mod->s_opt->quickdirty,
-		       Wrap_Part_Lk_At_Given_Edge,st_b,NULL,st,NO);
-      
-    }
-  return st->tree->c_lnL;
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-void PART_Initialise_Bl_Partition(supert_tree *st)
-{
-  int i,j;
-  
-  For(i,st->n_bl_part)
-    {
-      For(j,2*st->tree->n_otu-3)
-	{
-	  st->bl[i][j] = .1;
-	}
-    }
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-void PART_Optimize_Br_Len_Serie(t_node *st_a, t_node *st_d, t_edge *st_b, supert_tree *st)
-{
-  phydbl lk_init;
-  int i;
-
-  lk_init = st->tree->c_lnL;
-  
-  PART_Br_Len_Brent(st_b,0,st);
-
-  if(st->tree->c_lnL < lk_init - st->tree->mod->s_opt->min_diff_lk_local)
-    { 
-      PhyML_Printf("\n== %f -- %f",lk_init,st->tree->c_lnL);
-      PhyML_Printf("\n== Err. in file %s at line %d\n\n",__FILE__,__LINE__);
-      Warn_And_Exit("");
-    }
-    
-  if(st_d->tax) return;
-  else For(i,3) if(st_d->v[i] != st_a)
-    {
-      PART_Update_P_Lk(st_d->b[i],st_d,st);
-      PART_Optimize_Br_Len_Serie(st_d,st_d->v[i],st_d->b[i],st);
-    }
-
-  For(i,3) if((st_d->v[i] == st_a) && (!st_d->v[i]->tax)) PART_Update_P_Lk(st_d->b[i],st_d,st);
-
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-void PART_Update_P_Lk(t_edge *st_b, t_node *st_n, supert_tree *st)
-{
-  int i,dir;
-
-  dir = -1;
-  For(i,3) if((st_n->b[i]) && (st_n->b[i] == st_b)) {dir = i; break;}
-  
-  if(dir < 0)
-    {
-      PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__);
-      Warn_And_Exit("");
-    }
-
-  For(i,st->n_part)
-    {
-      if((st->map_st_node_in_gt[i][st_n->num][dir][0]) && (!st->map_st_node_in_gt[i][st_n->num][dir][0]->tax))
-	{	  
-	  Update_P_Lk(st->treelist->tree[i],
-		      st->map_st_edge_in_gt[i][st_b->num],
-		      st->map_st_node_in_gt[i][st_n->num][dir][0]);
-	}
-    }
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-void PART_Make_N_Swap(t_edge **st_b, int beg, int end, supert_tree *st)
-{
-  int i;
-  int dim;
-
-  dim = 2*st->tree->n_otu-2;
-
-  st->tree->n_swap = 0;
-  for(i=beg;i<end;i++)
-    {
-      if(st_b[i]->left->tax || st_b[i]->rght->tax)
-	{
-	  PhyML_Printf("\n. Edge %d is external.",st_b[i]->num);
-	  PhyML_Printf("\n. Err in file %s at line %d\n\n.",__FILE__,__LINE__);
-	  Warn_And_Exit("");
-	}
-      
-      PART_Swap(st_b[i]->nni->swap_node_v2->v[st->tree->t_dir[st_b[i]->nni->swap_node_v2->num*dim+st_b[i]->nni->swap_node_v1->num]],
-	      st_b[i]->nni->swap_node_v2,
-	      st_b[i]->nni->swap_node_v3,
-	      st_b[i]->nni->swap_node_v3->v[st->tree->t_dir[st_b[i]->nni->swap_node_v3->num*dim+st_b[i]->nni->swap_node_v4->num]],
-	      st);
-
-      Swap(st_b[i]->nni->swap_node_v2->v[st->tree->t_dir[st_b[i]->nni->swap_node_v2->num*dim+st_b[i]->nni->swap_node_v1->num]],
-	   st_b[i]->nni->swap_node_v2,
-	   st_b[i]->nni->swap_node_v3,
-	   st_b[i]->nni->swap_node_v3->v[st->tree->t_dir[st_b[i]->nni->swap_node_v3->num*dim+st_b[i]->nni->swap_node_v4->num]],
-	   st->tree);
-
-      PART_Do_Mapping(st);
-
-      st->tree->n_swap++;
-    }
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-void PART_Update_Bl(phydbl fact, supert_tree *st)
-{
-  int i,j;
-  
-  For(i,2*st->tree->n_otu-3)
-    {
-      For(j,st->n_part)
-	st->bl[st->bl_partition[j]][i] = 
-	st->bl_cpy[st->bl_partition[j]][i] + 
-	(st->bl0[st->bl_partition[j]][i] - st->bl_cpy[st->bl_partition[j]][i]) * fact;
-    }
-  PART_Set_Bl(st->bl,st);
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-void PART_Update_Bl_Swaped(t_edge **st_b, int n, supert_tree *st)
-{
-  int i,j;
-  
-  For(i,n)
-    {
-      For(j,st->n_part)
-	{
-	  st->bl[st->bl_partition[j]][st_b[i]->num] = 
-	    (st_b[i]->nni->best_conf == 1)?
-	    (st->bl1[st->bl_partition[j]][st_b[i]->num]):
-	    (st->bl2[st->bl_partition[j]][st_b[i]->num]);
-	}
-    }
-  PART_Set_Bl(st->bl,st);
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-void PART_Do_Mapping(supert_tree *st)
-{
-  int k;
-
-  Fill_Dir_Table(st->tree);
-  For(k,st->n_part)
-    {
-      Fill_Dir_Table(st->treelist->tree[k]);
-      PART_Match_St_Nodes_In_Gt(st->treelist->tree[k],st);	      
-      PART_Match_St_Edges_In_Gt(st->treelist->tree[k],st);	      
-      PART_Map_St_Nodes_In_Gt(st->treelist->tree[k],st);
-      PART_Map_St_Edges_In_Gt(st->treelist->tree[k],st);
-      PART_Map_Gt_Edges_In_St(st->treelist->tree[k],st);
-    }
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-void PART_Print_Bl(supert_tree *st)
-{
-  int i,j;
-  
-  For(j,2*st->tree->n_otu-3)
-    { 
-      PhyML_Printf("\n. t_edge %4d ",j);
-      For(i,st->n_bl_part)
-	{
-	  PhyML_Printf("%f ",st->bl[i][j]);
-	}
-    }
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
diff --git a/src/mg.h b/src/mg.h
index 734283c..63079f9 100644
--- a/src/mg.h
+++ b/src/mg.h
@@ -5,56 +5,5 @@
 
 #include "utilities.h"
 
-void Menu_Supertree(option *input);
-void PART_Print_Nodes(t_node *a, t_node *d, supert_tree *st);
-supert_tree *PART_Make_Supert_tree_Light(option *input);
-void PART_Make_Supert_tree_Full(supert_tree *st, option *input, calign **data);
-void PART_Get_List_Of_Reachable_Tips(t_node *a, t_node *d, calign **data, supert_tree *st);
-void PART_Get_List_Of_Reachable_Tips_Pre(t_node *a, t_node *d, supert_tree *st);
-void PART_Get_List_Of_Reachable_Tips_Post(t_node *a, t_node *d, supert_tree *st);
-void PART_Prune_St_Topo(t_tree *tree, calign *data, supert_tree *st);
-void PART_Match_St_Nodes_In_Gt_Recurr(t_node *a_gt, t_node *d_gt, t_node *a_st, t_node *d_st, t_tree *gt, supert_tree *st);
-void PART_Match_St_Nodes_In_Gt(t_tree *tree, supert_tree *st);
-void PART_Match_St_Edges_In_Gt(t_tree *gt, supert_tree *st);
-void PART_Match_St_Edges_In_Gt_Recurr(t_node *a, t_node *d, t_node *a_st, t_node *d_st, t_tree *gt, supert_tree *st);
-void PART_Simu(supert_tree *tr);
-int PART_Mov_Backward_Topo_Bl(supert_tree *st, phydbl lk_old, t_edge **tested_b, int n_tested);
-int PART_Get_Species_Found_In_St(supert_tree *st, calign *data);
-void PART_Map_St_Nodes_In_Gt_Pre(t_node *a_st, t_node *d_st, t_tree *gt, supert_tree *st);
-void PART_Map_St_Nodes_In_Gt_Post(t_node *a_st, t_node *d_st, t_tree *gt, supert_tree *st);
-void PART_Map_St_Nodes_In_Gt(t_tree *gt, supert_tree *st);
-void PART_Map_St_Nodes_In_Gt_One_Edge(t_node *a_st, t_node *d_st, t_edge *b_st, t_tree *gt, supert_tree *st);
-void PART_Map_St_Edges_In_Gt(t_tree *gt, supert_tree *st);
-phydbl PART_Lk(supert_tree *st);
-int PART_Pars(supert_tree *st);
-int PART_Spr(phydbl init_lnL, supert_tree *st);
-void PART_Speed_Spr(supert_tree *st);
-int Map_Spr_Move(t_edge *st_pruned, t_edge *st_target, t_node *st_link, t_tree *gt, supert_tree *st);
-void PART_Test_All_Spr_Targets(t_edge *pruned, t_node *n_link, supert_tree *st);
-void PART_Test_One_Spr_Target_Recur(t_node *a, t_node *d, t_edge *target, t_edge *pruned, t_node *n_link, supert_tree *st);
-void PART_Test_One_Spr_Target(t_edge *st_p, t_edge *st_t, t_node *n_link, supert_tree *st);
-int PART_Test_List_Of_Regraft_Pos(t_spr **st_spr_list, int list_size, supert_tree *st);
-int PART_Try_One_Spr_Move(t_spr *st_move, supert_tree *st);
-void PART_Map_Gt_Edges_In_St(t_tree *gt, supert_tree *st);
-void PART_NNI(t_edge *st_b, supert_tree *st);
-void PART_Swap(t_node *st_a, t_node *st_b, t_node *st_c, t_node *st_d, supert_tree *st);
-void PART_Set_Bl(phydbl **bl, supert_tree *st);
-void PART_Restore_Br_Len(supert_tree *st);
-void PART_Record_Br_Len(supert_tree *st);
-phydbl PART_Lk_At_Given_Edge(t_edge *st_b, supert_tree *st);
-phydbl PART_Update_Lk_At_Given_Edge(t_edge *st_b, supert_tree *st);
-void PART_Fill_Model_Partitions_Table(supert_tree *st);
-phydbl PART_Br_Len_Brent(t_edge *st_b, int quickdirty, supert_tree *tree);
-void PART_Initialise_Bl_Partition(supert_tree *st);
-void PART_Update_P_Lk(t_edge *st_b, t_node *st_n, supert_tree *st);
-void PART_Optimize_Br_Len_Serie(t_node *st_a, t_node *st_d, t_edge *st_b, supert_tree *st);
-void PART_Update_Bl_Swaped(t_edge **st_b, int n, supert_tree *st);
-void PART_Update_Bl(phydbl fact, supert_tree *st);
-void PART_Make_N_Swap(t_edge **st_b, int beg, int end, supert_tree *st);
-void PART_Do_Mapping(supert_tree *st);
-void PART_Update_PMat(t_edge *st_b, supert_tree *st);
-void PART_Print_Bl(supert_tree *st);
-void PART_Check_Extra_Taxa(supert_tree *st);
-int PART_main(int argc, char **argv);
 #endif
 
diff --git a/src/mixt.c b/src/mixt.c
index 5aa980a..c817d60 100644
--- a/src/mixt.c
+++ b/src/mixt.c
@@ -33,9 +33,10 @@ void MIXT_Chain_All(t_tree *mixt_tree)
       MIXT_Chain_Scalar_Dbl(curr->mod->kappa,next->mod->kappa);
       MIXT_Chain_Scalar_Dbl(curr->mod->lambda,next->mod->lambda);
       MIXT_Chain_Scalar_Dbl(curr->mod->br_len_mult,next->mod->br_len_mult);
+      MIXT_Chain_Scalar_Dbl(curr->mod->br_len_mult_unscaled,next->mod->br_len_mult_unscaled);
       MIXT_Chain_Scalar_Dbl(curr->mod->mr,next->mod->mr);
       MIXT_Chain_Vector_Dbl(curr->mod->Pij_rr,next->mod->Pij_rr);
-      MIXT_Chain_Vector_Dbl(curr->mod->user_b_freq,next->mod->user_b_freq);
+      MIXT_Chain_Vector_Dbl(curr->mod->e_frq->user_b_freq,next->mod->e_frq->user_b_freq);
       For(i,2*mixt_tree->n_otu-1) MIXT_Chain_Scalar_Dbl(curr->a_edges[i]->l,next->a_edges[i]->l);
       For(i,2*mixt_tree->n_otu-1) MIXT_Chain_Scalar_Dbl(curr->a_edges[i]->l_old,next->a_edges[i]->l_old);
       For(i,2*mixt_tree->n_otu-1) MIXT_Chain_Scalar_Dbl(curr->a_edges[i]->l_var,next->a_edges[i]->l_var);
@@ -64,7 +65,6 @@ void MIXT_Chain_All(t_tree *mixt_tree)
 
   Make_Rmat_Weight(mixt_tree);
   Make_Efrq_Weight(mixt_tree);
-
 }
 
 //////////////////////////////////////////////////////////////
@@ -75,6 +75,7 @@ void MIXT_Chain_Edges(t_tree *tree)
   int i;
   t_edge *b;
 
+
   For(i,2*tree->n_otu-1)
     {
       b = tree->a_edges[i];
@@ -84,6 +85,16 @@ void MIXT_Chain_Edges(t_tree *tree)
       if(tree->next_mixt) b->next_mixt  = tree->next_mixt->a_edges[i];
       if(tree->prev_mixt) b->prev_mixt  = tree->prev_mixt->a_edges[i];
     }
+
+  if(tree->e_root != NULL)
+    {
+      b = tree->e_root;
+
+      if(tree->next)      b->next       = tree->next->e_root;
+      if(tree->prev)      b->prev       = tree->prev->e_root;
+      if(tree->next_mixt) b->next_mixt  = tree->next_mixt->e_root;
+      if(tree->prev_mixt) b->prev_mixt  = tree->prev_mixt->e_root;
+    }
 }
 
 //////////////////////////////////////////////////////////////
@@ -103,6 +114,17 @@ void MIXT_Chain_Nodes(t_tree *tree)
       if(tree->next_mixt) n->next_mixt  = tree->next_mixt->a_nodes[i];
       if(tree->prev_mixt) n->prev_mixt  = tree->prev_mixt->a_nodes[i];
     }
+
+
+  if(tree->n_root != NULL)
+    {
+      n = tree->n_root;
+
+      if(tree->next)      n->next       = tree->next->n_root;
+      if(tree->prev)      n->prev       = tree->prev->n_root;
+      if(tree->next_mixt) n->next_mixt  = tree->next_mixt->n_root;
+      if(tree->prev_mixt) n->prev_mixt  = tree->prev_mixt->n_root;
+    }
 }
 
 //////////////////////////////////////////////////////////////
@@ -447,85 +469,47 @@ void MIXT_Chain_RAS(t_ras *curr, t_ras *next)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-void MIXT_Turn_Branches_OnOff(int onoff, t_tree *mixt_tree)
+void MIXT_Turn_Branches_OnOff_In_All_Elem(int onoff, t_tree *mixt_tree)
 {
-  int i;
   t_tree *tree;
 
-  if(mixt_tree->is_mixt_tree == NO)
-    {
-      PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__);
-      Exit("\n");
-    }
-
+  /*! Turn all branches to ON state */
   tree = mixt_tree;
-
   do
     {
-      For(i,2*tree->n_otu-1) tree->a_edges[i]->l->onoff = onoff;
-      tree = tree->next;
+      MIXT_Turn_Branches_OnOff_In_One_Elem(ON,tree);
+      tree = tree->next_mixt;
     }
-  while(tree && tree->is_mixt_tree == NO);
+  while(tree);
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-phydbl *MIXT_Get_Lengths_Of_This_Edge(t_edge *mixt_b, t_tree *mixt_tree)
+void MIXT_Turn_Branches_OnOff_In_One_Elem(int onoff, t_tree *mixt_tree)
 {
-  phydbl *lens;
-  t_edge *b;
+  int i;
   t_tree *tree;
-  int n_lens;
 
-  lens = NULL;
-  n_lens = 0;
+  if(mixt_tree->is_mixt_tree == NO)
+    {
+      PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__);
+      Exit("\n");
+    }
 
-  b = mixt_b;
   tree = mixt_tree;
+
   do
     {
-
-      if(!lens) lens = (phydbl *)mCalloc(2,sizeof(phydbl));
-      else      lens = (phydbl *)realloc(lens,(n_lens+2)*sizeof(phydbl));
-
-      lens[n_lens] = b->l->v;
-      lens[n_lens+1] = b->l_var->v;
-
-      n_lens+=2;
-      b = b->next;
+      For(i,2*tree->n_otu-1) tree->a_edges[i]->l->onoff = onoff;
       tree = tree->next;
     }
-  while(b);
-
-  return(lens);
+  while(tree && tree->is_mixt_tree == NO);
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-void MIXT_Set_Lengths_Of_This_Edge(phydbl *lens, t_edge *mixt_b, t_tree *mixt_tree)
-{
-  t_edge *b;
-  int n_lens;
-  t_tree *tree;
-
-  n_lens = 0;
-
-  tree = mixt_tree;
-  b = mixt_b;
-  do
-    {
-      b->l->v = lens[n_lens];
-      b->l_var->v = lens[n_lens+1];
-
-      n_lens+=2;
-      b = b->next;
-      tree = tree->next;
-    }
-  while(b);
-}
-
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
@@ -538,6 +522,10 @@ void MIXT_Post_Order_Lk(t_node *mixt_a, t_node *mixt_d, t_tree *mixt_tree)
   a    = mixt_a;
   d    = mixt_d;
 
+  assert(a);
+  assert(d);
+  assert(tree);
+
   do
     {
       if(tree->is_mixt_tree)
@@ -547,6 +535,10 @@ void MIXT_Post_Order_Lk(t_node *mixt_a, t_node *mixt_d, t_tree *mixt_tree)
           d    = d->next;
         }
 
+      assert(a);
+      assert(d);
+      assert(tree);
+
       if(tree->mod->ras->invar == NO) Post_Order_Lk(a,d,tree);
 
       tree = tree->next;
@@ -569,6 +561,10 @@ void MIXT_Pre_Order_Lk(t_node *mixt_a, t_node *mixt_d, t_tree *mixt_tree)
   a    = mixt_a;
   d    = mixt_d;
 
+  assert(a);
+  assert(d);
+  assert(tree);
+
   do
     {
       if(tree->is_mixt_tree)
@@ -578,6 +574,11 @@ void MIXT_Pre_Order_Lk(t_node *mixt_a, t_node *mixt_d, t_tree *mixt_tree)
           d    = d->next;
         }
 
+
+      assert(a);
+      assert(d);
+      assert(tree);
+
       if(tree->mod->ras->invar == NO) Pre_Order_Lk(a,d,tree);
 
       tree = tree->next;
@@ -607,6 +608,8 @@ phydbl MIXT_Lk(t_edge *mixt_b, t_tree *mixt_tree)
   int k,l;
   int dim1,dim2;
   phydbl r_mat_weight_sum, e_frq_weight_sum, sum_probas;
+  int piecewise_exponent;
+  phydbl multiplier;
 
   tree            = NULL;
   b               = NULL;
@@ -619,15 +622,15 @@ phydbl MIXT_Lk(t_edge *mixt_b, t_tree *mixt_tree)
     {
       if(!cpy_mixt_b) Set_Model_Parameters(mixt_tree->mod);      
       
-      Set_Br_Len_Var(mixt_tree);
+      Set_Br_Len_Var(mixt_b,mixt_tree);
 
       if(!cpy_mixt_b)
         {
           For(br,2*mixt_tree->n_otu-3) Update_PMat_At_Given_Edge(mixt_tree->a_edges[br],mixt_tree);
-          if(mixt_tree->n_root)
+          if(mixt_tree->n_root && mixt_tree->ignore_root == NO)
             {
-              Update_PMat_At_Given_Edge(mixt_tree->n_root->b[1],tree);
-              Update_PMat_At_Given_Edge(mixt_tree->n_root->b[2],tree);
+              Update_PMat_At_Given_Edge(mixt_tree->n_root->b[1],mixt_tree);
+              Update_PMat_At_Given_Edge(mixt_tree->n_root->b[2],mixt_tree);
             }
         }
       else
@@ -639,33 +642,64 @@ phydbl MIXT_Lk(t_edge *mixt_b, t_tree *mixt_tree)
         {
           if(mixt_tree->n_root)
             {
-              MIXT_Post_Order_Lk(mixt_tree->n_root,mixt_tree->n_root->v[1],mixt_tree);
-              MIXT_Post_Order_Lk(mixt_tree->n_root,mixt_tree->n_root->v[2],mixt_tree);
-
-              MIXT_Update_P_Lk(mixt_tree,mixt_tree->n_root->b[1],mixt_tree->n_root);
-              MIXT_Update_P_Lk(mixt_tree,mixt_tree->n_root->b[2],mixt_tree->n_root);
-
-              if(tree->both_sides == YES)
+              if(mixt_tree->ignore_root == NO)
+                {
+                  MIXT_Post_Order_Lk(mixt_tree->n_root,mixt_tree->n_root->v[1],mixt_tree);
+                  MIXT_Post_Order_Lk(mixt_tree->n_root,mixt_tree->n_root->v[2],mixt_tree);
+                  
+                  MIXT_Update_P_Lk(mixt_tree,mixt_tree->n_root->b[1],mixt_tree->n_root);
+                  MIXT_Update_P_Lk(mixt_tree,mixt_tree->n_root->b[2],mixt_tree->n_root);
+                
+                  if(mixt_tree->both_sides == YES)
+                    {
+                      MIXT_Pre_Order_Lk(mixt_tree->n_root,mixt_tree->n_root->v[1],mixt_tree);              
+                      MIXT_Pre_Order_Lk(mixt_tree->n_root,mixt_tree->n_root->v[2],mixt_tree);
+                    }
+                }
+              else
                 {
-                  MIXT_Pre_Order_Lk(mixt_tree->n_root,mixt_tree->n_root->v[1],mixt_tree);              
-                  MIXT_Pre_Order_Lk(mixt_tree->n_root,mixt_tree->n_root->v[2],mixt_tree);
+                  MIXT_Post_Order_Lk(mixt_tree->e_root->rght,
+                                     mixt_tree->e_root->left,
+                                     mixt_tree);
+                  MIXT_Post_Order_Lk(mixt_tree->e_root->left,
+                                     mixt_tree->e_root->rght,
+                                     mixt_tree);
+                  if(mixt_tree->both_sides == YES)
+                    {
+                      MIXT_Pre_Order_Lk(mixt_tree->e_root->rght,
+                                         mixt_tree->e_root->left,
+                                         mixt_tree);
+                      MIXT_Pre_Order_Lk(mixt_tree->e_root->left,
+                                         mixt_tree->e_root->rght,
+                                         mixt_tree);
+                    }
                 }
             }
           else
             {
               MIXT_Post_Order_Lk(mixt_tree->a_nodes[0],mixt_tree->a_nodes[0]->v[0],mixt_tree);
               if(mixt_tree->both_sides == YES)
-                MIXT_Pre_Order_Lk(mixt_tree->a_nodes[0],
-                                  mixt_tree->a_nodes[0]->v[0],
-                                  mixt_tree);
+                {
+                  MIXT_Pre_Order_Lk(mixt_tree->a_nodes[0],
+                                    mixt_tree->a_nodes[0]->v[0],
+                                    mixt_tree);
+                }
             }
         }
 
-
       if(!cpy_mixt_b) 
         {
-          if(mixt_tree->n_root) mixt_b = (mixt_tree->n_root->v[1]->tax == NO)?(mixt_tree->n_root->b[2]):(mixt_tree->n_root->b[1]);
-          else                  mixt_b = mixt_tree->a_nodes[0]->b[0];
+          if(mixt_tree->n_root) 
+            {
+              if(mixt_tree->ignore_root == NO)
+                mixt_b = (mixt_tree->n_root->v[1]->tax == NO)?(mixt_tree->n_root->b[2]):(mixt_tree->n_root->b[1]);
+              else
+                mixt_b = mixt_tree->e_root;
+            }          
+          else                  
+            {
+              mixt_b = mixt_tree->a_nodes[0]->b[0];
+            }
         }
 
       sum_scale_left_cat = (phydbl *)mCalloc(MAX(mixt_tree->mod->ras->n_catg,mixt_tree->mod->n_mixt_classes),sizeof(phydbl));
@@ -678,13 +712,13 @@ phydbl MIXT_Lk(t_edge *mixt_b, t_tree *mixt_tree)
       mixt_tree->c_lnL = .0;
       dim1 = mixt_tree->mod->ns;
       dim2 = mixt_tree->mod->ns;
+      
 
       For(site,mixt_tree->n_pattern)
         {
           b    = mixt_b->next;
           tree = mixt_tree->next;
 
-
           /*! Skip calculations if model has zero rate */
           while(tree->mod->ras->invar == YES)
             {
@@ -792,6 +826,7 @@ phydbl MIXT_Lk(t_edge *mixt_b, t_tree *mixt_tree)
           while(tree && tree->is_mixt_tree == NO);
 
 
+
           max_sum_scale =  (phydbl)BIG;
           min_sum_scale = -(phydbl)BIG;
 
@@ -844,11 +879,12 @@ phydbl MIXT_Lk(t_edge *mixt_b, t_tree *mixt_tree)
           if(min_sum_scale > max_sum_scale) min_sum_scale = max_sum_scale;
 
           fact_sum_scale = (int)((max_sum_scale + min_sum_scale) / 2);
-
+          mixt_tree->fact_sum_scale[site] = fact_sum_scale;
 
           /*! Populate the mixt_tree->site_lk_cat[class] table after
             scaling */
 
+
           tree  = mixt_tree->next;
           b     = mixt_b->next;
           class = 0;
@@ -874,6 +910,7 @@ phydbl MIXT_Lk(t_edge *mixt_b, t_tree *mixt_tree)
             }
           while(tree && tree->is_mixt_tree == NO);
 
+          
           tree    = mixt_tree->next;
           b       = mixt_b->next;
           class   = 0;
@@ -894,20 +931,14 @@ phydbl MIXT_Lk(t_edge *mixt_b, t_tree *mixt_tree)
                 tree->mod->r_mat_weight->v / r_mat_weight_sum *
                 tree->mod->e_frq_weight->v / e_frq_weight_sum /
                 sum_probas;
-
-                /* mixt_tree->site_lk_cat[class] * */
-                /* mixt_tree->mod->ras->gamma_r_proba->v[tree->mod->ras->parent_class_number]; */
-
-              /* printf("\n. %f %f %f %f ", */
-              /*        tree->mod->r_mat_weight->v,r_mat_weight_sum, */
-              /*        tree->mod->e_frq_weight->v,e_frq_weight_sum); */
-
+              
               tree = tree->next;
               b    = b->next;
               class++;
             }
           while(tree && tree->is_mixt_tree == NO);
 
+
           /* Scaling for invariants */
           if(mixt_tree->mod->ras->invar == YES)
             {
@@ -942,11 +973,11 @@ phydbl MIXT_Lk(t_edge *mixt_b, t_tree *mixt_tree)
 
           log_site_lk = LOG(site_lk) - (phydbl)LOG2 * fact_sum_scale;
 
-
           int mixt_class = 0;
           int rate_class = 0;
           For(rate_class,mixt_tree->mod->ras->n_catg)
             {
+              mixt_tree->unscaled_site_lk_cat[rate_class*mixt_tree->n_pattern + site] = 0.0;
               mixt_class = 0;
               tree = mixt_tree->next;
               do
@@ -954,15 +985,16 @@ phydbl MIXT_Lk(t_edge *mixt_b, t_tree *mixt_tree)
                   if(tree->mod->ras->parent_class_number == rate_class)
                     {
                       mixt_tree->unscaled_site_lk_cat[rate_class*mixt_tree->n_pattern + site] +=
-                        // TO DO: add correct weight here
-                        LOG(mixt_tree->site_lk_cat[mixt_class]) -
-                        (phydbl)LOG2 * fact_sum_scale;
+                        LOG(mixt_tree->site_lk_cat[rate_class]);
                       break;
                     }
                   mixt_class++;
                   tree = tree->next;
                 }
               while(tree && tree->is_mixt_tree == NO);
+
+              mixt_tree->unscaled_site_lk_cat[rate_class*mixt_tree->n_pattern + site] = 
+                EXP(mixt_tree->unscaled_site_lk_cat[rate_class*mixt_tree->n_pattern + site]);
             }
 
           if(isinf(log_site_lk) || isnan(log_site_lk))
@@ -977,8 +1009,39 @@ phydbl MIXT_Lk(t_edge *mixt_b, t_tree *mixt_tree)
               PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__);
               Exit("\n");
             }
-
-          mixt_tree->cur_site_lk[site] = log_site_lk;
+          
+          if(fact_sum_scale >= 0)
+            {
+              mixt_tree->cur_site_lk[site] = site_lk;
+              exponent = -fact_sum_scale;
+              do
+                {
+                  piecewise_exponent = MAX(exponent,-63);
+                  multiplier = 1. / (phydbl)((unsigned long long)(1) << -piecewise_exponent);
+                  mixt_tree->cur_site_lk[site] *= multiplier;
+                  exponent -= piecewise_exponent;
+                }
+              while(exponent != 0);
+            }
+          else
+            {
+              mixt_tree->cur_site_lk[site] = site_lk;
+              exponent = fact_sum_scale;
+              do
+                {
+                  piecewise_exponent = MIN(exponent,63);
+                  multiplier = (phydbl)((unsigned long long)(1) << piecewise_exponent);
+                  mixt_tree->cur_site_lk[site] *= multiplier;
+                  exponent -= piecewise_exponent;
+                }
+              while(exponent != 0);
+            }
+          
+          // ... or using the log-likelihood
+          if(isinf(site_lk) || isnan(site_lk))
+            {
+              mixt_tree->cur_site_lk[site] = EXP(log_site_lk);
+            }
 
           /* Multiply log likelihood by the number of times this site pattern is found in the data */
           mixt_tree->c_lnL_sorted[site] = mixt_tree->data->wght[site]*log_site_lk;
@@ -991,6 +1054,8 @@ phydbl MIXT_Lk(t_edge *mixt_b, t_tree *mixt_tree)
       Free(sum_scale_left_cat);
       Free(sum_scale_rght_cat);
 
+      /* printf("\n. <><><> LNL %f",mixt_tree->c_lnL); */
+
       mixt_tree = mixt_tree->next_mixt;
       mixt_b    = mixt_b->next_mixt;
     }
@@ -1075,6 +1140,39 @@ void MIXT_Update_P_Lk(t_tree *mixt_tree, t_edge *mixt_b, t_node *mixt_d)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
+void MIXT_Update_P_Pars(t_tree *mixt_tree, t_edge *mixt_b, t_node *mixt_d)
+{
+  t_tree *tree;
+  t_edge *b;
+  t_node *d;
+
+  tree = mixt_tree;
+  b    = mixt_b;
+  d    = mixt_d;
+
+  do
+    {
+      if(tree->is_mixt_tree)
+        {
+          tree = tree->next;
+          b    = b->next;
+          d    = d->next;
+        }
+
+      Update_P_Pars(tree,b,d);
+
+      tree = tree->next;
+      b    = b->next;
+      d    = d->next;
+
+    }
+  while(tree);
+
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
 void MIXT_Update_PMat_At_Given_Edge(t_edge *mixt_b, t_tree *mixt_tree)
 {
   t_tree *tree;
@@ -1111,14 +1209,14 @@ int *MIXT_Get_Number_Of_Classes_In_All_Mixtures(t_tree *mixt_tree)
 
   if(mixt_tree->is_mixt_tree == YES)
     {
-  n_catg = NULL;
-  tree = mixt_tree;
-  class = 0;
-  do
-    {
-      if(!class) n_catg = (int *)mCalloc(1,sizeof(int));
-      else       n_catg = (int *)realloc(n_catg,(class+1)*sizeof(int));
-
+      n_catg = NULL;
+      tree = mixt_tree;
+      class = 0;
+      do
+        {
+          if(!class) n_catg = (int *)mCalloc(1,sizeof(int));
+          else       n_catg = (int *)realloc(n_catg,(class+1)*sizeof(int));
+          
           tree = tree->next;
           
           n_catg[class]=0;
@@ -1397,7 +1495,7 @@ void MIXT_Prune_Subtree(t_node *mixt_a, t_node *mixt_d, t_edge **mixt_target, t_
   t_edge *target, *residual;
   t_tree *tree;
 
-  MIXT_Turn_Branches_OnOff(OFF,mixt_tree);
+  MIXT_Turn_Branches_OnOff_In_One_Elem(OFF,mixt_tree);
 
   tree     = mixt_tree;
   a        = mixt_a;
@@ -1432,7 +1530,7 @@ void MIXT_Prune_Subtree(t_node *mixt_a, t_node *mixt_d, t_edge **mixt_target, t_
     to Prune_Subtree such that, if branches of mixt_tree->next
     point to those of mixt_tree, they are set to OFF when calling
     Prune */
-  MIXT_Turn_Branches_OnOff(ON,mixt_tree);
+  MIXT_Turn_Branches_OnOff_In_One_Elem(ON,mixt_tree);
 
 }
 
@@ -1445,7 +1543,7 @@ void MIXT_Graft_Subtree(t_edge *mixt_target, t_node *mixt_link, t_edge *mixt_res
   t_node *link;
   t_tree *tree;
 
-  MIXT_Turn_Branches_OnOff(OFF,mixt_tree);
+  MIXT_Turn_Branches_OnOff_In_One_Elem(OFF,mixt_tree);
 
   tree     = mixt_tree;
   target   = mixt_target;
@@ -1477,7 +1575,7 @@ void MIXT_Graft_Subtree(t_edge *mixt_target, t_node *mixt_link, t_edge *mixt_res
     to Graft_Subtree such that, if branches of mixt_tree->next
     point to those of mixt_tree, they are set to OFF when calling
     Graft */
-  MIXT_Turn_Branches_OnOff(ON,mixt_tree);
+  MIXT_Turn_Branches_OnOff_In_One_Elem(ON,mixt_tree);
 }
 
 //////////////////////////////////////////////////////////////
@@ -1510,13 +1608,8 @@ void MIXT_Br_Len_Brent(phydbl prop_min,
     }
   while(tree);
 
-  tree = mixt_tree;
-  do
-    {
-      MIXT_Turn_Branches_OnOff(ON,tree);
-      tree = tree->next_mixt;
-    }
-  while(tree);
+
+  MIXT_Turn_Branches_OnOff_In_All_Elem(ON,mixt_tree);
 }
 
 /*////////////////////////////////////////////////////////////
@@ -1665,7 +1758,26 @@ void MIXT_Set_Alias_Subpatt(int onoff, t_tree *mixt_tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-void MIXT_Check_Single_Edge_Lens(t_tree *mixt_tree)
+void MIXT_Check_Edge_Lens_In_All_Elem(t_tree *mixt_tree)
+{
+  t_tree *tree;
+
+  /*! Check that all the edges in a mixt_tree at pointing
+    to a single set of lengths
+  */
+  tree = mixt_tree;
+  do
+    {
+      MIXT_Check_Edge_Lens_In_One_Elem(tree);
+      tree = tree->next_mixt;
+    }
+  while(tree);
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void MIXT_Check_Edge_Lens_In_One_Elem(t_tree *mixt_tree)
 {
   t_tree *tree;
   int i;
@@ -1699,19 +1811,20 @@ int MIXT_Pars(t_edge *mixt_b, t_tree *mixt_tree)
   t_edge *b;
   t_tree *tree;
 
-  b    = mixt_b;
-  tree = mixt_tree;
+  b                 = mixt_b;
+  tree              = mixt_tree;
+  mixt_tree->c_pars = 0;
 
   do
     {
-      b    = b->next_mixt;
-      tree = tree->next_mixt;
-
-      if(tree)
+      if(tree->next)
         {
-          Pars(b,tree);
-          mixt_tree->c_pars += tree->c_pars;
+          Pars(b?b->next:NULL,tree->next);
+          mixt_tree->c_pars += tree->next->c_pars;      
         }
+      
+      if(mixt_b != NULL) b = b->next_mixt;
+      tree = tree->next_mixt;
     }
   while(tree);
 
@@ -1745,7 +1858,7 @@ void MIXT_Bootstrap(char *best_tree, xml_node *root)
       xml_attr *boot_attr,*seqfile_attr,*out_attr,*boot_out_attr;
       char *orig_align,*boot_out_file_name,*xml_boot_file_name,*buff;
       FILE *boot_fp_in_align,*xml_boot_file_fp;
-      option *io;
+      option *io,*dum;
       align **boot_data,**orig_data;
       int position,elem;
       xml_node *boot_root;
@@ -1867,7 +1980,8 @@ void MIXT_Bootstrap(char *best_tree, xml_node *root)
           fclose(xml_boot_file_fp);
 
           /*! Reconstruct the tree */
-          PhyML_XML(xml_boot_file_name);
+          dum = PhyML_XML(xml_boot_file_name);
+          Free(dum);
 
           /*! Remove the bootstrap alignment files */
           p_elem = boot_root;
@@ -1971,10 +2085,15 @@ phydbl MIXT_Get_Sum_Of_Probas_Across_Mixtures(phydbl r_mat_weight_sum, phydbl e_
   tree = mixt_tree->next;
   do
     {
+      // e.g., if mixture has two classes, one of these 
+      // corresponding to invariable sites. We need to skip it.
+      if(tree->mod->ras->invar == YES) tree = tree->next;
+          
       sum +=
         mixt_tree->mod->ras->gamma_r_proba->v[tree->mod->ras->parent_class_number] *
         tree->mod->r_mat_weight->v / r_mat_weight_sum *
         tree->mod->e_frq_weight->v / e_frq_weight_sum;
+      
 
       tree = tree->next;
 
@@ -1987,18 +2106,65 @@ phydbl MIXT_Get_Sum_Of_Probas_Across_Mixtures(phydbl r_mat_weight_sum, phydbl e_
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-void MIXT_Set_Br_Len_Var(t_tree *mixt_tree)
+void MIXT_Set_Br_Len_Var(t_edge *mixt_b, t_tree *mixt_tree)
 {
   t_tree *tree;
-
-  tree = mixt_tree->next;
   
+  if(mixt_b != NULL)
+    {
+      t_edge *b;
+  
+      tree = mixt_tree->next;
+      b    = mixt_b->next;
+
+      do
+        {
+          Set_Br_Len_Var(b,tree);
+          tree = tree->next;
+          b    = b->next;
+        }
+      while(tree);
+    }
+  else
+    {
+      tree = mixt_tree->next;
+
+      do
+        {
+          Set_Br_Len_Var(NULL,tree);
+          tree = tree->next;
+        }
+      while(tree);
+
+    }
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void MIXT_Add_Root(t_edge *mixt_b, t_tree *mixt_tree)
+{
+  t_tree *tree;
+  t_edge *b;
+
+  tree = mixt_tree;
+  b    = mixt_b;
   do
     {
-      Set_Br_Len_Var(tree);
+      if(tree->is_mixt_tree) 
+        {
+          tree = tree->next;
+          b    = b->next;
+        }
+
+      // Condition is true when tree is not chained
+      if(b == NULL) break; 
+
+      Add_Root(b,tree);
       tree = tree->next;
+      b    = b->next;
     }
-  while(tree);
+  while(tree && tree->is_mixt_tree == NO);
   
 }
 
@@ -2046,14 +2212,427 @@ void MIXT_Update_Br_Len_Multipliers(t_mod *mod)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
+void MIXT_Init_Model(t_tree *mixt_tree)
+{
+  t_mod *mod,*mixt_mod;
+  option *io;
+  t_tree *tree;
+
+  assert(mixt_tree);
+
+  mixt_mod = mixt_tree->mod;
+  io       = mixt_tree->io;
+
+  mod = mixt_mod;
+  do
+    {
+      Init_Model(mod->io->cdata,mod,io);
+      mod = mod->next;
+    }
+  while(mod);
+
+  tree = mixt_tree;
+  do
+    {
+      if(tree->next_mixt)
+        {
+          tree->mod->next_mixt = tree->next_mixt->mod;
+          tree->next_mixt->mod->prev_mixt = tree->mod;
+        }
+      tree = tree->next_mixt;
+    }
+  while(tree);
+}
+
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
+void MIXT_Check_Model_Validity(t_tree *mixt_tree)
+{
+  // Verify that models associated to distinct data partition elements do not 
+  // share the same empirical character frequencies.
+  
+  t_mod *mod_in, *mod_out;
+
+  mod_out = mixt_tree->mod;
+
+  do
+    {
+      mod_in = mod_out;
+      do
+        {
+          if(mod_in->io->cdata != mod_out->io->cdata)
+            {
+              if(mod_in->e_frq == mod_out->e_frq)
+                {
+                  if(mod_in->io->datatype == NT && mod_in->e_frq->user_state_freq == NO)
+                    {
+                      PhyML_Printf("\n== A vector of observed nucleotide frequencies should correspond ");
+                      PhyML_Printf("\n== to one data set only. If you are using the XML interface, ");
+                      PhyML_Printf("\n== please amend your file accordingly.");          
+                      Exit("\n");
+                    }
+                  else if(mod_in->io->datatype == AA && mod_in->e_frq->empirical_state_freq == YES)
+                    {
+                      PhyML_Printf("\n== A vector of observed amino-acid frequencies should correspond ");
+                      PhyML_Printf("\n== to one data set only. If you are using the XML interface, ");
+                      PhyML_Printf("\n== please amend your file accordingly.");          
+                      Exit("\n");
+                    }
+                }
+            }
+          mod_in = mod_in->next;
+        }
+      while(mod_in);      
+      mod_out = mod_out->next;
+    }
+  while(mod_out);
+
+
+}
+
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
+t_tree *MIXT_Starting_Tree(t_tree *mixt_tree)
+{
+  t_tree *tree;
+
+  tree = NULL;
+
+  switch(mixt_tree->io->in_tree)
+    {
+    case 2: // user-defined input tree 
+      {
+        assert(mixt_tree->io->fp_in_tree);
+        
+        // Copy user tree to all tree structures
+        tree = Read_User_Tree(mixt_tree->io->cdata,
+                              mixt_tree->mod,
+                              mixt_tree->io);
+        break;
+      }
+    case 1: case 0:
+      {
+        // Build a BioNJ tree from the analysis of
+        // the first partition element
+        tree = Dist_And_BioNJ(mixt_tree->data,
+                              mixt_tree->mod,
+                              mixt_tree->io);
+        break;
+      }
+    default : assert(FALSE);
+   }
+  
+  return tree;
+}
+
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
+void MIXT_Connect_Cseqs_To_Nodes(t_tree *mixt_tree)
+{
+  t_tree *tree;
+  
+  tree = mixt_tree;
+  do
+    {
+      if(tree != mixt_tree) Copy_Tree(mixt_tree,tree);
+      Connect_CSeqs_To_Nodes(tree->data,mixt_tree->io,tree);
+      tree = tree->next;
+    }
+  while(tree);
+  
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
 
+void MIXT_Init_T_Beg(t_tree *mixt_tree)
+{
+  t_tree *tree;
 
+  /*! Initialize t_beg in each mixture tree */
+  tree = mixt_tree;
+  do
+    {
+      time(&(tree->t_beg));
+      tree = tree->next_mixt;
+    }
+  while(tree);
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void MIXT_Init_T_End(t_tree *mixt_tree)
+{
+  t_tree *tree;
+
+  /*! Initialize t_beg in each mixture tree */
+  tree = mixt_tree;
+  do
+    {
+      time(&(tree->t_current));
+      tree = tree->next_mixt;
+    }
+  while(tree);
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void MIXT_Prepare_All(int num_rand_tree, t_tree *mixt_tree)
+{
+  t_tree *tree;
+
+  MIXT_Check_Model_Validity(mixt_tree);
+  MIXT_Init_Model(mixt_tree);
+  Print_Data_Structure(NO,stdout,mixt_tree);
+  tree = MIXT_Starting_Tree(mixt_tree);
+  Copy_Tree(tree,mixt_tree);
+  Free_Tree(tree);
+  
+  if(mixt_tree->io->mod->s_opt->random_input_tree)
+    {
+      PhyML_Printf("\n\n. [%3d/%3d]",num_rand_tree+1,mixt_tree->io->mod->s_opt->n_rand_starts);
+      Random_Tree(mixt_tree);
+    }
+  
+  MIXT_Connect_Cseqs_To_Nodes(mixt_tree);
+  MIXT_Init_T_Beg(mixt_tree);
+  Prepare_Tree_For_Lk(mixt_tree);
+  MIXT_Chain_All(mixt_tree);
+  MIXT_Check_Edge_Lens_In_All_Elem(mixt_tree);
+  MIXT_Turn_Branches_OnOff_In_All_Elem(ON,mixt_tree);
+  MIXT_Check_Invar_Struct_In_Each_Partition_Elem(mixt_tree);
+  MIXT_Check_RAS_Struct_In_Each_Partition_Elem(mixt_tree);
+}
+
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void MIXT_ML_Ancestral_Sequences_One_Node(t_node *mixt_d, t_tree *mixt_tree)
+{
+  if(mixt_d->tax) return;
+  else
+    {
+      t_node *v0,*v1,*v2; // three neighbours of d
+      t_edge *b0,*b1,*b2;
+      int i,j;
+      int catg;
+      phydbl p0, p1, p2;
+      phydbl *p;
+      t_node *d,*curr_mixt_d;
+      t_tree *tree, *curr_mixt_tree;
+      int site,csite;
+      phydbl *p_lk0, *p_lk1, *p_lk2;
+      int *sum_scale0, *sum_scale1, *sum_scale2;
+      phydbl r_mat_weight_sum, e_frq_weight_sum, sum_probas;
+      phydbl *Pij0, *Pij1, *Pij2;
+      int NsNs, Ns, NsNg;
+      FILE *fp;
+
+      if(!mixt_d) return;
+
+      curr_mixt_tree = mixt_tree;
+      curr_mixt_d    = mixt_d;
+      fp             = mixt_tree->io->fp_out_ancestral;
+
+
+      do /* For each partition element */
+        {
+          if(curr_mixt_tree->next)
+            {
+              r_mat_weight_sum = MIXT_Get_Sum_Chained_Scalar_Dbl(curr_mixt_tree->next->mod->r_mat_weight);
+              e_frq_weight_sum = MIXT_Get_Sum_Chained_Scalar_Dbl(curr_mixt_tree->next->mod->e_frq_weight);
+              sum_probas       = MIXT_Get_Sum_Of_Probas_Across_Mixtures(r_mat_weight_sum, e_frq_weight_sum, curr_mixt_tree);
+            }
+          else
+            {
+              r_mat_weight_sum = 1.;
+              e_frq_weight_sum = 1.;
+              sum_probas       = 1.;
+            }
+
+          Ns   = curr_mixt_tree->next ? curr_mixt_tree->next->mod->ns : curr_mixt_tree->mod->ns;
+          NsNs = Ns*Ns;
+          NsNg = Ns*curr_mixt_tree->mod->ras->n_catg;
+
+          p = (phydbl *)mCalloc(Ns,sizeof(phydbl));
+
+          /* For(site,curr_mixt_tree->n_pattern) // For each site in the current partition element */
+          For(site,curr_mixt_tree->data->init_len) // For each site in the current partition element
+            {
+              csite = curr_mixt_tree->data->sitepatt[site];
+
+              d    = curr_mixt_d->next ? curr_mixt_d->next : curr_mixt_d;
+              tree = curr_mixt_tree->next ? curr_mixt_tree->next : curr_mixt_tree;
+
+              For(i,tree->mod->ns) p[i] = .0;
+
+              do // For each class of the mixture model that applies to the current partition element
+                {
+                  if(tree->is_mixt_tree == YES)
+                    {
+                      tree = tree->next;
+                      d    = d->next;
+                    }
+
+                  v0 = d->v[0];
+                  v1 = d->v[1];
+                  v2 = d->v[2];
+
+                  b0 = d->b[0];
+                  b1 = d->b[1];
+                  b2 = d->b[2];
+
+                  Pij0 = b0->Pij_rr;
+                  Pij1 = b1->Pij_rr;
+                  Pij2 = b2->Pij_rr;
+
+                  if(v0 == b0->left)
+                    {
+                      p_lk0 = b0->p_lk_left;
+                      sum_scale0 = b0->sum_scale_left;
+                    }
+                  else
+                    {
+                      p_lk0 = b0->p_lk_rght;
+                      sum_scale0 = b0->sum_scale_rght;
+                    }
+
+                  if(v1 == b1->left)
+                    {
+                      p_lk1 = b1->p_lk_left;
+                      sum_scale1 = b1->sum_scale_left;
+                    }
+                  else
+                    {
+                      p_lk1 = b1->p_lk_rght;
+                      sum_scale1 = b1->sum_scale_rght;
+                    }
+
+                  if(v2 == b2->left)
+                    {
+                      p_lk2 = b2->p_lk_left;
+                      sum_scale2 = b2->sum_scale_left;
+                    }
+                  else
+                    {
+                      p_lk2 = b2->p_lk_rght;
+                      sum_scale2 = b2->sum_scale_rght;
+                    }
+
+
+                  For(catg,tree->mod->ras->n_catg)
+                    {
+                      For(i,Ns)
+                        {
+                          p0 = .0;
+                          if(v0->tax)
+                            For(j,tree->mod->ns)
+                              {
+                                p0 += v0->b[0]->p_lk_tip_r[csite*Ns+j] * Pij0[catg*NsNs+i*Ns+j];
+
+                                /* printf("\n. p0 %d %f", */
+                                /*        v0->b[0]->p_lk_tip_r[site*Ns+j], */
+                                /*        Pij0[catg*NsNs+i*Ns+j]); */
+                              }
+                          else
+                            For(j,tree->mod->ns)
+                              {
+                                p0 += p_lk0[csite*NsNg+catg*Ns+j] * Pij0[catg*NsNs+i*Ns+j] / (phydbl)POW(2,sum_scale0[catg*curr_mixt_tree->n_pattern+csite]);
+
+                                /* p0 += p_lk0[site*NsNg+catg*Ns+j] * Pij0[catg*NsNs+i*Ns+j]; */
+
+                                /* printf("\n. p0 %f %f", */
+                                /*        p_lk0[site*NsNg+catg*Ns+j], */
+                                /*        Pij0[catg*NsNs+i*Ns+j]); */
+                              }
+                          p1 = .0;
+                          if(v1->tax)
+                            For(j,tree->mod->ns)
+                              {
+                                p1 += v1->b[0]->p_lk_tip_r[csite*Ns+j] * Pij1[catg*NsNs+i*Ns+j];
+
+                                /* printf("\n. p1 %d %f", */
+                                /*        v1->b[0]->p_lk_tip_r[site*Ns+j], */
+                                /*        Pij1[catg*NsNs+i*Ns+j]); */
+                              }
+
+                          else
+                            For(j,tree->mod->ns)
+                              {
+                                p1 += p_lk1[csite*NsNg+catg*Ns+j] * Pij1[catg*NsNs+i*Ns+j] / (phydbl)POW(2,sum_scale1[catg*curr_mixt_tree->n_pattern+csite]);
+
+                                /* p1 += p_lk1[site*NsNg+catg*Ns+j] * Pij1[catg*NsNs+i*Ns+j];  */
+
+                                /* printf("\n. p1 %f %f", */
+                                /*        p_lk1[site*NsNg+catg*Ns+j], */
+                                /*        Pij1[catg*NsNs+i*Ns+j]); */
+                             }
+
+
+                          p2 = .0;
+                          if(v2->tax)
+                            For(j,tree->mod->ns)
+                              {
+                                p2 += v2->b[0]->p_lk_tip_r[csite*Ns+j] * Pij2[catg*NsNs+i*Ns+j];
+                                /* printf("\n. p2 %d %f", */
+                                /*        v2->b[0]->p_lk_tip_r[site*Ns+j], */
+                                /*        Pij2[catg*NsNs+i*Ns+j]); */
+                              }
+                          else
+                            For(j,tree->mod->ns)
+                              {
+                                p2 += p_lk2[csite*NsNg+catg*Ns+j] * Pij2[catg*NsNs+i*Ns+j] / (phydbl)POW(2,sum_scale2[catg*curr_mixt_tree->n_pattern+csite]);
+
+                                /* p2 += p_lk2[site*NsNg+catg*Ns+j] * Pij2[catg*NsNs+i*Ns+j]; */
+
+                                /* printf("\n. p2 %f %f", */
+                                /*        p_lk2[site*NsNg+catg*Ns+j], */
+                                /*        Pij2[catg*NsNs+i*Ns+j]);  */
+                             }
+
+                          p[i] +=
+                            p0*p1*p2*
+                            tree->mod->e_frq->pi->v[i] /
+                            tree->cur_site_lk[csite] *
+                            curr_mixt_tree->mod->ras->gamma_r_proba->v[tree->mod->ras->parent_class_number] *
+                            tree->mod->r_mat_weight->v / r_mat_weight_sum *
+                            tree->mod->e_frq_weight->v / e_frq_weight_sum /
+                            sum_probas;
+
+                          printf("\n class: %d prob: %f",
+                                 tree->mod->ras->parent_class_number,
+                                 curr_mixt_tree->mod->ras->gamma_r_proba->v[tree->mod->ras->parent_class_number]);
+                        }
+                    }
+
+                  PhyML_Fprintf(fp,"%4d\t%4d\t",site+1,d->num);
+                  For(i,Ns)
+                    {
+                      PhyML_Fprintf(fp,"%.4f\t",p[i]);
+                    }
+                  PhyML_Fprintf(fp,"\n");
+                  fflush(NULL);
+                  /* Exit("\n"); */
+                  
+
+                  tree = tree->next;
+                  d    = d->next;
+
+
+                }
+              while(tree && d && tree->is_mixt_tree == NO);
+            }
+
+          Free(p);
+          curr_mixt_tree = curr_mixt_tree->next_mixt;
+          curr_mixt_d    = curr_mixt_d->next_mixt;
+        }
+      while(curr_mixt_tree != NULL);
+    }
+}
diff --git a/src/mixt.h b/src/mixt.h
index 4373d8a..d879567 100644
--- a/src/mixt.h
+++ b/src/mixt.h
@@ -70,8 +70,22 @@ phydbl MIXT_Get_Mean_Edge_Len(t_edge *mixt_b, t_tree *tree);
 phydbl MIXT_Get_Sum_Chained_Scalar_Dbl(scalar_dbl *s);
 phydbl MIXT_Get_Sum_Of_Probas_Across_Mixtures(phydbl r_mat_weight_sum, phydbl e_frq_weight_sum, t_tree *mixt_tree);
 phydbl MIXT_Rescale_Free_Rate_Tree(t_tree *mixt_tree);
-void MIXT_Set_Br_Len_Var(t_tree *mixt_tree);
+void MIXT_Set_Br_Len_Var(t_edge *mixt_b, t_tree *mixt_tree);
 void MIXT_Optimize_Br_Len_Multiplier(t_tree *mixt_tree);
 void MIXT_Update_Br_Len_Multipliers(t_mod *mod);
+void MIXT_Init_Model(t_tree *mixt_tree);
+t_tree *MIXT_Starting_Tree(t_tree *mixt_tree);
+void MIXT_Connect_Cseqs_To_Nodes(t_tree *mixt_tree);
+void MIXT_Check_Edge_Lens_In_One_Elem(t_tree *mixt_tree);
+void MIXT_Check_Edge_Lens_In_All_Elem(t_tree *mixt_tree);
+void MIXT_Turn_Branches_OnOff_In_One_Elem(int onoff, t_tree *mixt_tree);
+void MIXT_Turn_Branches_OnOff_In_All_Elem(int onoff, t_tree *mixt_tree);
+void MIXT_Init_T_Beg(t_tree *mixt_tree);
+void MIXT_Prepare_All(int num_rand_tree, t_tree *mixt_tree);
+void MIXT_Init_T_End(t_tree *mixt_tree);
+void MIXT_Add_Root(t_edge *mixt_b, t_tree *mixt_tree);
+void MIXT_Check_Model_Validity(t_tree *mixt_tree);
+void MIXT_ML_Ancestral_Sequences_One_Node(t_node *mixt_d, t_tree *mixt_tree);
+void MIXT_Update_P_Pars(t_tree *mixt_tree, t_edge *mixt_b, t_node *mixt_d);
 
 #endif
diff --git a/src/models.c b/src/models.c
index a2eebd0..38e8dd3 100644
--- a/src/models.c
+++ b/src/models.c
@@ -269,8 +269,10 @@ void PMat_Empirical(phydbl l, t_mod *mod, int pos, phydbl *Pij)
   For(i,n) For(k,n) Pij[pos+mod->ns*i+k] = .0;
 
   /* compute POW(EXP(D/mr),l) into mat_eDmrl */
-  For(k,n) expt[k] = (phydbl)POW(R[k],l);
-
+  For(k,n) 
+    {
+      expt[k] = (phydbl)POW(R[k],l);
+    }
   /* multiply Vr*POW(EXP(D/mr),l)*Vi into Pij */
   For (i,n) For (k,n) uexpt[i*n+k] = U[i*n+k] * expt[k];
 
@@ -482,9 +484,10 @@ void PMat(phydbl l, t_mod *mod, int pos, phydbl *Pij)
                       {
 #ifdef BEAGLE
                         //when there is no active instance (i.e. when we are building the initial tree)
-                        if(UNINITIALIZED == mod->b_inst) {
+                        if(UNINITIALIZED == mod->b_inst) 
+                          {
                             PMat_Empirical(l,mod,pos,Pij);
-                        }
+                          }
 #else
                         PMat_Empirical(l,mod,pos,Pij);
 #endif
@@ -984,13 +987,12 @@ void Update_Eigen(t_mod *mod)
                   PhyML_Printf("\n== Cannot work out eigen vectors.");
                   Exit("\n");
                 }
-            };
+            }
           For(i,mod->eigen->size) mod->eigen->e_val[i] /= scalar;
-
+          
           /* compute the diagonal terms of EXP(D) */
           For(i,mod->ns) mod->eigen->e_val[i] = (phydbl)EXP(mod->eigen->e_val[i]);
 
-
       /* int j; */
       /* double *U,*V,*R; */
       /* double *expt; */
diff --git a/src/mpi_boot.c b/src/mpi_boot.c
index 86e7a0e..045c95e 100644
--- a/src/mpi_boot.c
+++ b/src/mpi_boot.c
@@ -358,7 +358,7 @@ PhyML_Printf("\n\n. Exiting bootstrap function normally."); fflush(NULL);
       fclose(tree->io->fp_out_boot_stats);
     }
 
-  Free_Cseq(boot_data);
+  Free_Calign(boot_data);
   Free(site_num);
 }
 
diff --git a/src/optimiz.c b/src/optimiz.c
index 6ddc17b..83eec08 100644
--- a/src/optimiz.c
+++ b/src/optimiz.c
@@ -576,9 +576,9 @@ void Round_Optimize(t_tree *tree, calign *data, int n_round_max)
   Set_Both_Sides(NO,tree); /* Only the down partial likelihoods need to be up-to-date here */
   Lk(NULL,tree);
 
+
   while(n_round < n_round_max)
     {
-
       if(tree->mod->s_opt->opt_bl || tree->mod->s_opt->constrained_br_len)
         Optimize_Br_Len_Serie(tree);
 
@@ -768,7 +768,7 @@ void Optimize_Br_Len_Serie_Post(t_node *a, t_node *d, t_edge *b_fcus, t_tree *tr
 
   if(d->tax) return;
 
-  if(tree->n_root)
+  if(tree->n_root && tree->ignore_root == NO)
     {
       For(i,3)
         {
@@ -794,9 +794,11 @@ void Optimize_Br_Len_Serie_Post(t_node *a, t_node *d, t_edge *b_fcus, t_tree *tr
             }
         }
       
-      For(i,3) 
-        if(d->v[i] == a) 
-          Update_P_Lk(tree,d->b[i],d);
+      /* For(i,3)  */
+      /*   if(d->v[i] == a)  */
+      /*     Update_P_Lk(tree,d->b[i],d); */
+
+      Update_P_Lk(tree,b_fcus,d);
     }
 }
 
@@ -807,9 +809,10 @@ void Optimize_Br_Len_Serie_Post(t_node *a, t_node *d, t_edge *b_fcus, t_tree *tr
 void Optimiz_Ext_Br(t_tree *tree)
 {
   int i;
-  t_edge *b,*ori;
+  t_edge *b;
   phydbl l_infa,l_infb;
-  phydbl lk_init,l_init;
+  phydbl lk_init;
+  scalar_dbl *l_init,*v_init;
 
   lk_init = tree->c_lnL;
 
@@ -817,30 +820,57 @@ void Optimiz_Ext_Br(t_tree *tree)
     {
       b = tree->a_edges[i];
       if((b->left->tax) || (b->rght->tax))
-    {
+        {
+          
+          l_init = Duplicate_Scalar_Dbl(b->l);          
+          v_init = Duplicate_Scalar_Dbl(b->l_var);          
 
-      l_init = b->l->v;
+          l_infb = tree->mod->l_min/b->l->v;
+          l_infa = 10.;
+          
+          Br_Len_Brent(l_infb,l_infa,b,tree);
+          
+          if(b->nni->best_l == NULL)
+            {
+              b->nni->best_l = Duplicate_Scalar_Dbl(b->l);
+              b->nni->best_v = Duplicate_Scalar_Dbl(b->l_var);
+            }
+          else
+            {
+              Copy_Scalar_Dbl(b->l,b->nni->best_l);
+              Copy_Scalar_Dbl(b->l_var,b->nni->best_v);
+            }
 
-/* 	  Fast_Br_Len(b,tree); */
-/* 	  lk = Lk(NULL,tree,b); */
+          if(b->nni->l0 == NULL)
+            {
+              b->nni->l0 = Duplicate_Scalar_Dbl(b->l);
+              b->nni->v0 = Duplicate_Scalar_Dbl(b->l_var);
+            }
+          else
+            {
+              Copy_Scalar_Dbl(b->l,b->nni->l0);
+              Copy_Scalar_Dbl(b->l_var,b->nni->v0);
+            }
 
-      l_infb = tree->mod->l_min/b->l->v;
-      l_infa = 10.;
+          // Revert of original edge lengths
+          Copy_Scalar_Dbl(l_init,b->l);
+          Copy_Scalar_Dbl(v_init,b->l_var);
 
-      Br_Len_Brent(l_infb,l_infa,b,tree);
+          Free_Scalar_Dbl(l_init);
+          Free_Scalar_Dbl(v_init);
 
-      ori = b;
-      do
-        {
-          b->nni->best_l    = b->l->v;
-          b->nni->l0        = b->l->v;
-          b->nni->best_conf = 0;
-          b->l->v              = l_init;
-              b = b->next;
+          /* ori = b; */
+          /* do */
+          /*   { */
+          /*     b->nni->best_l->v = b->l->v; */
+          /*     b->nni->l0->v     = b->l->v; */
+          /*     b->nni->best_conf = 0; */
+          /*     b->l->v           = l_init; */
+          /*     b = b->next; */
+          /*   } */
+          /* while(b); */
+          /* b = ori; */
         }
-      while(b);
-      b = ori;
-    }
     }
   tree->c_lnL = lk_init;
 }
@@ -1768,7 +1798,7 @@ phydbl Dist_F_Brent(phydbl ax, phydbl bx, phydbl cx, phydbl tol, int n_iter_max,
   phydbl a,b,d,etemp,fu,fv,fw,fx,p,q,r,tol1,tol2,u,v,w,x,xm;
   phydbl e=0.0;
   phydbl old_lnL,init_lnL, curr_lnL;
-
+  
   d=0.0;
   a=((ax < cx) ? ax : cx);
   b=((ax > cx) ? ax : cx);
@@ -1776,90 +1806,94 @@ phydbl Dist_F_Brent(phydbl ax, phydbl bx, phydbl cx, phydbl tol, int n_iter_max,
   old_lnL = UNLIKELY;
   fw = fv = fx = -Lk_Dist(F,FABS(bx),mod);
   curr_lnL = init_lnL = -fw;
+  
+  assert(!isnan(fx));
+  assert(!isinf(fx));
 
   for(iter=1;iter<=BRENT_IT_MAX;iter++)
     {
       xm=0.5*(a+b);
-
+      
       tol2=2.0*(tol1=tol*FABS(x)+BRENT_ZEPS);
-
+      
       if(
-     ((FABS(curr_lnL-old_lnL) < mod->s_opt->min_diff_lk_local) &&
-      (curr_lnL > init_lnL - mod->s_opt->min_diff_lk_local)) ||
-      (iter > n_iter_max - 1)
-     )
-    {
-      *param = x;
-      curr_lnL = Lk_Dist(F,*param,mod);
-      return -curr_lnL;
-    }
-
+         ((FABS(curr_lnL-old_lnL) < mod->s_opt->min_diff_lk_local) &&
+          (curr_lnL > init_lnL - mod->s_opt->min_diff_lk_local)) ||
+         (iter > n_iter_max - 1)
+         )
+        {
+          *param = x;
+          curr_lnL = Lk_Dist(F,*param,mod);
+          return -curr_lnL;
+        }
+      
       if(FABS(e) > tol1)
-    {
-      r=(x-w)*(fx-fv);
-      q=(x-v)*(fx-fw);
-      p=(x-v)*q-(x-w)*r;
-      q=2.0*(q-r);
-      if(q > 0.0) p = -p;
-      q=FABS(q);
-      etemp=e;
-      e=d;
-      if(FABS(p) >= FABS(0.5*q*etemp) || p <= q*(a-x) || p >= q*(b-x))
         {
-          d=BRENT_CGOLD*(e=(x >= xm ? a-x : b-x));
-          /*                   PhyML_Printf("Golden section step\n"); */
+          r=(x-w)*(fx-fv);
+          q=(x-v)*(fx-fw);
+          p=(x-v)*q-(x-w)*r;
+          q=2.0*(q-r);
+          if(q > 0.0) p = -p;
+          q=FABS(q);
+          etemp=e;
+          e=d;
+          if(FABS(p) >= FABS(0.5*q*etemp) || p <= q*(a-x) || p >= q*(b-x))
+            {
+              d=BRENT_CGOLD*(e=(x >= xm ? a-x : b-x));
+              /* PhyML_Printf("Golden section step\n"); */
+            }
+          else
+            {
+              d=p/q;
+              u=x+d;
+              if (u-a < tol2 || b-u < tol2)
+                d=SIGN(tol1,xm-x);
+              /* PhyML_Printf("Parabolic step\n"); */
+            }
         }
       else
         {
-          d=p/q;
-          u=x+d;
-          if (u-a < tol2 || b-u < tol2)
-        d=SIGN(tol1,xm-x);
-          /*                   PhyML_Printf("Parabolic step\n"); */
-        }
+          d=BRENT_CGOLD*(e=(x >= xm ? a-x : b-x));
+          /* PhyML_Printf("Golden section step (default)\n"); */
         }
-      else
-    {
-      d=BRENT_CGOLD*(e=(x >= xm ? a-x : b-x));
-      /*               PhyML_Printf("Golden section step (default)\n"); */
-    }
-
+      
       u=(FABS(d) >= tol1 ? x+d : x+SIGN(tol1,d));
       (*param) = FABS(u);
       old_lnL = curr_lnL;
       fu = -Lk_Dist(F,FABS(u),mod);
       curr_lnL = -fu;
-/*       PhyML_Printf("param=%f loglk=%f\n",*param,fu); */
-
-/*       if(fu <= fx)  */
+      /* PhyML_Printf("param=%f loglk=%f\n",*param,fu); */
+      
+      /*       if(fu <= fx)  */
       if(fu < fx)
-    {
-      if(iter > n_iter_max) return -fu;
-
-      if(u >= x) a=x; else b=x;
-      SHFT(v,w,x,u)
-      SHFT(fv,fw,fx,fu)
-    }
-      else
-    {
-      if (u < x) a=u; else b=u;
-/* 	  if (fu <= fw || w == x)  */
-      if (fu < fw || FABS(w-x) < SMALL)
         {
-          v=w;
-          w=u;
-          fv=fw;
-          fw=fu;
-        }
-/* 	  else if (fu <= fv || v == x || v == w)  */
-      else if (fu < fv || FABS(v-x) < SMALL || FABS(v-w) < SMALL)
+          if(iter > n_iter_max) return -fu;
+          
+          if(u >= x) a=x; else b=x;
+          SHFT(v,w,x,u)
+            SHFT(fv,fw,fx,fu)
+            }
+      else
         {
-          v=u;
-          fv=fu;
+          if (u < x) a=u; else b=u;
+          /* 	  if (fu <= fw || w == x)  */
+          if (fu < fw || FABS(w-x) < SMALL)
+            {
+              v=w;
+              w=u;
+              fv=fw;
+              fw=fu;
+            }
+          /* 	  else if (fu <= fv || v == x || v == w)  */
+          else if (fu < fv || FABS(v-x) < SMALL || FABS(v-w) < SMALL)
+            {
+              v=u;
+              fv=fu;
+            }
         }
     }
-    }
-  Exit("\n. Too many iterations in Dist_F_Brent !");
+  
+  Exit("\n. Too many iterations in Dist_F_Brent !\n");
   return(-1);
 }
 
@@ -2086,7 +2120,7 @@ int Optimiz_Alpha_And_Pinv(t_tree *mixt_tree, int verbose)
 
   do
     {
-      if(tree->mod->s_opt->opt_alpha == YES && tree->mod->ras->n_catg > 1)
+      if(tree->mod->s_opt->opt_alpha == YES && tree->mod->ras->n_catg > 1 && tree->mod->s_opt->opt_pinvar == YES)
         {
           For(i,n_alpha) if(tree->mod->ras->alpha == alpha[i]) break;
 
@@ -2883,7 +2917,6 @@ void Optimize_Pinv(t_tree *mixt_tree, int verbose)
 
   do
     {
-
       For(i,n_pinv) if(tree->mod->ras->pinvar == pinv[i]) break;
 
       if(i == n_pinv)
@@ -2892,8 +2925,8 @@ void Optimize_Pinv(t_tree *mixt_tree, int verbose)
           else      pinv = (scalar_dbl **)mRealloc(pinv,n_pinv+1,sizeof(scalar_dbl *));
           pinv[n_pinv] = tree->mod->ras->pinvar;
           n_pinv++;
-          
-          if(tree->mod->s_opt->opt_pinvar == YES && tree->mod->s_opt->opt_alpha == NO)
+           
+          if(tree->mod->s_opt->opt_pinvar == YES && (tree->mod->s_opt->opt_alpha == NO || tree->mod->ras->n_catg == 1))
             {
               Generic_Brent_Lk(&(tree->mod->ras->pinvar->v),
                                0.0001,0.9999,
@@ -2904,13 +2937,13 @@ void Optimize_Pinv(t_tree *mixt_tree, int verbose)
               
               if(verbose)
                 {
-                  Print_Lk(mixt_tree,"[P-inv              ]");
+                  Print_Lk(tree,"[P-inv              ]");
                   PhyML_Printf("[%10f]",tree->mod->ras->pinvar->v);
                 }
             }
         }
       
-      tree = tree->next;
+      tree = tree->next_mixt;
 
     }
   while(tree);
diff --git a/src/pars.c b/src/pars.c
index 08fc76d..7f2b26c 100644
--- a/src/pars.c
+++ b/src/pars.c
@@ -21,15 +21,22 @@ int Pars(t_edge *b, t_tree *tree)
 {
   int site,n_patterns;
 
+  if(tree->is_mixt_tree == YES) 
+    {
+      MIXT_Pars(b,tree);
+      return tree->c_pars;
+    }
+
   n_patterns = tree->n_pattern;
 
-  if(!b)
+  
+  if(b == NULL)
     {
       Post_Order_Pars(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree);
       if(tree->both_sides == YES) Pre_Order_Pars(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree);
     }
 
-  if(!b) b = tree->a_nodes[0]->b[0];
+  if(b == NULL) b = tree->a_nodes[0]->b[0];
 
   tree->c_pars = 0;
   For(site,n_patterns)
@@ -41,11 +48,6 @@ int Pars(t_edge *b, t_tree *tree)
       /* printf("\n. site %d pars: %d",site,tree->c_pars); */
     }
 
-  if(tree->is_mixt_tree)
-    {
-      MIXT_Pars(b,tree);
-    }
-
   return tree->c_pars;
 }
 
@@ -256,6 +258,12 @@ void Update_P_Pars(t_tree *tree, t_edge *b_fcus, t_node *n)
   int v;
   int dim1;
 
+  if(tree->is_mixt_tree)
+    {
+      MIXT_Update_P_Pars(tree,b_fcus,n);
+      return;
+    }
+
   if((tree->io->do_alias_subpatt == YES) &&
      (tree->update_alias_subpatt == YES))
     Alias_One_Subpatt((n==b_fcus->left)?(b_fcus->rght):(b_fcus->left),n,tree);
@@ -268,122 +276,120 @@ void Update_P_Pars(t_tree *tree, t_edge *b_fcus, t_node *n)
   pars = pars_v1 = pars_v2 = NULL;
 
   n_patterns = tree->n_pattern;
-
-
+    
   if(n == b_fcus->left)
     {
       ui = b_fcus->ui_l;
-
+      
       pars = b_fcus->pars_l;
       p_pars = b_fcus->p_pars_l;
-
+      
       ui_v1 =
-      (n == n->b[b_fcus->l_v1]->left)?
-      (n->b[b_fcus->l_v1]->ui_r):
-      (n->b[b_fcus->l_v1]->ui_l);
-
+        (n == n->b[b_fcus->l_v1]->left)?
+        (n->b[b_fcus->l_v1]->ui_r):
+        (n->b[b_fcus->l_v1]->ui_l);
+      
       ui_v2 =
-      (n == n->b[b_fcus->l_v2]->left)?
-      (n->b[b_fcus->l_v2]->ui_r):
-      (n->b[b_fcus->l_v2]->ui_l);
-
+        (n == n->b[b_fcus->l_v2]->left)?
+        (n->b[b_fcus->l_v2]->ui_r):
+        (n->b[b_fcus->l_v2]->ui_l);
+      
       p_pars_v1 =
-      (n == n->b[b_fcus->l_v1]->left)?
-      (n->b[b_fcus->l_v1]->p_pars_r):
-      (n->b[b_fcus->l_v1]->p_pars_l);
-
+        (n == n->b[b_fcus->l_v1]->left)?
+        (n->b[b_fcus->l_v1]->p_pars_r):
+        (n->b[b_fcus->l_v1]->p_pars_l);
+      
       p_pars_v2 =
-      (n == n->b[b_fcus->l_v2]->left)?
-      (n->b[b_fcus->l_v2]->p_pars_r):
-      (n->b[b_fcus->l_v2]->p_pars_l);
-
+        (n == n->b[b_fcus->l_v2]->left)?
+        (n->b[b_fcus->l_v2]->p_pars_r):
+        (n->b[b_fcus->l_v2]->p_pars_l);
+      
       pars_v1 =
-      (n == n->b[b_fcus->l_v1]->left)?
-      (n->b[b_fcus->l_v1]->pars_r):
-      (n->b[b_fcus->l_v1]->pars_l);
-
+        (n == n->b[b_fcus->l_v1]->left)?
+        (n->b[b_fcus->l_v1]->pars_r):
+        (n->b[b_fcus->l_v1]->pars_l);
+      
       pars_v2 =
-      (n == n->b[b_fcus->l_v2]->left)?
-      (n->b[b_fcus->l_v2]->pars_r):
-      (n->b[b_fcus->l_v2]->pars_l);
+        (n == n->b[b_fcus->l_v2]->left)?
+        (n->b[b_fcus->l_v2]->pars_r):
+        (n->b[b_fcus->l_v2]->pars_l);
     }
   else
     {
       ui = b_fcus->ui_r;
-
+      
       pars = b_fcus->pars_r;
       p_pars = b_fcus->p_pars_r;
-
+      
       ui_v1 =
-      (n == n->b[b_fcus->r_v1]->left)?
-      (n->b[b_fcus->r_v1]->ui_r):
-      (n->b[b_fcus->r_v1]->ui_l);
-
+        (n == n->b[b_fcus->r_v1]->left)?
+        (n->b[b_fcus->r_v1]->ui_r):
+        (n->b[b_fcus->r_v1]->ui_l);
+      
       ui_v2 =
-      (n == n->b[b_fcus->r_v2]->left)?
-      (n->b[b_fcus->r_v2]->ui_r):
-      (n->b[b_fcus->r_v2]->ui_l);
-
+        (n == n->b[b_fcus->r_v2]->left)?
+        (n->b[b_fcus->r_v2]->ui_r):
+        (n->b[b_fcus->r_v2]->ui_l);
+      
       p_pars_v1 =
-      (n == n->b[b_fcus->r_v1]->left)?
-      (n->b[b_fcus->r_v1]->p_pars_r):
-      (n->b[b_fcus->r_v1]->p_pars_l);
-
+        (n == n->b[b_fcus->r_v1]->left)?
+        (n->b[b_fcus->r_v1]->p_pars_r):
+        (n->b[b_fcus->r_v1]->p_pars_l);
+      
       p_pars_v2 =
-      (n == n->b[b_fcus->r_v2]->left)?
-      (n->b[b_fcus->r_v2]->p_pars_r):
-      (n->b[b_fcus->r_v2]->p_pars_l);
-
+        (n == n->b[b_fcus->r_v2]->left)?
+        (n->b[b_fcus->r_v2]->p_pars_r):
+        (n->b[b_fcus->r_v2]->p_pars_l);
+      
       pars_v1 =
-      (n == n->b[b_fcus->r_v1]->left)?
-      (n->b[b_fcus->r_v1]->pars_r):
-      (n->b[b_fcus->r_v1]->pars_l);
-
+        (n == n->b[b_fcus->r_v1]->left)?
+        (n->b[b_fcus->r_v1]->pars_r):
+        (n->b[b_fcus->r_v1]->pars_l);
+      
       pars_v2 =
-      (n == n->b[b_fcus->r_v2]->left)?
-      (n->b[b_fcus->r_v2]->pars_r):
-      (n->b[b_fcus->r_v2]->pars_l);
+        (n == n->b[b_fcus->r_v2]->left)?
+        (n->b[b_fcus->r_v2]->pars_r):
+        (n->b[b_fcus->r_v2]->pars_l);
     }
-
-
+  
+  
   if(tree->mod->s_opt->general_pars)
     {
       For(site,n_patterns)
-    {
-      For(i,tree->mod->ns)
-        {
-          min_v1 = MAX_PARS;
-          For(j,tree->mod->ns)
         {
-          v = p_pars_v1[site*dim1+j] + tree->step_mat[i*tree->mod->ns+j];
-          if(v < min_v1) min_v1 = v;
-        }
-
-          min_v2 = MAX_PARS;
-          For(j,tree->mod->ns)
-        {
-          v = p_pars_v2[site*dim1+j] + tree->step_mat[i*tree->mod->ns+j];
-          if(v < min_v2) min_v2 = v;
-        }
-          p_pars[site*dim1+i] = min_v1 + min_v2;
+          For(i,tree->mod->ns)
+            {
+              min_v1 = MAX_PARS;
+              For(j,tree->mod->ns)
+                {
+                  v = p_pars_v1[site*dim1+j] + tree->step_mat[i*tree->mod->ns+j];
+                  if(v < min_v1) min_v1 = v;
+                }
+              
+              min_v2 = MAX_PARS;
+              For(j,tree->mod->ns)
+                {
+                  v = p_pars_v2[site*dim1+j] + tree->step_mat[i*tree->mod->ns+j];
+                  if(v < min_v2) min_v2 = v;
+                }
+              p_pars[site*dim1+i] = min_v1 + min_v2;
+            }
         }
     }
-    }
   else
     {
       For(site,n_patterns)
-    {
-      pars[site] = pars_v1[site] + pars_v2[site];
-
-      ui[site] = ui_v1[site] & ui_v2[site];
-
-      if(!ui[site])
         {
-          pars[site]++;
-          ui[site] = ui_v1[site] | ui_v2[site];
+          pars[site] = pars_v1[site] + pars_v2[site];
+          
+          ui[site] = ui_v1[site] & ui_v2[site];
+          
+          if(!ui[site])
+            {
+              pars[site]++;
+              ui[site] = ui_v1[site] | ui_v2[site];
+            }          
         }
-
-    }
     }
 }
 
diff --git a/src/phyrex.c b/src/phyrex.c
index aea1700..037e4b7 100644
--- a/src/phyrex.c
+++ b/src/phyrex.c
@@ -23,7 +23,6 @@ int PHYREX_Main(int argc, char *argv[])
 {
   return(PHYREX_Main_Estimate(argc,argv));
   /* return(PHYREX_Main_Simulate(argc,argv)); */
-
 }
 
 //////////////////////////////////////////////////////////////
@@ -114,8 +113,6 @@ int PHYREX_Main_Estimate(int argc, char *argv[])
 
   Init_Model(tree->data,io->mod,io);
   Prepare_Tree_For_Lk(tree);
-  Init_P_Lk_Tips_Int(tree);
-  Init_P_Lk_Loc(tree);
 
   res = PHYREX_MCMC(tree);
 
@@ -134,7 +131,7 @@ int PHYREX_Main_Simulate(int argc, char *argv[])
   int seed,pid,i;
   char *s;
   t_dsk *disk;
-  int n_otus, n_sites;
+  int n_sites,n_otus;
 
   s = (char *)mCalloc(T_MAX_NAME,sizeof(char));
 
@@ -143,35 +140,14 @@ int PHYREX_Main_Simulate(int argc, char *argv[])
   n_otus  = (int)atoi(argv[1]);
   n_sites = (int)atoi(argv[2]);
 
-  /* !!!!!!!!!!!!! */
-  /* seed = 9498; */
-  /* seed = 27351; */
-  /* seed = 359; */
-  /* seed = 1; */
-  /* seed = 10112; */
-  /* seed = 5818; */
-  /* seed = 16167; */
-  /* seed = 18885; */
-  /* seed = 22776; */
-  /* seed = 629; */
-  /* seed = 1; */
-  /* seed = 14493; */
-  /* seed = 15364; */
-  /* seed = 21414; */
-  /* seed = 13536; */
-  /* seed = 28366; */
-  /* seed = 20679; */
-  /* seed = 23661; */
-
   printf("\n. seed: %d",seed);
   srand(seed);
   
-  tree = PHYREX_Simulate((int)atoi(argv[1]),(int)atoi(argv[2]),10.,10.,seed);
+  tree = PHYREX_Simulate(n_otus,n_sites,10.,10.,seed);
 
   disk = tree->disk;
   while(disk->prev) disk = disk->prev;
 
-
   strcpy(s,"phyrex_trees");
   sprintf(s+strlen(s),".%d",tree->mod->io->r_seed);
   tree->io->fp_out_tree = Openfile(s,WRITE);
@@ -211,7 +187,7 @@ int PHYREX_Main_Simulate(int argc, char *argv[])
   Free_Optimiz(tree->mod->s_opt);
   Free_Model_Complete(tree->mod);
   Free_Model_Basic(tree->mod);
-  Free_Cseq(tree->data);
+  Free_Calign(tree->data);
   Free_Tree(tree);
   Free(res);  
   Free(s);
@@ -227,7 +203,7 @@ int PHYREX_Main_Simulate(int argc, char *argv[])
 t_tree *PHYREX_Simulate(int n_otu, int n_sites, phydbl width, phydbl height, int r_seed)
 {  
   t_tree *tree;
-  int n_dim;
+  int n_dim,i;
   t_phyrex_mod *mmod;
   t_dsk *disk;
   option *io;
@@ -316,26 +292,17 @@ t_tree *PHYREX_Simulate(int n_otu, int n_sites, phydbl width, phydbl height, int
   tree->mmod->lbda = area * mmod->sigsq / (4.*PI*tree->mmod->mu*POW(tree->mmod->rad,4));
 
   
-  /* mmod->lbda  = 0.04; */
-  /* mmod->mu    = 0.16; */
-  /* mmod->rad   = 2.75; */
+
+  /* !!!!!!!!!!!!! */
+  /* mmod->lbda  = 1.00; */
+  /* mmod->mu    = 0.9; */
+  /* mmod->rad   = 10.00; */
   /* neigh       = 2./mmod->mu; */
   /* mmod->sigsq = PHYREX_Update_Sigsq(tree); */
 
-  PhyML_Printf("\n. lbda: %G mu: %G sigsq: %G rad: %G neigh: %G N: %G rhoe: %G",
-               mmod->lbda,
-               mmod->mu,
-               mmod->sigsq,
-               mmod->rad,
-               neigh,
-               area*neigh/(4*PI*mmod->sigsq),
-               neigh/(4.*PI*mmod->sigsq));
-  fflush(NULL);
-
-
   /* PHYREX_Simulate_Backward_Core(YES,tree->disk,tree); */
-  mmod->sampl_area = PHYREX_Simulate_Forward_Core(n_sites,tree);
-    
+  mmod->samp_area = PHYREX_Simulate_Forward_Core(n_sites,tree);
+  
   PHYREX_Ldsk_To_Tree(tree);  
 
   Update_Ancestors(tree->n_root,tree->n_root->v[2],tree);
@@ -369,18 +336,40 @@ t_tree *PHYREX_Simulate(int n_otu, int n_sites, phydbl width, phydbl height, int
 
   disk = tree->disk->prev;
   while(disk->prev) disk = disk->prev;
+  
+  PhyML_Printf("\n. Useful parameters: lambda=%G; mu=%G; rad=%G; clockr=%G; sigsq=%G; neigh=%G; N=%G; rhoe=%G",
+               mmod->lbda,
+               mmod->mu,
+               mmod->rad,
+               tree->rates->clock_r,
+               mmod->sigsq,
+               neigh,
+               area*neigh/(4*PI*mmod->sigsq),
+               neigh/(4.*PI*mmod->sigsq));
+  fflush(NULL);
 
-  printf("\n. XXX %f %d %d %d %f %f %f %f %f %f\n",
-         disk->time,
-         PHYREX_Total_Number_Of_Intervals(tree),
-         PHYREX_Total_Number_Of_Coal_Disks(tree),
-         PHYREX_Total_Number_Of_Hit_Disks(tree),
-         disk->ldsk->coord->lonlat[0],
-         disk->ldsk->coord->lonlat[1],
-         mmod->lbda,  
-         mmod->mu,    
-         mmod->sigsq,
-         Nucleotide_Diversity(tree->data));
+  PhyML_Printf("\n. Useful statistics: t.root=%f n.int=%d n.coal=%d n.hit=%d root.x=%f root.y=%f nt.div=%f\n",
+               disk->time,
+               PHYREX_Total_Number_Of_Intervals(tree),
+               PHYREX_Total_Number_Of_Coal_Disks(tree),
+               PHYREX_Total_Number_Of_Hit_Disks(tree),
+               disk->ldsk->coord->lonlat[0],
+               disk->ldsk->coord->lonlat[1],
+               Nucleotide_Diversity(tree->data));
+  
+  
+  PhyML_Printf("\n. Tree: ");
+  PhyML_Printf("\n. %s \n",Write_Tree(tree,NO));
+
+  PhyML_Printf("\n. Spatial coordinates: ");
+  For(i,tree->n_otu)
+    {
+      PhyML_Printf("\n. %15s: [%12f ; %12f]",
+                   tree->disk->ldsk_a[i]->nd->name,
+                   tree->disk->ldsk_a[i]->coord->lonlat[0],                   
+                   tree->disk->ldsk_a[i]->coord->lonlat[1]);
+    }
+  PhyML_Printf("\n");
 
   return(tree);
 }
@@ -426,7 +415,7 @@ phydbl PHYREX_Simulate_Backward_Core(int new_loc, t_dsk *init_disk, t_tree *tree
           Free(init_disk->ldsk_a[i]->coord->id);
           init_disk->ldsk_a[i]->coord->id = s;
         }
-
+      
       /* PhyML_Printf("\n. WARNING: position of samples are not random."); */
       /* Generate coordinates for the tip nodes (uniform distribution on the rectangle) */
       For(i,tree->n_otu)
@@ -596,15 +585,17 @@ phydbl PHYREX_Simulate_Backward_Core(int new_loc, t_dsk *init_disk, t_tree *tree
 ////////////////////////////////////////////////////////////*/
 // Simulate Etheridge-Barton model forwards in time, following n_otu lineages
 // on a rectangle of dimension width x height
-phydbl PHYREX_Simulate_Forward_Core(int n_sites, t_tree *tree)
+t_sarea *PHYREX_Simulate_Forward_Core(int n_sites, t_tree *tree)
 {
   t_dsk *disk;
   t_ldsk *new_ldsk,**ldsk_a_pop,**ldsk_a_samp,**ldsk_a_tmp,**ldsk_a_tips;
-  int i,j,n_disk,n_dim,n_otu,pop_size,parent_id,n_lineages,sample_size,n_poly,*permut;
-  phydbl dt_dsk,curr_t,sum,*parent_prob,prob_death,tree_height,max_x,max_y,trans_x,trans_y,area;
+  int i,j,n_disk,n_dim,n_otu,pop_size,parent_id,n_lineages,sample_size,n_poly,*permut,n_sampled_demes;
+  phydbl dt_dsk,curr_t,sum,*parent_prob,prob_death,tree_height,max_x,max_y,trans_x,trans_y;
   short int dies,n_remain;
   t_phyrex_mod *mmod;
   t_poly **poly;
+  t_sarea *area;
+  short int *is_sampled;
 
   mmod     = tree->mmod;
   n_dim    = tree->mmod->n_dim;
@@ -751,6 +742,8 @@ phydbl PHYREX_Simulate_Forward_Core(int n_sites, t_tree *tree)
 
   n_poly = n_sites;
 
+  is_sampled = (short int *)mCalloc(n_poly,sizeof(short int));
+
   do
     {
       poly = (t_poly **)mCalloc(n_poly,sizeof(t_poly *));
@@ -778,15 +771,13 @@ phydbl PHYREX_Simulate_Forward_Core(int n_sites, t_tree *tree)
             {
               poly[i]->poly_vert[j]->lonlat[0] += trans_x;
               poly[i]->poly_vert[j]->lonlat[1] += trans_y;
-              PhyML_Printf("\n# Sampling == polygon %d vertex @ (%f; %f)",
-                           i,
-                           poly[i]->poly_vert[j]->lonlat[0],
-                           poly[i]->poly_vert[j]->lonlat[1]);
             }
         }
       
       For(i,n_otu) ldsk_a_samp[i] = NULL;
 
+      For(i,n_poly) is_sampled[i] = NO;
+
       permut = Permutate(n_poly);
 
       sample_size = 0;
@@ -798,18 +789,25 @@ phydbl PHYREX_Simulate_Forward_Core(int n_sites, t_tree *tree)
                 {
                   char *s;
                   int k;
-                  s = (char *)mCalloc((int)strlen(ldsk_a_pop[i]->coord->id)+1+20,sizeof(char));
+                                   
+                  s = (char *)mCalloc((int)strlen(ldsk_a_pop[i]->coord->id)+1+50,sizeof(char));
                   For(k,(int)strlen(ldsk_a_pop[i]->coord->id)+1+20) s[k]='\0';
-                  strcpy(s,ldsk_a_pop[i]->coord->id);
+                  sprintf(s,"%d_",i);
+                  strcat(s,ldsk_a_pop[i]->coord->id);
                   Free(ldsk_a_pop[i]->coord->id);
                   strcat(s,"_deme");
                   sprintf(s+strlen(s),"%d",permut[j]);
                   ldsk_a_pop[i]->coord->id = s;
 
+
                   ldsk_a_samp[sample_size] = ldsk_a_pop[i];
                   sample_size++;
-                  PhyML_Printf("\n@ Coord: %f %f %s",ldsk_a_samp[sample_size-1]->coord->lonlat[0],ldsk_a_samp[sample_size-1]->coord->lonlat[1],ldsk_a_pop[i]->coord->id);
-                  
+                  PhyML_Printf("\n@ Coord: %f %f %s %p",
+                               ldsk_a_samp[sample_size-1]->coord->lonlat[0],
+                               ldsk_a_samp[sample_size-1]->coord->lonlat[1],
+                               ldsk_a_pop[i]->coord->id,ldsk_a_pop[i]);
+
+                  is_sampled[permut[j]] = YES;
                   break;
                 }
             }
@@ -817,14 +815,11 @@ phydbl PHYREX_Simulate_Forward_Core(int n_sites, t_tree *tree)
         }
 
       Free(permut);
-
-      area = Area_Of_Poly_Monte_Carlo(poly,n_poly,mmod->lim);
       
-      For(j,n_poly) Free_Poly(poly[j]);
-      Free(poly);
-
       if(i == pop_size)
         {
+          For(j,n_poly) Free_Poly(poly[j]);
+          Free(poly);
           PhyML_Printf("\n== Not enough individuals in polygon(s) (only %d found).",sample_size);
           /* Generic_Exit(__FILE__,__LINE__,__FUNCTION__);       */
         }
@@ -833,7 +828,31 @@ phydbl PHYREX_Simulate_Forward_Core(int n_sites, t_tree *tree)
   while(1);
       
   For(i,n_otu) ldsk_a_tips[i] = ldsk_a_samp[i];
-  
+
+  n_sampled_demes = 0;
+  For(i,n_poly) if(is_sampled[i] == YES) n_sampled_demes++;
+
+  area = Make_Sarea(n_sampled_demes);
+  area->n_poly = n_sampled_demes;
+
+  n_sampled_demes = 0;
+  For(i,n_poly) if(is_sampled[i] == YES) area->a_poly[n_sampled_demes++] = poly[i];
+
+
+  For(i,area->n_poly) 
+    {
+      /* PhyML_Printf("\n@ Poly %3d area = %f",i,Area_Of_Poly_Monte_Carlo(area->a_poly[i],mmod->lim)); */
+
+      For(j,area->a_poly[i]->n_poly_vert)
+        {
+          PhyML_Printf("\n@ Poly %3d point %d (x,y) = (%f,%f)",
+                       i,
+                       j,
+                       area->a_poly[i]->poly_vert[j]->lonlat[0],
+                       area->a_poly[i]->poly_vert[j]->lonlat[1]);
+        }
+    }
+
   tree->disk             = disk;
   disk->ldsk_a           = ldsk_a_tips;
   disk->mmod             = tree->mmod;
@@ -922,6 +941,7 @@ phydbl PHYREX_Simulate_Forward_Core(int n_sites, t_tree *tree)
   Free(ldsk_a_samp);
   Free(ldsk_a_pop);
   Free(parent_prob);
+  Free(is_sampled);
   
   /* PHYREX_Print_Struct('#',tree); */
   /* Exit("\n"); */
@@ -1096,12 +1116,12 @@ phydbl PHYREX_Lk_Range(t_dsk *young, t_dsk *old, t_tree *tree)
 phydbl *PHYREX_MCMC(t_tree *tree)
 {
   t_mcmc *mcmc;
-  int move,i,n_vars,burnin,true_ncoal,true_nint,true_nhits;
+  int move,i,n_vars,burnin,true_ncoal,true_nint,true_nhits,n_demes;
   phydbl u;
   t_dsk *disk;
   FILE *fp_tree,*fp_stats,*fp_summary;
   phydbl *res;
-  phydbl true_root_x, true_root_y,true_lbda,true_mu,true_sigsq,true_neigh,fst_neigh,diversity,true_rad,true_height,true_rhoe;
+  phydbl true_root_x, true_root_y,true_lbda,true_mu,true_sigsq,true_neigh,fst_neigh,diversity,true_rad,true_height,true_rhoe,tot_samp_area;
   int adjust_len;
 
   fp_tree    = tree->io->fp_out_tree;
@@ -1134,6 +1154,12 @@ phydbl *PHYREX_MCMC(t_tree *tree)
   mcmc->sample_num       = 0;
   adjust_len             = 1E+6;
 
+  
+  tot_samp_area = 0.0;
+  /* if(tree->mmod->samp_area != NULL) */
+  /*   For(i,tree->mmod->samp_area->n_poly) tot_samp_area += Area_Of_Poly_Monte_Carlo(tree->mmod->samp_area->a_poly[i],tree->mmod->lim); */
+
+
   MCMC_Complete_MCMC(mcmc,tree);
 
   n_vars                 = 12;
@@ -1157,7 +1183,9 @@ phydbl *PHYREX_MCMC(t_tree *tree)
   true_nhits  = PHYREX_Total_Number_Of_Hit_Disks(tree);
   true_height = PHYREX_Tree_Height(tree);
   true_rhoe   = PHYREX_Effective_Density(tree);
-
+  n_demes     = 0;
+  /* n_demes     = tree->mmod->samp_area->n_poly; */
+  
   PhyML_Fprintf(fp_stats,"\n# before rand glnL: %f alnL: %f",tree->mmod->c_lnL,tree->c_lnL);
   PhyML_Fprintf(fp_stats,"\n# ninter: %d",PHYREX_Total_Number_Of_Intervals(tree));
   PhyML_Fprintf(fp_stats,"\n# ncoal: %d",PHYREX_Total_Number_Of_Coal_Disks(tree));
@@ -1174,8 +1202,12 @@ phydbl *PHYREX_MCMC(t_tree *tree)
   PhyML_Fprintf(fp_stats,"\n# nucleotide diversity: %f",Nucleotide_Diversity(tree->data));
   PhyML_Fprintf(fp_stats,"\n# length of a generation: %G time units",PHYREX_Generation_Length(tree));
   PhyML_Fprintf(fp_stats,"\n# clock rate: %G subst. per time unit",tree->rates->clock_r);
-  PhyML_Fprintf(fp_stats,"\n# proportion of sampled area: %f",tree->mmod->sampl_area);
-
+  /* PhyML_Fprintf(fp_stats,"\n# of sampled demes: %d",n_demes); */
+  /* if(tree->mmod->samp_area != NULL) */
+  /*   For(i,tree->mmod->samp_area->n_poly) PhyML_Fprintf(fp_stats,"\n# area of deme%d: %f", */
+  /*                                                      i, */
+  /*                                                      Area_Of_Poly_Monte_Carlo(tree->mmod->samp_area->a_poly[i],tree->mmod->lim)); */
+ 
   /* Starting parameter values */
   tree->mmod->lbda = Uni()*(0.5 - 0.2) + 0.2;
   tree->mmod->mu   = Uni()*(0.6 - 0.3) + 0.3;
@@ -1360,9 +1392,6 @@ phydbl *PHYREX_MCMC(t_tree *tree)
       tree->mcmc->run++;
       MCMC_Get_Acc_Rates(tree->mcmc);
       
-
-
-
       if(!(tree->mcmc->run%tree->mcmc->sample_interval))
         {
           /* Lk(NULL,tree); */
@@ -1430,6 +1459,7 @@ phydbl *PHYREX_MCMC(t_tree *tree)
           res[6 * tree->mcmc->chain_len / tree->mcmc->sample_interval +  tree->mcmc->run / tree->mcmc->sample_interval] = PHYREX_Total_Number_Of_Coal_Disks(tree);
           res[7 * tree->mcmc->chain_len / tree->mcmc->sample_interval +  tree->mcmc->run / tree->mcmc->sample_interval] = PHYREX_Total_Number_Of_Hit_Disks(tree);
           res[8 * tree->mcmc->chain_len / tree->mcmc->sample_interval +  tree->mcmc->run / tree->mcmc->sample_interval] = PHYREX_Effective_Density(tree);
+          res[9 * tree->mcmc->chain_len / tree->mcmc->sample_interval +  tree->mcmc->run / tree->mcmc->sample_interval] = PHYREX_Coalescence_Rate(tree);
 
           MCMC_Copy_To_New_Param_Val(tree->mcmc,tree);
           
@@ -1441,16 +1471,18 @@ phydbl *PHYREX_MCMC(t_tree *tree)
           
           rewind(fp_summary);
 
-          PhyML_Fprintf(fp_summary,"\n# SampArea\t TrueLbda\t TrueMu\t TrueSig\t TrueRad\t TrueNeigh\t TrueRhoe\t Diversity\t TrueInt\t TrueCoal\t TrueHits\t RegNeigh\t TrueXroot\t TrueYroot\t TrueHeight\t Lbda5\t Lbda50\t Lbda95\t LbdaMod \t Mu5\t Mu50\t Mu95\t  MuMod \t Sig5\t Sig50\t Sig95\t SigMod \t Neigh5\t Neigh50\t Neigh95\t NeighMod \t Rad5\t Rad50\t Rad95\t Int5\t Int50\t Int95\t Coal5\t Coal50\t Coal95\t Hit5\t Hit50\t Hit95\t Rhoe5\t Rhoe50\t Rhoe95\t ESSLbda \t ESSMu \t ESSS [...]
+          PhyML_Fprintf(fp_summary,"\n# SampArea\t NDemes\t TrueLbda\t TrueMu\t TrueSig\t TrueRad\t TrueNeigh\t TrueRhoe\t \t ClockRate\t Diversity\t TrueInt\t TrueCoal\t TrueHits\t RegNeigh\t TrueXroot\t TrueYroot\t TrueHeight\t Lbda5\t Lbda50\t Lbda95\t LbdaMod \t Mu5\t Mu50\t Mu95\t  MuMod \t Sig5\t Sig50\t Sig95\t SigMod \t Neigh5\t Neigh50\t Neigh95\t NeighMod \t Rad5\t Rad50\t Rad95\t Int5\t Int50\t Int95\t Coal5\t Coal50\t Coal95\t Hit5\t Hit50\t Hit95\t Rhoe5\t Rhoe50\t Rhoe95\t  [...]
           
-          PhyML_Fprintf(fp_summary,"\n %f\t %f\t %f\t %f\t %f\t %f\t %f\t %f\t %d\t %d\t %d\t %f\t %f\t %f\t %f\t ",
-                        tree->mmod->sampl_area,
+          PhyML_Fprintf(fp_summary,"\n %G\t %d\t %G\t %G\t %G\t %G\t %G\t %G\t %G\t %G\t %d\t %d\t %d\t %G\t %G\t %G\t %G\t ",
+                        tot_samp_area,
+                        n_demes,
                         true_lbda,
                         true_mu,
                         true_sigsq,
                         true_rad,
                         true_neigh,
                         true_rhoe,
+                        tree->rates->clock_r,
                         diversity,
                         true_nint,
                         true_ncoal,
@@ -1460,58 +1492,63 @@ phydbl *PHYREX_MCMC(t_tree *tree)
                         true_root_y,
                         true_height);
           
-          PhyML_Fprintf(fp_summary,"%f\t %f\t %f\t %f\t",
+          PhyML_Fprintf(fp_summary,"%G\t %G\t %G\t %G\t",
                         /* Lbda5 */  Quantile(res+0*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.025),
                         /* Lbda50 */ Quantile(res+0*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.50),
                         /* Lbda95 */ Quantile(res+0*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.975),
                         /* LbdaMod*/ tree->mcmc->mode[tree->mcmc->num_move_phyrex_lbda]);
           
-          PhyML_Fprintf(fp_summary,"%f\t %f\t %f\t %f\t",
+          PhyML_Fprintf(fp_summary,"%G\t %G\t %G\t %G\t",
                         /* mu5 */   Quantile(res+1*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.025),
                         /* mu50 */  Quantile(res+1*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.50),
                         /* mu95 */  Quantile(res+1*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.975),
                         /* muMod */ 2./tree->mcmc->mode[tree->mcmc->num_move_phyrex_mu]);
                     
-          PhyML_Fprintf(fp_summary,"%f\t %f\t %f\t %f\t",
+          PhyML_Fprintf(fp_summary,"%G\t %G\t %G\t %G\t",
                         /* sig5 */   Quantile(res+2*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.025),
                         /* sig50*/   Quantile(res+2*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.50),
                         /* sig95*/   Quantile(res+2*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.975),
                         /* sigMod */ tree->mcmc->mode[tree->mcmc->num_move_phyrex_sigsq]);
           
-          PhyML_Fprintf(fp_summary,"%f\t %f\t %f\t %f\t",
+          PhyML_Fprintf(fp_summary,"%G\t %G\t %G\t %G\t",
                         /* Neigh5 */   Quantile(res+3*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.025),
                         /* Neigh50*/   Quantile(res+3*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.50),
                         /* Neigh95*/   Quantile(res+3*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.975),
                         /* NeighMod */ tree->mcmc->mode[tree->mcmc->num_move_phyrex_mu]);
 
           
-          PhyML_Fprintf(fp_summary,"%f\t %f\t %f\t",
+          PhyML_Fprintf(fp_summary,"%G\t %G\t %G\t",
                         /* Rad5 */  Quantile(res+4*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.025),
                         /* Rad50 */ Quantile(res+4*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.50),
                         /* Rad95 */ Quantile(res+4*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.975));
 
 
-          PhyML_Fprintf(fp_summary,"%f\t %f\t %f\t",
+          PhyML_Fprintf(fp_summary,"%G\t %G\t %G\t",
                         /* Int5 */  Quantile(res+5*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.025),
                         /* Int50 */ Quantile(res+5*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.50),
                         /* Int95 */ Quantile(res+5*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.975));
 
-          PhyML_Fprintf(fp_summary,"%f\t %f\t %f\t",
+          PhyML_Fprintf(fp_summary,"%G\t %G\t %G\t",
                         /* Coal5 */  Quantile(res+6*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.025),
                         /* Coal50 */ Quantile(res+6*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.50),
                         /* Coal95 */ Quantile(res+6*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.975));
 
-          PhyML_Fprintf(fp_summary,"%f\t %f\t %f\t",
+          PhyML_Fprintf(fp_summary,"%G\t %G\t %G\t",
                         /* Hit5 */  Quantile(res+7*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.025),
                         /* Hit50 */ Quantile(res+7*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.50),
                         /* Hit95 */ Quantile(res+7*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.975));
                     
-          PhyML_Fprintf(fp_summary,"%f\t %f\t %f\t",
+          PhyML_Fprintf(fp_summary,"%G\t %G\t %G\t",
                         /* rhoe5 */  Quantile(res+8*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.025),
                         /* rhoe50 */ Quantile(res+8*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.50),
                         /* rhoe95 */ Quantile(res+8*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.975));
 
-          PhyML_Fprintf(fp_summary,"%f\t %f\t %f\t",
+          PhyML_Fprintf(fp_summary,"%G\t %G\t %G\t",
+                        /* CoalRate5 */  Quantile(res+9*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.025),
+                        /* CoalRate50 */ Quantile(res+9*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.50),
+                        /* CoalRate95 */ Quantile(res+9*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.975));
+
+          PhyML_Fprintf(fp_summary,"%G\t %G\t %G\t",
                         tree->mcmc->ess[tree->mcmc->num_move_phyrex_lbda],
                         tree->mcmc->ess[tree->mcmc->num_move_phyrex_mu],  
                         tree->mcmc->ess[tree->mcmc->num_move_phyrex_sigsq]);
@@ -1529,9 +1566,9 @@ phydbl *PHYREX_MCMC(t_tree *tree)
 
       if(tree->mcmc->run > 2*adjust_len                            &&
          tree->mcmc->sample_num > 1E+2                             &&
-         tree->mcmc->ess[tree->mcmc->num_move_phyrex_lbda]  > 100. &&
-         tree->mcmc->ess[tree->mcmc->num_move_phyrex_mu]    > 100. &&
-         tree->mcmc->ess[tree->mcmc->num_move_phyrex_sigsq] > 100.) break;
+         tree->mcmc->ess[tree->mcmc->num_move_phyrex_lbda]  > 10000. &&
+         tree->mcmc->ess[tree->mcmc->num_move_phyrex_mu]    > 10000. &&
+         tree->mcmc->ess[tree->mcmc->num_move_phyrex_sigsq] > 10000.) break;
 
       /* if(tree->mcmc->run > tree->mcmc->sample_interval           &&  */
       /*    tree->mcmc->ess[tree->mcmc->num_move_phyrex_lbda]  > 1. && */
@@ -3324,7 +3361,7 @@ void PHYREX_Read_Tip_Coordinates(t_ldsk **ldsk_a, t_tree *tree)
       if(i != strlen(s)) continue;
       
       For(i,tree->n_otu) if(strstr(tree->a_nodes[i]->name,s)) break;
-      
+
       if(i != tree->n_otu) /* Found a match */
         {
           if(fscanf(fp,"%lf",&(ldsk_a[i]->coord->lonlat[0])) == EOF) break;
@@ -3991,14 +4028,15 @@ void PHYREX_Print_MultiTypeTree_Config_File(int n_sites, char *filename, t_tree
   PhyML_Fprintf(fp,"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");
   PhyML_Fprintf(fp,"\n<beast beautitemplate='MultiTypeTree' beautistatus='' namespace=\"beast.core:beast.evolution.alignment:beast.evolution.tree.coalescent:beast.core.util:beast.evolution.nuc:beast.evolution.operators:beast.evolution.sitemodel:beast.evolution.substitutionmodel:beast.evolution.likelihood\" version=\"2.0\">");
 
-  PhyML_Fprintf(fp,"\n<data id=\"h3n2\" name=\"alignment\">");
+  PhyML_Fprintf(fp,"\n<data id=\"data\" name=\"alignment\">");
 
 
   For(i,tree->n_otu)
     {
       PhyML_Fprintf(fp,"\n<sequence id=\"%s\" taxon=\"%s\" totalcount=\"4\" value=\"%s\"/>",
                    tree->a_nodes[i]->coord->id,
-                   tree->a_nodes[i]->coord->id,
+                   /* tree->a_nodes[i]->coord->id, */
+                   tree->a_nodes[i]->name,
                    tree->a_nodes[i]->c_seq->state);
     }
 
@@ -4018,8 +4056,8 @@ void PHYREX_Print_MultiTypeTree_Config_File(int n_sites, char *filename, t_tree
 
   PhyML_Fprintf(fp,"\n<run id=\"mcmc\" spec=\"MCMC\" chainLength=\"1000000000\">");
   PhyML_Fprintf(fp,"\n<state id=\"state\" storeEvery=\"10000\">");
-  PhyML_Fprintf(fp,"\n<stateNode id=\"Tree.t:h3n2\" spec=\"beast.evolution.tree.StructuredCoalescentMultiTypeTree\">");
-  PhyML_Fprintf(fp,"\n<migrationModel id=\"migModelInit.t:h3n2\" spec=\"beast.evolution.tree.MigrationModel\">");
+  PhyML_Fprintf(fp,"\n<stateNode id=\"Tree.t:data\" spec=\"beast.evolution.tree.StructuredCoalescentMultiTypeTree\">");
+  PhyML_Fprintf(fp,"\n<migrationModel id=\"migModelInit.t:data\" spec=\"beast.evolution.tree.MigrationModel\">");
 
 
   s = (char *)mCalloc(T_MAX_LINE,sizeof(char));
@@ -4034,11 +4072,11 @@ void PHYREX_Print_MultiTypeTree_Config_File(int n_sites, char *filename, t_tree
 
   PhyML_Fprintf(fp,"\n</migrationModel>");
 
-  PhyML_Fprintf(fp,"\n<typeTrait id=\"typeTraitSet.t:h3n2\" spec=\"beast.evolution.tree.TraitSet\" traitname=\"type\" value=\"");
+  PhyML_Fprintf(fp,"\n<typeTrait id=\"typeTraitSet.t:data\" spec=\"beast.evolution.tree.TraitSet\" traitname=\"type\" value=\"");
 
   For(i,tree->n_otu)
     {
-      s = strchr(tree->a_nodes[i]->coord->id,'_');
+      s = strrchr(tree->a_nodes[i]->coord->id,'_');
       PhyML_Fprintf(fp,"%s=%s",
                    tree->a_nodes[i]->coord->id,
                    s+1);
@@ -4048,100 +4086,100 @@ void PHYREX_Print_MultiTypeTree_Config_File(int n_sites, char *filename, t_tree
     }
 
   PhyML_Fprintf(fp,"\n<taxa id=\"TaxonSet.0\" spec=\"TaxonSet\">");
-  PhyML_Fprintf(fp,"\n<alignment idref=\"h3n2\"/>");
+  PhyML_Fprintf(fp,"\n<alignment idref=\"data\"/>");
   PhyML_Fprintf(fp,"\n</taxa>");
   PhyML_Fprintf(fp,"\n</typeTrait>");
   PhyML_Fprintf(fp,"\n<taxonset idref=\"TaxonSet.0\"/>");
   PhyML_Fprintf(fp,"\n</stateNode>");
-  PhyML_Fprintf(fp,"\n<parameter id=\"kappa.s:h3n2\" lower=\"0.0\" name=\"stateNode\">2.0</parameter>");
+  PhyML_Fprintf(fp,"\n<parameter id=\"kappa.s:data\" lower=\"0.0\" name=\"stateNode\">2.0</parameter>");
 
   s = (char *)mCalloc(T_MAX_LINE,sizeof(char));
   For(i,n_demes) strcat(s,"1.0 ");
-  PhyML_Fprintf(fp,"\n<parameter id=\"popSizes.t:h3n2\" dimension=\"%d\" name=\"stateNode\">%s</parameter>",n_demes,s);
+  PhyML_Fprintf(fp,"\n<parameter id=\"popSizes.t:data\" dimension=\"%d\" name=\"stateNode\">%s</parameter>",n_demes,s);
   Free(s);
 
   s = (char *)mCalloc(T_MAX_LINE,sizeof(char));
   For(i,n_demes*(n_demes-1)) strcat(s,"1.0 ");
-  PhyML_Fprintf(fp,"\n<parameter id=\"rateMatrix.t:h3n2\" dimension=\"%d\" name=\"stateNode\">%s</parameter>",n_demes*(n_demes-1),s);
+  PhyML_Fprintf(fp,"\n<parameter id=\"rateMatrix.t:data\" dimension=\"%d\" name=\"stateNode\">%s</parameter>",n_demes*(n_demes-1),s);
   Free(s);
 
 
-  PhyML_Fprintf(fp,"\n<parameter id=\"freqParameter.s:h3n2\" dimension=\"4\" lower=\"0.0\" name=\"stateNode\" upper=\"1.0\">0.25</parameter>");
+  PhyML_Fprintf(fp,"\n<parameter id=\"freqParameter.s:data\" dimension=\"4\" lower=\"0.0\" name=\"stateNode\" upper=\"1.0\">0.25</parameter>");
   PhyML_Fprintf(fp,"\n</state>");
 
 
   PhyML_Fprintf(fp,"\n<distribution id=\"posterior\" spec=\"util.CompoundDistribution\">");
   PhyML_Fprintf(fp,"\n<distribution id=\"prior\" spec=\"util.CompoundDistribution\">");
-  PhyML_Fprintf(fp,"\n<prior id=\"KappaPrior.s:h3n2\" name=\"distribution\" x=\"@kappa.s:h3n2\">");
+  PhyML_Fprintf(fp,"\n<prior id=\"KappaPrior.s:data\" name=\"distribution\" x=\"@kappa.s:data\">");
   PhyML_Fprintf(fp,"\n<LogNormal id=\"LogNormalDistributionModel.0\" name=\"distr\">");
   PhyML_Fprintf(fp,"\n<parameter id=\"RealParameter.02\" estimate=\"false\" name=\"M\">1.0</parameter>");
   PhyML_Fprintf(fp,"\n<parameter id=\"RealParameter.03\" estimate=\"false\" name=\"S\">1.25</parameter>");
   PhyML_Fprintf(fp,"\n</LogNormal>");
   PhyML_Fprintf(fp,"\n</prior>");
 
-  PhyML_Fprintf(fp,"\n<prior id=\"popSizesPrior.t:h3n2\" name=\"distribution\" x=\"@popSizes.t:h3n2\">");
+  PhyML_Fprintf(fp,"\n<prior id=\"popSizesPrior.t:data\" name=\"distribution\" x=\"@popSizes.t:data\">");
   PhyML_Fprintf(fp,"\n<LogNormal id=\"LogNormalDistributionModel.01\" name=\"distr\">");
   PhyML_Fprintf(fp,"\n<parameter id=\"RealParameter.04\" estimate=\"false\" name=\"M\">1.0</parameter>");
   PhyML_Fprintf(fp,"\n<parameter id=\"RealParameter.05\" estimate=\"false\" lower=\"0.0\" name=\"S\" upper=\"5.0\">1.25</parameter>");
   PhyML_Fprintf(fp,"\n</LogNormal>");
   PhyML_Fprintf(fp,"\n</prior>");
 
-  PhyML_Fprintf(fp,"\n<prior id=\"rateMatrixPrior.t:h3n2\" name=\"distribution\" x=\"@rateMatrix.t:h3n2\">");
+  PhyML_Fprintf(fp,"\n<prior id=\"rateMatrixPrior.t:data\" name=\"distribution\" x=\"@rateMatrix.t:data\">");
   PhyML_Fprintf(fp,"\n<LogNormal id=\"LogNormalDistributionModel.02\" name=\"distr\">");
   PhyML_Fprintf(fp,"\n<parameter id=\"RealParameter.06\" estimate=\"false\" name=\"M\">1.0</parameter>");
   PhyML_Fprintf(fp,"\n<parameter id=\"RealParameter.07\" estimate=\"false\" lower=\"0.0\" name=\"S\" upper=\"5.0\">1.25</parameter>");
   PhyML_Fprintf(fp,"\n</LogNormal>");
   PhyML_Fprintf(fp,"\n</prior>");
 
-  PhyML_Fprintf(fp,"\n<distribution id=\"structuredCoalescent.t:h3n2\" spec=\"multitypetree.distributions.StructuredCoalescentTreeDensity\" multiTypeTree=\"@Tree.t:h3n2\">");
-  PhyML_Fprintf(fp,"\n<migrationModel id=\"migModel.t:h3n2\" spec=\"beast.evolution.tree.MigrationModel\" popSizes=\"@popSizes.t:h3n2\" rateMatrix=\"@rateMatrix.t:h3n2\">");
+  PhyML_Fprintf(fp,"\n<distribution id=\"structuredCoalescent.t:data\" spec=\"multitypetree.distributions.StructuredCoalescentTreeDensity\" multiTypeTree=\"@Tree.t:data\">");
+  PhyML_Fprintf(fp,"\n<migrationModel id=\"migModel.t:data\" spec=\"beast.evolution.tree.MigrationModel\" popSizes=\"@popSizes.t:data\" rateMatrix=\"@rateMatrix.t:data\">");
   PhyML_Fprintf(fp,"\n</migrationModel>");
   PhyML_Fprintf(fp,"\n</distribution>");
 
   PhyML_Fprintf(fp,"\n<distribution id=\"likelihood\" spec=\"util.CompoundDistribution\">");
-  PhyML_Fprintf(fp,"\n<distribution id=\"treeLikelihood.h3n2\" spec=\"TreeLikelihood\" data=\"@h3n2\" tree=\"@Tree.t:h3n2\">");
-  PhyML_Fprintf(fp,"\n<siteModel id=\"SiteModel.s:h3n2\" spec=\"SiteModel\">");
-  PhyML_Fprintf(fp,"\n<parameter id=\"mutationRate.s:h3n2\" estimate=\"false\" name=\"mutationRate\">1.0</parameter>");
-  PhyML_Fprintf(fp,"\n<parameter id=\"gammaShape.s:h3n2\" estimate=\"false\" name=\"shape\">1.0</parameter>");
-  PhyML_Fprintf(fp,"\n<parameter id=\"proportionInvariant.s:h3n2\" estimate=\"false\" lower=\"0.0\" name=\"proportionInvariant\" upper=\"1.0\">0.0</parameter>");
-  PhyML_Fprintf(fp,"\n<substModel id=\"hky.s:h3n2\" spec=\"HKY\" kappa=\"@kappa.s:h3n2\">");
-  PhyML_Fprintf(fp,"\n<frequencies id=\"estimatedFreqs.s:h3n2\" spec=\"Frequencies\" frequencies=\"@freqParameter.s:h3n2\"/>");
+  PhyML_Fprintf(fp,"\n<distribution id=\"treeLikelihood.data\" spec=\"TreeLikelihood\" data=\"@data\" tree=\"@Tree.t:data\">");
+  PhyML_Fprintf(fp,"\n<siteModel id=\"SiteModel.s:data\" spec=\"SiteModel\">");
+  PhyML_Fprintf(fp,"\n<parameter id=\"mutationRate.s:data\" estimate=\"false\" name=\"mutationRate\">1.0</parameter>");
+  PhyML_Fprintf(fp,"\n<parameter id=\"gammaShape.s:data\" estimate=\"false\" name=\"shape\">1.0</parameter>");
+  PhyML_Fprintf(fp,"\n<parameter id=\"proportionInvariant.s:data\" estimate=\"false\" lower=\"0.0\" name=\"proportionInvariant\" upper=\"1.0\">0.0</parameter>");
+  PhyML_Fprintf(fp,"\n<substModel id=\"hky.s:data\" spec=\"HKY\" kappa=\"@kappa.s:data\">");
+  PhyML_Fprintf(fp,"\n<frequencies id=\"estimatedFreqs.s:data\" spec=\"Frequencies\" frequencies=\"@freqParameter.s:data\"/>");
   PhyML_Fprintf(fp,"\n</substModel>");
   PhyML_Fprintf(fp,"\n</siteModel>");
-  PhyML_Fprintf(fp,"\n<branchRateModel id=\"StrictClock.c:h3n2\" spec=\"beast.evolution.branchratemodel.StrictClockModel\">");
-  PhyML_Fprintf(fp,"\n<parameter id=\"clockRate.c:h3n2\" estimate=\"false\" name=\"clock.rate\">%G</parameter>",1.0);
+  PhyML_Fprintf(fp,"\n<branchRateModel id=\"StrictClock.c:data\" spec=\"beast.evolution.branchratemodel.StrictClockModel\">");
+  PhyML_Fprintf(fp,"\n<parameter id=\"clockRate.c:data\" estimate=\"false\" name=\"clock.rate\">%G</parameter>",1.0);
   PhyML_Fprintf(fp,"\n</branchRateModel>");
   PhyML_Fprintf(fp,"\n</distribution>");
   PhyML_Fprintf(fp,"\n</distribution>");
   PhyML_Fprintf(fp,"\n</distribution>");
   PhyML_Fprintf(fp,"\n</distribution>");
   PhyML_Fprintf(fp,"\n");
-  PhyML_Fprintf(fp,"\n<operator id=\"STX.t:h3n2\" spec=\"multitypetree.operators.TypedSubtreeExchange\" migrationModel=\"@migModel.t:h3n2\" multiTypeTree=\"@Tree.t:h3n2\" weight=\"10.0\"/>");
-  PhyML_Fprintf(fp,"\n<operator id=\"TWB.t:h3n2\" spec=\"multitypetree.operators.TypedWilsonBalding\" alpha=\"0.2\" migrationModel=\"@migModel.t:h3n2\" multiTypeTree=\"@Tree.t:h3n2\" weight=\"10.0\"/>");
-  PhyML_Fprintf(fp,"\n<operator id=\"NR.t:h3n2\" spec=\"multitypetree.operators.NodeRetype\" migrationModel=\"@migModel.t:h3n2\" multiTypeTree=\"@Tree.t:h3n2\" weight=\"10.0\"/>");
-  PhyML_Fprintf(fp,"\n<operator id=\"NSR1.t:h3n2\" spec=\"multitypetree.operators.NodeShiftRetype\" migrationModel=\"@migModel.t:h3n2\" multiTypeTree=\"@Tree.t:h3n2\" rootOnly=\"true\" weight=\"10.0\"/>");
-  PhyML_Fprintf(fp,"\n<operator id=\"NSR2.t:h3n2\" spec=\"multitypetree.operators.NodeShiftRetype\" migrationModel=\"@migModel.t:h3n2\" multiTypeTree=\"@Tree.t:h3n2\" noRoot=\"true\" weight=\"10.0\"/>");
-  PhyML_Fprintf(fp,"<operator id=\"MTU.t:h3n2\" spec=\"multitypetree.operators.MultiTypeUniform\" includeRoot=\"true\" migrationModel=\"@migModel.t:h3n2\" multiTypeTree=\"@Tree.t:h3n2\" weight=\"10.0\"/>\n");
-  PhyML_Fprintf(fp,"<operator id=\"MTTS.t:h3n2\" spec=\"multitypetree.operators.MultiTypeTreeScale\" migrationModel=\"@migModel.t:h3n2\" multiTypeTree=\"@Tree.t:h3n2\" scaleFactor=\"0.98\" useOldTreeScaler=\"true\" weight=\"10.0\"/>\n");
-  PhyML_Fprintf(fp,"\n<operator id=\"MTTUpDown.t:h3n2\" spec=\"multitypetree.operators.MultiTypeTreeScale\" migrationModel=\"@migModel.t:h3n2\" multiTypeTree=\"@Tree.t:h3n2\" scaleFactor=\"0.98\" useOldTreeScaler=\"true\" weight=\"10.0\">");
-  PhyML_Fprintf(fp,"\n<parameter idref=\"popSizes.t:h3n2\"/>");
+  PhyML_Fprintf(fp,"\n<operator id=\"STX.t:data\" spec=\"multitypetree.operators.TypedSubtreeExchange\" migrationModel=\"@migModel.t:data\" multiTypeTree=\"@Tree.t:data\" weight=\"10.0\"/>");
+  PhyML_Fprintf(fp,"\n<operator id=\"TWB.t:data\" spec=\"multitypetree.operators.TypedWilsonBalding\" alpha=\"0.2\" migrationModel=\"@migModel.t:data\" multiTypeTree=\"@Tree.t:data\" weight=\"10.0\"/>");
+  PhyML_Fprintf(fp,"\n<operator id=\"NR.t:data\" spec=\"multitypetree.operators.NodeRetype\" migrationModel=\"@migModel.t:data\" multiTypeTree=\"@Tree.t:data\" weight=\"10.0\"/>");
+  PhyML_Fprintf(fp,"\n<operator id=\"NSR1.t:data\" spec=\"multitypetree.operators.NodeShiftRetype\" migrationModel=\"@migModel.t:data\" multiTypeTree=\"@Tree.t:data\" rootOnly=\"true\" weight=\"10.0\"/>");
+  PhyML_Fprintf(fp,"\n<operator id=\"NSR2.t:data\" spec=\"multitypetree.operators.NodeShiftRetype\" migrationModel=\"@migModel.t:data\" multiTypeTree=\"@Tree.t:data\" noRoot=\"true\" weight=\"10.0\"/>");
+  PhyML_Fprintf(fp,"<operator id=\"MTU.t:data\" spec=\"multitypetree.operators.MultiTypeUniform\" includeRoot=\"true\" migrationModel=\"@migModel.t:data\" multiTypeTree=\"@Tree.t:data\" weight=\"10.0\"/>\n");
+  PhyML_Fprintf(fp,"<operator id=\"MTTS.t:data\" spec=\"multitypetree.operators.MultiTypeTreeScale\" migrationModel=\"@migModel.t:data\" multiTypeTree=\"@Tree.t:data\" scaleFactor=\"0.98\" useOldTreeScaler=\"true\" weight=\"10.0\"/>\n");
+  PhyML_Fprintf(fp,"\n<operator id=\"MTTUpDown.t:data\" spec=\"multitypetree.operators.MultiTypeTreeScale\" migrationModel=\"@migModel.t:data\" multiTypeTree=\"@Tree.t:data\" scaleFactor=\"0.98\" useOldTreeScaler=\"true\" weight=\"10.0\">");
+  PhyML_Fprintf(fp,"\n<parameter idref=\"popSizes.t:data\"/>");
   PhyML_Fprintf(fp,"\n</operator>");
-  PhyML_Fprintf(fp,"\n<operator id=\"KappaScaler.s:h3n2\" spec=\"ScaleOperator\" parameter=\"@kappa.s:h3n2\" scaleFactor=\"0.5\" weight=\"0.1\"/>");
-  PhyML_Fprintf(fp,"\n<operator id=\"popSizesScaler.t:h3n2\" spec=\"ScaleOperator\" parameter=\"@popSizes.t:h3n2\" scaleFactor=\"0.8\" weight=\"1.0\"/>");
-  PhyML_Fprintf(fp,"\n<operator id=\"rateMatrixScaler.t:h3n2\" spec=\"ScaleOperator\" parameter=\"@rateMatrix.t:h3n2\" scaleFactor=\"0.8\" weight=\"1.0\"/>");
-  PhyML_Fprintf(fp,"\n<operator id=\"FrequenciesExchanger.s:h3n2\" spec=\"DeltaExchangeOperator\" delta=\"0.01\" weight=\"0.1\">");
-  PhyML_Fprintf(fp,"\n<parameter idref=\"freqParameter.s:h3n2\"/>");
+  PhyML_Fprintf(fp,"\n<operator id=\"KappaScaler.s:data\" spec=\"ScaleOperator\" parameter=\"@kappa.s:data\" scaleFactor=\"0.5\" weight=\"0.1\"/>");
+  PhyML_Fprintf(fp,"\n<operator id=\"popSizesScaler.t:data\" spec=\"ScaleOperator\" parameter=\"@popSizes.t:data\" scaleFactor=\"0.8\" weight=\"1.0\"/>");
+  PhyML_Fprintf(fp,"\n<operator id=\"rateMatrixScaler.t:data\" spec=\"ScaleOperator\" parameter=\"@rateMatrix.t:data\" scaleFactor=\"0.8\" weight=\"1.0\"/>");
+  PhyML_Fprintf(fp,"\n<operator id=\"FrequenciesExchanger.s:data\" spec=\"DeltaExchangeOperator\" delta=\"0.01\" weight=\"0.1\">");
+  PhyML_Fprintf(fp,"\n<parameter idref=\"freqParameter.s:data\"/>");
   PhyML_Fprintf(fp,"\n</operator>");
   PhyML_Fprintf(fp,"\n");
   PhyML_Fprintf(fp,"\n<logger id=\"tracelog\" fileName=\"$(filebase).log\" logEvery=\"10000\">");
   PhyML_Fprintf(fp,"\n<log idref=\"likelihood\"/>");
   PhyML_Fprintf(fp,"\n<log idref=\"prior\"/>");
-  PhyML_Fprintf(fp,"\n<log idref=\"treeLikelihood.h3n2\"/>");
-  PhyML_Fprintf(fp,"\n<log id=\"treeHeight.t:h3n2\" spec=\"beast.evolution.tree.TreeHeightLogger\" tree=\"@Tree.t:h3n2\"/>");
-  /* PhyML_Fprintf(fp,"\n<log id=\"treeLength.t:h3n2\" spec=\"multitypetree.util.TreeLengthLogger\" tree=\"@Tree.t:h3n2\"/>"); */
-  /* PhyML_Fprintf(fp,"\n<log id=\"changeCounts.t:h3n2\" spec=\"multitypetree.util.TypeChangeCounts\" migrationModel=\"@migModel.t:h3n2\" multiTypeTree=\"@Tree.t:h3n2\"/>"); */
-  /* PhyML_Fprintf(fp,"\n<log id=\"rootTypeLogger.t:h3n2\" spec=\"multitypetree.util.TreeRootTypeLogger\" multiTypeTree=\"@Tree.t:h3n2\"/>"); */
-  PhyML_Fprintf(fp,"\n<log id=\"migModelLogger.t:h3n2\" spec=\"multitypetree.util.MigrationModelLogger\" migrationModel=\"@migModel.t:h3n2\" multiTypeTree=\"@Tree.t:h3n2\"/>");
+  PhyML_Fprintf(fp,"\n<log idref=\"treeLikelihood.data\"/>");
+  PhyML_Fprintf(fp,"\n<log id=\"treeHeight.t:data\" spec=\"beast.evolution.tree.TreeHeightLogger\" tree=\"@Tree.t:data\"/>");
+  /* PhyML_Fprintf(fp,"\n<log id=\"treeLength.t:data\" spec=\"multitypetree.util.TreeLengthLogger\" tree=\"@Tree.t:data\"/>"); */
+  /* PhyML_Fprintf(fp,"\n<log id=\"changeCounts.t:data\" spec=\"multitypetree.util.TypeChangeCounts\" migrationModel=\"@migModel.t:data\" multiTypeTree=\"@Tree.t:data\"/>"); */
+  /* PhyML_Fprintf(fp,"\n<log id=\"rootTypeLogger.t:data\" spec=\"multitypetree.util.TreeRootTypeLogger\" multiTypeTree=\"@Tree.t:data\"/>"); */
+  PhyML_Fprintf(fp,"\n<log id=\"migModelLogger.t:data\" spec=\"multitypetree.util.MigrationModelLogger\" migrationModel=\"@migModel.t:data\" multiTypeTree=\"@Tree.t:data\"/>");
   PhyML_Fprintf(fp,"\n</logger>");
   PhyML_Fprintf(fp,"\n");
   PhyML_Fprintf(fp,"\n<logger id=\"screenlog\" logEvery=\"50000\">");
@@ -4158,11 +4196,60 @@ void PHYREX_Print_MultiTypeTree_Config_File(int n_sites, char *filename, t_tree
   fclose(fp);
 }
 
-
 /*////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////*/
+
+int PHYREX_Number_Of_Sampled_Demes(t_tree *tree)
+{
+  int i,j,n_demes;
+  t_dsk *disk;
+  char **deme_list;
+
+  deme_list = (char **)mCalloc(tree->n_otu,sizeof(char *));
+
+  disk = tree->disk;
+
+  n_demes = 0;
+  For(i,tree->n_otu)
+    {
+      For(j,n_demes)
+        {
+          if(deme_list[j] != NULL && !strcmp(strstr(disk->ldsk_a[i]->coord->id,"_deme"),deme_list[j]))
+            {
+              break;
+            }
+        }
+
+      if(j == n_demes)
+        {
+          deme_list[j] = strstr(disk->ldsk_a[i]->coord->id,"_deme");
+          /* printf("\n. deme_list[%d]: %s",j,deme_list[j]); */
+          n_demes++;
+        }
+    }
+
+  Free(deme_list);
+
+
+  return(n_demes);
+}
+
 /*////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////*/
+// Coalescence rate with time expressed in calendar unit
+phydbl PHYREX_Coalescence_Rate(t_tree *tree)
+{
+  phydbl mu,theta,lbda,w,h;
+
+  mu    = tree->mmod->mu;
+  theta = tree->mmod->rad;
+  lbda  = tree->mmod->lbda;
+  w     = tree->mmod->lim->lonlat[0];
+  h     = tree->mmod->lim->lonlat[1];
+
+  return(4.*POW(PI,2)*POW(theta,4)*POW(mu,2)*lbda / (POW(w,2)*POW(h,2)));
+}
+
 /*////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////*/
 /*////////////////////////////////////////////////////////////
diff --git a/src/phyrex.h b/src/phyrex.h
index 5e9409f..11668b3 100644
--- a/src/phyrex.h
+++ b/src/phyrex.h
@@ -69,7 +69,7 @@ void PHYREX_Remove_Lindisk_Next(t_ldsk *ldsk, t_ldsk *rm);
 phydbl PHYREX_Simulate_Backward_Core(int new_loc, t_dsk *init_disk, t_tree *tree);
 phydbl *PHYREX_Mean_Pairwise_Distance_Between_Lineage_Locations(t_tree *tree);
 phydbl PHYREX_Random_Select_Time_Between_Jumps(t_tree *tree);
-phydbl PHYREX_Simulate_Forward_Core(int n_sites, t_tree *tree);
+t_sarea *PHYREX_Simulate_Forward_Core(int n_sites, t_tree *tree);
 int PHYREX_Is_In_Ldscape(t_ldsk *ldsk, t_phyrex_mod *mmod);
 void PHYREX_Update_Lindisk_List_Core(t_dsk *disk, t_tree *tree);
 phydbl PHYREX_Mean_Time_Between_Events(t_tree *tree);
@@ -106,6 +106,8 @@ phydbl PHYREX_Lk_Range(t_dsk *young, t_dsk *old, t_tree *tree);
 void PHYREX_Print_MultiTypeTree_Config_File(int n_sites, char *filename, t_tree *tree);
 phydbl PHYREX_Effective_Density(t_tree *tree);
 phydbl PHYREX_Generation_Length(t_tree *tree);
+int PHYREX_Number_Of_Sampled_Demes(t_tree *tree);
+phydbl PHYREX_Coalescence_Rate(t_tree *tree);
 
 
 
diff --git a/src/rates.c b/src/rates.c
index 6a2926b..0e58cac 100644
--- a/src/rates.c
+++ b/src/rates.c
@@ -428,7 +428,7 @@ phydbl RATES_Lk_Rates_Core(phydbl br_r_a, phydbl br_r_d, phydbl nd_r_a, phydbl n
 
     default : 
       {
-	PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__);
+	PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__);
 	Warn_And_Exit("");
       }
     }
@@ -2487,10 +2487,8 @@ void RATES_Update_Cur_Bl_Pre(t_node *a, t_node *d, t_edge *b, t_tree *tree)
       if(b && (isnan(b->l->v) || isnan(b->l_var->v)))
 	{
 	  PhyML_Printf("\n== dt=%G rr=%G cr=%G ra=%G rd=%G nu=%G %f %f ",dt,rr,cr,ra,rd,nu,b->l_var->v,b->l->v);	  
-	  PhyML_Printf("\n== ta=%G td=%G ra*cr=%G rd*cr=%G sd=%G",
-		       ta,td,ra*cr,rd*cr,
-		       SQRT(dt*nu)*cr);
-	  PhyML_Printf("\n== Err. in file %s at line %d (function '%s')\n",__FILE__,__LINE__,__FUNCTION__);
+	  PhyML_Printf("\n== ta=%G td=%G ra*cr=%G rd*cr=%G sd=%G",ta,td,ra*cr,rd*cr,SQRT(dt*nu)*cr);
+	  PhyML_Printf("\n== Err. in file %s at line %d (function '%s').\n",__FILE__,__LINE__,__FUNCTION__);
 	  Exit("\n");
 	}
     }
diff --git a/src/simu.c b/src/simu.c
index 57e9f87..92d4765 100644
--- a/src/simu.c
+++ b/src/simu.c
@@ -19,36 +19,72 @@ the GNU public licence.  See http://www.opensource.org for details.
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-void Simu_Loop(t_tree *mixt_tree)
+void Simu_Loop(t_tree *tree)
 {
-  phydbl lk_old;
+  phydbl lk_old,delta_lnL;
+  int n_round;
 
-  SPR_Shuffle(mixt_tree);
+  tree->best_pars                  = 1E+8;
+  tree->mod->s_opt->spr_lnL        = NO;
+  tree->mod->s_opt->spr_pars       = NO;
+  tree->mod->s_opt->quickdirty     = NO;
 
-  Set_Both_Sides(YES,mixt_tree);
-  Lk(NULL,mixt_tree);
-  mixt_tree->best_lnL = mixt_tree->c_lnL;
-  if(mixt_tree->mod->s_opt->print) PhyML_Printf("\n. Current value of log-likelihood: %f",mixt_tree->c_lnL);
+  if((tree->mod->s_opt->print) && (!tree->io->quiet)) PhyML_Printf("\n\n. Maximizing likelihood (using SPR moves)...\n");
 
-  int n_tot_moves = 0;
+  tree->mod->s_opt->max_depth_path = tree->n_otu;
+  Spr_Pars(0,10,tree);
+  Set_Both_Sides(YES,tree);
+  Lk(NULL,tree);
+
+  n_round = 0;
   do
     {
-      lk_old = mixt_tree->c_lnL;
-      Optimiz_All_Free_Param(mixt_tree,(mixt_tree->io->quiet)?(0):(mixt_tree->mod->s_opt->print));
-      n_tot_moves = Simu(mixt_tree,10);
-      if(!n_tot_moves) break;
+      Optimiz_All_Free_Param(tree,(tree->io->quiet)?(NO):(tree->mod->s_opt->print));
+      Optimize_Br_Len_Serie(tree);
     }
-  while(mixt_tree->c_lnL > lk_old + mixt_tree->mod->s_opt->min_diff_lk_local);
+  while(++n_round != 3); 
+
+  tree->best_pars = tree->c_pars;
+  tree->best_lnL  = tree->c_lnL;
+
+
 
+  /*****************************/
+  if(tree->mod->s_opt->print == YES && tree->io->quiet == NO) PhyML_Printf("\n\n. First round of SPR moves...\n");
+  lk_old = tree->c_lnL;
+  tree->mod->s_opt->max_depth_path    = tree->n_otu;
+  tree->mod->s_opt->max_delta_lnL_spr = (tree->io->datatype == NT)?(0.):(0.);
+  tree->mod->s_opt->spr_lnL           = NO;
+  tree->mod->s_opt->spr_pars          = NO;
+  tree->mod->s_opt->min_diff_lk_move  = 0.1;
+  delta_lnL                           = 3.0;
+  Speed_Spr(tree,1.0,20,delta_lnL);
+  Optimiz_All_Free_Param(tree,(tree->io->quiet)?(NO):(tree->mod->s_opt->print));
+
+  /*****************************/
+  tree->mod->s_opt->min_diff_lk_move  = 0.001;
+  lk_old = UNLIKELY;
   do
     {
-      Round_Optimize(mixt_tree,mixt_tree->data,ROUND_MAX);
-      if(!Check_NNI_Five_Branches(mixt_tree)) break;
+      lk_old = tree->c_lnL;
+      if(!Simu(tree,5)) break;
+    }
+  while(FABS(lk_old - tree->c_lnL) > tree->mod->s_opt->min_diff_lk_local);
+  /*****************************/
+
+  Optimiz_All_Free_Param(tree,(tree->io->quiet)?(NO):(tree->mod->s_opt->print));
+
+  /*****************************/
+  do
+    {
+      Round_Optimize(tree,tree->data,ROUND_MAX);
+      if(!Check_NNI_Five_Branches(tree)) break;
     }
   while(1);
+  /*****************************/
+
+/*   if((tree->mod->s_opt->print) && (!tree->io->quiet)) PhyML_Printf("\n"); */
 
-  if((mixt_tree->mod->s_opt->print) &&
-     (!mixt_tree->io->quiet)) PhyML_Printf("\n");
 }
 
 //////////////////////////////////////////////////////////////
@@ -66,7 +102,6 @@ int Simu(t_tree *tree, int n_step_max)
   old_loglk           = UNLIKELY;
   tree->c_lnL         = UNLIKELY;
   n_iter              = 1.0;
-  /* it_lim_without_swap = (tree->mod->ras->invar)?(5):(2); */
   it_lim_without_swap = (tree->mod->ras->invar)?(1):(1);
   n_tested            = 0;
   n_without_swap      = 0;
@@ -93,11 +128,19 @@ int Simu(t_tree *tree, int n_step_max)
       Lk(NULL,tree);
       MIXT_Set_Alias_Subpatt(NO,tree);
 
+      if(tree->c_lnL > old_loglk - 5.0)
+        {
+          MIXT_Set_Alias_Subpatt(YES,tree);
+          Optimize_Br_Len_Serie(tree);
+          Set_Both_Sides(YES,tree);
+          Lk(NULL,tree);
+          MIXT_Set_Alias_Subpatt(NO,tree);
+        }
+
       if(tree->c_lnL < old_loglk)
         {
           if((tree->mod->s_opt->print) && (!tree->io->quiet)) PhyML_Printf("\n\n. Moving backward\n");
-          if(!Mov_Backward_Topo_Bl(tree,old_loglk,tested_b,n_tested))
-            Exit("\n== Err. mov_back failed\n");
+          if(!Mov_Backward_Topo_Bl(tree,old_loglk,tested_b,n_tested)) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
           if(!tree->n_swap) n_neg = 0;
           Record_Br_Len(tree);
           Set_Both_Sides(YES,tree);
@@ -114,12 +157,12 @@ int Simu(t_tree *tree, int n_step_max)
           Free(s);
         }
 
+      if(tree->io->print_json_trace == YES) JSON_Tree_Io(tree,tree->io->fp_out_json_trace); 
+
       if((tree->mod->s_opt->print) && (!tree->io->quiet)) Print_Lk(tree,"[Topology           ]");
 
-/*       if(((tree->c_lnL > old_loglk) && (FABS(old_loglk-tree->c_lnL) < tree->mod->s_opt->min_diff_lk_local)) || (n_without_swap > it_lim_without_swap)) break; */
       if((FABS(old_loglk-tree->c_lnL) < tree->mod->s_opt->min_diff_lk_global) || (n_without_swap > it_lim_without_swap)) break;
 
-      Fill_Dir_Table(tree);
       Fix_All(tree);
       n_neg = 0;
       For(i,2*tree->n_otu-3)
@@ -127,6 +170,7 @@ int Simu(t_tree *tree, int n_step_max)
            (!tree->a_edges[i]->rght->tax))
           NNI(tree,tree->a_edges[i],0);
 
+
       Select_Edges_To_Swap(tree,sorted_b,&n_neg);
       Sort_Edges_NNI_Score(tree,sorted_b,n_neg);
       Optimiz_Ext_Br(tree);
@@ -210,18 +254,15 @@ void Simu_Pars(t_tree *tree, int n_step_max)
           if((tree->mod->s_opt->print) && (!tree->io->quiet))
             PhyML_Printf("\n\n. Moving backward (topoLlogy) \n");
           if(!Mov_Backward_Topo_Pars(tree,old_pars,tested_b,n_tested))
-            Exit("\n. Err: mov_back failed\n");
+            Generic_Exit(__FILE__,__LINE__,__FUNCTION__);    
           if(!tree->n_swap) n_neg = 0;
           
-          
           Set_Both_Sides(YES,tree);
           Pars(NULL,tree);
         }
       else
-        {
-          
+        {          
           old_pars = tree->c_pars;
-          Fill_Dir_Table(tree);
           
           n_neg = 0;
           For(i,2*tree->n_otu-3)
@@ -285,65 +326,64 @@ void Select_Edges_To_Swap(t_tree *tree, t_edge **sorted_b, int *n_neg)
 void Update_Bl(t_tree *tree, phydbl fact)
 {
   int i;
-  t_edge *b,*orig;
+  scalar_dbl *l,*l_old,*l0;
 
   For(i,2*tree->n_otu-3)
     {
-      b = tree->a_edges[i];
-      /* b->l->v = b->l_old->v + (b->nni->l0 - b->l_old->v)*fact;       */
+      l     = tree->a_edges[i]->l;
+      l_old = tree->a_edges[i]->l_old;
+      l0    = tree->a_edges[i]->nni->l0;
 
-      orig = b;
       do
-    {
-      b->l->v = b->l_old->v + (b->nni->l0 - b->l_old->v)*fact;
-      if(b->next) b = b->next;
-      else         b = b->next;
-    }
-      while(b);
-      b = orig;
-
+        {
+          l->v  = l_old->v + (l0->v - l_old->v)*fact;
+          l     = l->next;
+          l_old = l_old->next;
+          l0    = l0->next;
+        }
+      while(l);
     }
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Make_N_Swap(t_tree *tree,t_edge **b, int beg, int end)
 {
   int i;
-  int dim;
-  t_edge *orig;
+  /* t_edge *orig; */
+  t_node *n1,*n2,*n3,*n4;
 
-  dim = 2*tree->n_otu-2;
+  n1 = n2 = n3 = n4 = NULL;
 
-  /* PhyML_Printf("\n. Beg Actually performing swaps\n"); */
   tree->n_swap = 0;
   for(i=beg;i<end;i++)
     {
-      /* we use t_dir here to take into account previous modifications of the topology */
-      /* printf("\n. Swap on edge %d [%d %d %d %d]",b[i]->num, */
-      /* 	     b[i]->nni->swap_node_v2->v[tree->t_dir[b[i]->nni->swap_node_v2->num*dim+b[i]->nni->swap_node_v1->num]]->num, */
-      /* 	     b[i]->nni->swap_node_v2->num, */
-      /* 	     b[i]->nni->swap_node_v3->num, */
-      /* 	     b[i]->nni->swap_node_v3->v[tree->t_dir[b[i]->nni->swap_node_v3->num*dim+b[i]->nni->swap_node_v4->num]]->num); */
-
-      Swap(b[i]->nni->swap_node_v2->v[tree->t_dir[b[i]->nni->swap_node_v2->num*dim+b[i]->nni->swap_node_v1->num]],
-       b[i]->nni->swap_node_v2,
-       b[i]->nni->swap_node_v3,
-       b[i]->nni->swap_node_v3->v[tree->t_dir[b[i]->nni->swap_node_v3->num*dim+b[i]->nni->swap_node_v4->num]],
-       tree);
+      n1 = n2 = n3 = n4 = NULL;
+
+      if(b[i]->nni->best_conf == 1)
+        {
+          n1 = b[i]->left->v[b[i]->l_v2];
+          n2 = b[i]->left;
+          n3 = b[i]->rght;
+          n4 = b[i]->rght->v[b[i]->r_v1];
+        }
+      else if(b[i]->nni->best_conf == 2)
+        {
+          n1 = b[i]->left->v[b[i]->l_v2];
+          n2 = b[i]->left;
+          n3 = b[i]->rght;
+          n4 = b[i]->rght->v[b[i]->r_v2];
+        }
 
+      Swap(n1,n2,n3,n4,tree);
+      
       if(!Check_Topo_Constraints(tree,tree->io->cstr_tree))
         {
           /* Undo this swap as it violates one of the topological constraints
              defined in the input constraint tree
           */
-          Swap(b[i]->nni->swap_node_v2->v[tree->t_dir[b[i]->nni->swap_node_v2->num*dim+b[i]->nni->swap_node_v1->num]],
-               b[i]->nni->swap_node_v2,
-               b[i]->nni->swap_node_v3,
-               b[i]->nni->swap_node_v3->v[tree->t_dir[b[i]->nni->swap_node_v3->num*dim+b[i]->nni->swap_node_v4->num]],
-               tree);
+          Swap(n1,n2,n3,n4,tree);
         }
       
       if(tree->n_root)
@@ -352,15 +392,17 @@ void Make_N_Swap(t_tree *tree,t_edge **b, int beg, int end)
           tree->n_root->v[1] = tree->e_root->rght;
         }
       
-      orig = b[i];
-      do
-        {
-          b[i]->l->v = b[i]->nni->best_l;
-          if(b[i]->next) b[i] = b[i]->next;
-          else            b[i] = b[i]->next;
-        }
-      while(b[i]);
-      b[i] = orig;
+      Copy_Scalar_Dbl(b[i]->nni->best_l,b[i]->l);
+      Copy_Scalar_Dbl(b[i]->nni->best_v,b[i]->l_var);
+
+      /* orig = b[i]; */
+      /* do */
+      /*   { */
+      /*     b[i]->l->v = b[i]->nni->best_l; */
+      /*     b[i] = b[i]->next; */
+      /*   } */
+      /* while(b[i]); */
+      /* b[i] = orig; */
 
       tree->n_swap++;
     }
@@ -373,74 +415,72 @@ void Make_N_Swap(t_tree *tree,t_edge **b, int beg, int end)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 int Make_Best_Swap(t_tree *tree)
 {
   int i,j,return_value;
   t_edge *b,**sorted_b;
-  int dim;
-  t_edge *orig;
+  /* t_edge *orig; */
+  t_node *n1,*n2,*n3,*n4;
 
-  dim = 2*tree->n_otu-2;
 
   sorted_b = (t_edge **)mCalloc(tree->n_otu-3,sizeof(t_edge *));
-
+  
   j=0;
-  For(i,2*tree->n_otu-3) if((!tree->a_edges[i]->left->tax) &&
-                (!tree->a_edges[i]->rght->tax))
-                              sorted_b[j++] = tree->a_edges[i];
-
+  For(i,2*tree->n_otu-3) 
+    if((!tree->a_edges[i]->left->tax) &&
+       (!tree->a_edges[i]->rght->tax))
+      sorted_b[j++] = tree->a_edges[i];
+  
   Sort_Edges_NNI_Score(tree,sorted_b,tree->n_otu-3);
-
+  
   if(sorted_b[0]->nni->score < -0.0)
     {
       b = sorted_b[0];
       return_value = 1;
+      
+      n1 = n2 = n3 = n4 = NULL;
 
-      Swap(b->nni->swap_node_v2->v[tree->t_dir[b->nni->swap_node_v2->num*dim+b->nni->swap_node_v1->num]],
-       b->nni->swap_node_v2,
-       b->nni->swap_node_v3,
-       b->nni->swap_node_v3->v[tree->t_dir[b->nni->swap_node_v3->num*dim+b->nni->swap_node_v4->num]],
-       tree);
+      if(b->nni->best_conf == 1)
+        {
+          n1 = b->left->v[b->l_v2];
+          n2 = b->left;
+          n3 = b->rght;
+          n4 = b->rght->v[b->r_v1];
+        }
+      else if(b->nni->best_conf == 2)
+        {
+          n1 = b->left->v[b->l_v2];
+          n2 = b->left;
+          n3 = b->rght;
+          n4 = b->rght->v[b->r_v2];
+        }
 
+      Swap(n1,n2,n3,n4,tree);
+      
       if(!Check_Topo_Constraints(tree,tree->io->cstr_tree))
-    {
-      /* Undo this swap as it violates one of the topological constraints
-         defined in the input constraint tree
-      */
-      Swap(b->nni->swap_node_v2->v[tree->t_dir[b->nni->swap_node_v2->num*dim+b->nni->swap_node_v1->num]],
-           b->nni->swap_node_v2,
-           b->nni->swap_node_v3,
-           b->nni->swap_node_v3->v[tree->t_dir[b->nni->swap_node_v3->num*dim+b->nni->swap_node_v4->num]],
-           tree);
-    }
-
+        {
+          /* Undo this swap as it violates one of the topological constraints
+             defined in the input constraint tree
+          */
+          Swap(n1,n2,n3,n4,tree);
+        }
+      
       /* b->l->v = b->nni->best_l; */
-
-      orig = b;
-      do
-    {
-      b->l->v = b->nni->best_l;
-      if(b->next) b = b->next;
-      else         b = b->next;
-    }
-      while(b);
-      b = orig;
-
-
-/*       (b->nni->best_conf == 1)? */
-/* 	(Swap(b->left->v[b->l_v2],b->left,b->rght,b->rght->v[b->r_v1],tree)): */
-/* 	(Swap(b->left->v[b->l_v2],b->left,b->rght,b->rght->v[b->r_v2],tree)); */
-
-/*       b->l->v =  */
-/* 	(b->nni->best_conf == 1)? */
-/* 	(b->nni->l1): */
-/* 	(b->nni->l2); */
-
-
+      
+      Copy_Scalar_Dbl(b->nni->best_l,b->l);
+      Copy_Scalar_Dbl(b->nni->best_v,b->l_var);
+
+      /* orig = b; */
+      /* do */
+      /*   { */
+      /*     b->l->v = b->nni->best_l; */
+      /*     b = b->next; */
+      /*   } */
+      /* while(b); */
+      /* b = orig; */
     }
   else return_value = 0;
-
+  
   Free(sorted_b);
 
   return return_value;
@@ -449,83 +489,90 @@ int Make_Best_Swap(t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 int Mov_Backward_Topo_Bl(t_tree *tree, phydbl lk_old, t_edge **tested_b, int n_tested)
 {
-  phydbl **l_init;
-  int i,j,step,beg,end;
+  scalar_dbl **l_init,**v_init;
+  int i,step,beg,end;
   t_edge *b,*orig;
 
-  l_init = (phydbl **)mCalloc(2*tree->n_otu-3,sizeof(phydbl *));
+  l_init = (scalar_dbl **)mCalloc(2*tree->n_otu-3,sizeof(scalar_dbl *));
+  v_init = (scalar_dbl **)mCalloc(2*tree->n_otu-3,sizeof(scalar_dbl *));
 
-  For(i,2*tree->n_otu-3) l_init[i] = MIXT_Get_Lengths_Of_This_Edge(tree->a_edges[i],tree);
+  For(i,2*tree->n_otu-3) 
+    {
+      l_init[i] = Duplicate_Scalar_Dbl(tree->a_edges[i]->l);
+      v_init[i] = Duplicate_Scalar_Dbl(tree->a_edges[i]->l_var);
+      /* l_init[i] = MIXT_Get_Lengths_Of_This_Edge(tree->a_edges[i],tree); */
+    }
 
   step = 2;
   do
     {
       For(i,2*tree->n_otu-3)
-    {
-      b = tree->a_edges[i];
-
-      /* b->l->v = b->l_old->v + (1./step) * (l_init[i] - b->l_old->v); */
-
-      j = 0;
-      orig = b;
-      do
         {
-          b->l->v = b->l_old->v + (1./step) * (l_init[i][j] - b->l_old->v);
-          if(b->next) b = b->next;
-          else         b = b->next;
-          j++;
+          b = tree->a_edges[i];
+          
+          /* b->l->v = b->l_old->v + (1./step) * (l_init[i] - b->l_old->v); */
+          
+          orig = b;
+          do
+            {
+              b->l->v = b->l_old->v + (1./step) * (l_init[i]->v - b->l_old->v);
+              b = b->next;
+              l_init[i] = l_init[i]->next;
+            }
+          while(b);
+          b = orig;
         }
-      while(b);
-      b = orig;
-    }
-
+      
       beg = (int)FLOOR((phydbl)n_tested/(step-1));
       end = 0;
       Unswap_N_Branch(tree,tested_b,beg,end);
       beg = 0;
       end = (int)FLOOR((phydbl)n_tested/step);
       Swap_N_Branch(tree,tested_b,beg,end);
-
+      
       if(!end) tree->n_swap = 0;
-
+      
       Set_Both_Sides(NO,tree);
       Lk(NULL,tree);
-
+      
       step++;
-
+      
     }while((tree->c_lnL < lk_old) && (step < 1000));
-
-
+  
+  
   if(step == 1000)
     {
       if(tree->n_swap)  Exit("\n== Err. in Mov_Backward_Topo_Bl (n_swap > 0)\n");
+      
+      Restore_Br_Len(tree);
 
-      For(i,2*tree->n_otu-3)
-    {
-      b = tree->a_edges[i];
-
-      orig = b;
-      do
-        {
-          b->l->v = b->l_old->v;
-          if(b->next) b = b->next;
-          else         b = b->next;
-        }
-      while(b);
-      b = orig;
-    }
-
-
+      /* For(i,2*tree->n_otu-3) */
+      /*   { */
+      /*     b = tree->a_edges[i]; */
+          
+      /*     orig = b; */
+      /*     do */
+      /*       { */
+      /*         b->l->v = b->l_old->v; */
+      /*         b = b->next; */
+      /*       } */
+      /*     while(b); */
+      /*     b = orig; */
+      /*   } */
+      
+      
       Set_Both_Sides(NO,tree);
       Lk(NULL,tree);
     }
 
-  For(i,2*tree->n_otu-3) Free(l_init[i]);
+  For(i,2*tree->n_otu-3) Free_Scalar_Dbl(l_init[i]);
   Free(l_init);
 
+  For(i,2*tree->n_otu-3) Free_Scalar_Dbl(v_init[i]);
+  Free(v_init);
+
   tree->n_swap = 0;
   For(i,2*tree->n_otu-3)
     {
@@ -536,14 +583,13 @@ int Mov_Backward_Topo_Bl(t_tree *tree, phydbl lk_old, t_edge **tested_b, int n_t
 
   if(tree->c_lnL > lk_old)                                return  1;
   else if((tree->c_lnL > lk_old-tree->mod->s_opt->min_diff_lk_local) &&
-      (tree->c_lnL < lk_old+tree->mod->s_opt->min_diff_lk_local)) return -1;
+          (tree->c_lnL < lk_old+tree->mod->s_opt->min_diff_lk_local)) return -1;
   else                                                    return  0;
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 int Mov_Backward_Topo_Pars(t_tree *tree, int pars_old, t_edge **tested_b, int n_tested)
 {
   int i,step,beg,end;
@@ -596,193 +642,220 @@ int Mov_Backward_Topo_Pars(t_tree *tree, int pars_old, t_edge **tested_b, int n_
 void Unswap_N_Branch(t_tree *tree, t_edge **b, int beg, int end)
 {
   int i;
-  int dim;
-  t_edge *orig;
-
-  dim = 2*tree->n_otu-2;
+  /* t_edge *orig; */
+  t_node *n1,*n2,*n3,*n4;
 
+  n1 = n2 = n3 = n4 = NULL;
+          
   if(end>beg)
     {
       for(i=beg;i<end;i++)
-    {
-
-/* 	  PhyML_Printf("MOV BACK UNSWAP Edge %d Swap nodes %d(%d) %d %d %d(%d)\n", */
-/* 		 b[i]->num, */
-/* 		 b[i]->nni->swap_node_v2->v[tree->t_dir[b[i]->nni->swap_node_v2->num][b[i]->nni->swap_node_v1->num]]->num, */
-/* 		 b[i]->nni->swap_node_v4->num, */
-/* 		 b[i]->nni->swap_node_v2->num, */
-/* 		 b[i]->nni->swap_node_v3->num, */
-/* 		 b[i]->nni->swap_node_v3->v[tree->t_dir[b[i]->nni->swap_node_v3->num][b[i]->nni->swap_node_v4->num]]->num, */
-/* 		 b[i]->nni->swap_node_v1->num */
-/* 		 ); */
-
-      Swap(b[i]->nni->swap_node_v2->v[tree->t_dir[b[i]->nni->swap_node_v2->num*dim+b[i]->nni->swap_node_v1->num]],
-           b[i]->nni->swap_node_v2,
-           b[i]->nni->swap_node_v3,
-           b[i]->nni->swap_node_v3->v[tree->t_dir[b[i]->nni->swap_node_v3->num*dim+b[i]->nni->swap_node_v4->num]],
-           tree);
-
-      if(!Check_Topo_Constraints(tree,tree->io->cstr_tree))
         {
-          /* Undo this swap as it violates one of the topological constraints
-         defined in the input constraint tree
-          */
-          Swap(b[i]->nni->swap_node_v2->v[tree->t_dir[b[i]->nni->swap_node_v2->num*dim+b[i]->nni->swap_node_v1->num]],
-           b[i]->nni->swap_node_v2,
-           b[i]->nni->swap_node_v3,
-           b[i]->nni->swap_node_v3->v[tree->t_dir[b[i]->nni->swap_node_v3->num*dim+b[i]->nni->swap_node_v4->num]],
-           tree);
-        }
-
-
-/* 	  (b[i]->nni->best_conf == 1)? */
-/* 	    (Swap(b[i]->left->v[b[i]->l_v2],b[i]->left,b[i]->rght,b[i]->rght->v[b[i]->r_v1],tree)): */
-/* 	    (Swap(b[i]->left->v[b[i]->l_v2],b[i]->left,b[i]->rght,b[i]->rght->v[b[i]->r_v2],tree)); */
-
-      /* b[i]->l->v = b[i]->l_old->v; */
-
-
-      orig = b[i];
-      do
-        {
-          b[i]->l->v = b[i]->l_old->v;
-          if(b[i]->next) b[i] = b[i]->next;
-          else            b[i] = b[i]->next;
+          n1 = n2 = n3 = n4 = NULL;
+          
+          if(b[i]->nni->best_conf == 1)
+            {
+              n1 = b[i]->left->v[b[i]->l_v2];
+              n2 = b[i]->left;
+              n3 = b[i]->rght;
+              n4 = b[i]->rght->v[b[i]->r_v1];
+            }
+          else if(b[i]->nni->best_conf == 2)
+            {
+              n1 = b[i]->left->v[b[i]->l_v2];
+              n2 = b[i]->left;
+              n3 = b[i]->rght;
+              n4 = b[i]->rght->v[b[i]->r_v2];
+            }
+
+          Swap(n1,n2,n3,n4,tree);
+          
+          if(!Check_Topo_Constraints(tree,tree->io->cstr_tree))
+            {
+              /* Undo this swap as it violates one of the topological constraints
+                 defined in the input constraint tree
+              */
+              Swap(n4,n2,n3,n1,tree);
+            }
+          
+          
+          /* 	  (b[i]->nni->best_conf == 1)? */
+          /* 	    (Swap(b[i]->left->v[b[i]->l_v2],b[i]->left,b[i]->rght,b[i]->rght->v[b[i]->r_v1],tree)): */
+          /* 	    (Swap(b[i]->left->v[b[i]->l_v2],b[i]->left,b[i]->rght,b[i]->rght->v[b[i]->r_v2],tree)); */
+          
+          /* b[i]->l->v = b[i]->l_old->v; */
+          
+          Copy_Scalar_Dbl(b[i]->l_old,b[i]->l);
+          Copy_Scalar_Dbl(b[i]->l_var_old,b[i]->l_var);
+          
+          /* orig = b[i]; */
+          /* do */
+          /*   { */
+          /*     b[i]->l->v = b[i]->l_old->v; */
+          /*     b[i] = b[i]->next; */
+          /*   } */
+          /* while(b[i]); */
+          /* b[i] = orig; */
         }
-      while(b[i]);
-      b[i] = orig;
-
-    }
     }
   else
     {
       for(i=beg-1;i>=end;i--)
-    {
-      Swap(b[i]->nni->swap_node_v2->v[tree->t_dir[b[i]->nni->swap_node_v2->num*dim+b[i]->nni->swap_node_v1->num]],
-           b[i]->nni->swap_node_v2,
-           b[i]->nni->swap_node_v3,
-           b[i]->nni->swap_node_v3->v[tree->t_dir[b[i]->nni->swap_node_v3->num*dim+b[i]->nni->swap_node_v4->num]],
-           tree);
-
-      if(!Check_Topo_Constraints(tree,tree->io->cstr_tree))
         {
-          /* Undo this swap as it violates one of the topological constraints
-         defined in the input constraint tree
-          */
-          Swap(b[i]->nni->swap_node_v2->v[tree->t_dir[b[i]->nni->swap_node_v2->num*dim+b[i]->nni->swap_node_v1->num]],
-           b[i]->nni->swap_node_v2,
-           b[i]->nni->swap_node_v3,
-           b[i]->nni->swap_node_v3->v[tree->t_dir[b[i]->nni->swap_node_v3->num*dim+b[i]->nni->swap_node_v4->num]],
-           tree);
-        }
-
-
-      /* b[i]->l->v = b[i]->l_old->v; */
-
-      orig = b[i];
-      do
-        {
-          b[i]->l->v = b[i]->l_old->v;
-          if(b[i]->next) b[i] = b[i]->next;
-          else            b[i] = b[i]->next;
+          n1 = n2 = n3 = n4 = NULL;
+          
+          if(b[i]->nni->best_conf == 1)
+            {
+              n1 = b[i]->left->v[b[i]->l_v2];
+              n2 = b[i]->left;
+              n3 = b[i]->rght;
+              n4 = b[i]->rght->v[b[i]->r_v1];
+            }
+          else if(b[i]->nni->best_conf == 2)
+            {
+              n1 = b[i]->left->v[b[i]->l_v2];
+              n2 = b[i]->left;
+              n3 = b[i]->rght;
+              n4 = b[i]->rght->v[b[i]->r_v2];
+            }
+
+          Swap(n1,n2,n3,n4,tree);
+          
+          if(!Check_Topo_Constraints(tree,tree->io->cstr_tree))
+            {
+              /* Undo this swap as it violates one of the topological constraints
+                 defined in the input constraint tree
+              */
+              Swap(n4,n2,n3,n1,tree);
+            }
+          
+          
+          /* b[i]->l->v = b[i]->l_old->v; */
+          Copy_Scalar_Dbl(b[i]->l_old,b[i]->l);
+          Copy_Scalar_Dbl(b[i]->l_var_old,b[i]->l_var);
+          
+          /* orig = b[i]; */
+          /* do */
+          /*   { */
+          /*     b[i]->l->v = b[i]->l_old->v; */
+          /*     b[i] = b[i]->next; */
+          /*   } */
+          /* while(b[i]); */
+          /* b[i] = orig; */
+          
         }
-      while(b[i]);
-      b[i] = orig;
-
-    }
     }
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Swap_N_Branch(t_tree *tree,t_edge **b, int beg, int end)
 {
   int i;
-  int dim;
-  t_edge *orig;
+  /* t_edge *orig; */
+  t_node *n1,*n2,*n3,*n4;
 
-  dim = 2*tree->n_otu-2;
+  n1 = n2 = n3 = n4 = NULL;
 
   if(end>beg)
     {
       for(i=beg;i<end;i++)
-    {
-      Swap(b[i]->nni->swap_node_v2->v[tree->t_dir[b[i]->nni->swap_node_v2->num*dim+b[i]->nni->swap_node_v1->num]],
-           b[i]->nni->swap_node_v2,
-           b[i]->nni->swap_node_v3,
-           b[i]->nni->swap_node_v3->v[tree->t_dir[b[i]->nni->swap_node_v3->num*dim+b[i]->nni->swap_node_v4->num]],
-           tree);
-
-      if(!Check_Topo_Constraints(tree,tree->io->cstr_tree))
-        {
-          /* Undo this swap as it violates one of the topological constraints
-         defined in the input constraint tree
-          */
-          Swap(b[i]->nni->swap_node_v2->v[tree->t_dir[b[i]->nni->swap_node_v2->num*dim+b[i]->nni->swap_node_v1->num]],
-           b[i]->nni->swap_node_v2,
-           b[i]->nni->swap_node_v3,
-           b[i]->nni->swap_node_v3->v[tree->t_dir[b[i]->nni->swap_node_v3->num*dim+b[i]->nni->swap_node_v4->num]],
-           tree);
-        }
-
-      /* b[i]->l->v = b[i]->nni->best_l; */
-
-      orig = b[i];
-      do
         {
-          b[i]->l->v = b[i]->nni->best_l;
-          if(b[i]->next) b[i] = b[i]->next;
-          else            b[i] = b[i]->next;
+          n1 = n2 = n3 = n4 = NULL;
+          
+          if(b[i]->nni->best_conf == 1)
+            {
+              n1 = b[i]->left->v[b[i]->l_v2];
+              n2 = b[i]->left;
+              n3 = b[i]->rght;
+              n4 = b[i]->rght->v[b[i]->r_v1];
+            }
+          else if(b[i]->nni->best_conf == 2)
+            {
+              n1 = b[i]->left->v[b[i]->l_v2];
+              n2 = b[i]->left;
+              n3 = b[i]->rght;
+              n4 = b[i]->rght->v[b[i]->r_v2];
+            }
+          
+          Swap(n1,n2,n3,n4,tree);
+          
+          if(!Check_Topo_Constraints(tree,tree->io->cstr_tree))
+            {
+              /* Undo this swap as it violates one of the topological constraints
+                 defined in the input constraint tree
+              */
+              Swap(n4,n2,n3,n1,tree);
+            }
+          
+          /* b[i]->l->v = b[i]->nni->best_l; */
+
+          Copy_Scalar_Dbl(b[i]->nni->best_l,b[i]->l);
+          Copy_Scalar_Dbl(b[i]->nni->best_v,b[i]->l_var);
+
+          /* orig = b[i]; */
+          /* do */
+          /*   { */
+          /*     b[i]->l->v = b[i]->nni->best_l; */
+          /*     b[i] = b[i]->next; */
+          /*   } */
+          /* while(b[i]); */
+          /* b[i] = orig; */
         }
-      while(b[i]);
-      b[i] = orig;
-
-    }
     }
   else
     {
       for(i=beg-1;i>=end;i--)
-    {
-      Swap(b[i]->nni->swap_node_v2->v[tree->t_dir[b[i]->nni->swap_node_v2->num*dim+b[i]->nni->swap_node_v1->num]],
-           b[i]->nni->swap_node_v2,
-           b[i]->nni->swap_node_v3,
-           b[i]->nni->swap_node_v3->v[tree->t_dir[b[i]->nni->swap_node_v3->num*dim+b[i]->nni->swap_node_v4->num]],
-           tree);
-
-      if(!Check_Topo_Constraints(tree,tree->io->cstr_tree))
         {
-          /* Undo this swap as it violates one of the topological constraints
-         defined in the input constraint tree
-          */
-          Swap(b[i]->nni->swap_node_v2->v[tree->t_dir[b[i]->nni->swap_node_v2->num*dim+b[i]->nni->swap_node_v1->num]],
-           b[i]->nni->swap_node_v2,
-           b[i]->nni->swap_node_v3,
-           b[i]->nni->swap_node_v3->v[tree->t_dir[b[i]->nni->swap_node_v3->num*dim+b[i]->nni->swap_node_v4->num]],
-           tree);
-        }
-
-      /* b[i]->l->v = b[i]->nni->best_l; */
 
-      orig = b[i];
-      do
-        {
-          b[i]->l->v = b[i]->nni->best_l;
-          if(b[i]->next) b[i] = b[i]->next;
-          else            b[i] = b[i]->next;
+          n1 = n2 = n3 = n4 = NULL;
+          
+          if(b[i]->nni->best_conf == 1)
+            {
+              n1 = b[i]->left->v[b[i]->l_v2];
+              n2 = b[i]->left;
+              n3 = b[i]->rght;
+              n4 = b[i]->rght->v[b[i]->r_v1];
+            }
+          else if(b[i]->nni->best_conf == 2)
+            {
+              n1 = b[i]->left->v[b[i]->l_v2];
+              n2 = b[i]->left;
+              n3 = b[i]->rght;
+              n4 = b[i]->rght->v[b[i]->r_v2];
+            }
+          
+          Swap(n1,n2,n3,n4,tree);
+          
+          if(!Check_Topo_Constraints(tree,tree->io->cstr_tree))
+            {
+              /* Undo this swap as it violates one of the topological constraints
+                 defined in the input constraint tree
+              */
+              Swap(n4,n2,n3,n1,tree);
+            }
+          
+          /* b[i]->l->v = b[i]->nni->best_l; */
+          
+          Copy_Scalar_Dbl(b[i]->nni->best_l,b[i]->l);
+          Copy_Scalar_Dbl(b[i]->nni->best_v,b[i]->l_var);
+
+          /* orig = b[i]; */
+          /* do */
+          /*   { */
+          /*     b[i]->l->v = b[i]->nni->best_l; */
+          /*     b[i] = b[i]->next; */
+          /*   } */
+          /* while(b[i]); */
+          /* b[i] = orig; */
         }
-      while(b[i]);
-      b[i] = orig;
-
-    }
     }
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Check_NNI_Scores_Around(t_node *a, t_node *d, t_edge *b, phydbl *best_score, t_tree *tree)
 {
 
@@ -790,19 +863,19 @@ void Check_NNI_Scores_Around(t_node *a, t_node *d, t_edge *b, phydbl *best_score
   For(i,3)
     {
       if((d->v[i] != a) && (!d->v[i]->tax))
-    {
-      if((d->b[i]->nni->score > *best_score-1.E-10) &&
-         (d->b[i]->nni->score < *best_score+1.E-10)) /* ties */
-         {
-           d->b[i]->nni->score = *best_score+1.;
-         }
-
-      if(d->b[i]->nni->score < *best_score)
         {
-          *best_score = d->b[i]->nni->score;
+          if((d->b[i]->nni->score > *best_score-1.E-10) &&
+             (d->b[i]->nni->score < *best_score+1.E-10)) /* ties */
+            {
+              d->b[i]->nni->score = *best_score+1.;
+            }
+
+          if(d->b[i]->nni->score < *best_score)
+            {
+              *best_score = d->b[i]->nni->score;
+            }
         }
     }
-    }
 }
 
 //////////////////////////////////////////////////////////////
diff --git a/src/spr.c b/src/spr.c
index f3771ca..25c5bc9 100644
--- a/src/spr.c
+++ b/src/spr.c
@@ -3085,17 +3085,17 @@ void PostOrder_w (t_tree *tree, t_node *v, t_edge *v_e, t_node *w, t_edge *e)
 
 /*********************************************************/
 /*********************************************************/
-/* Sort list of SPR move by putting the deepest moves first */
+/* Sort list of SPR move by putting the shallowest moves first */
 void Sort_Spr_List_Depth(t_tree *tree)
 {
   int i,j;
   t_spr *buff;
 
-  For(i,tree->size_spr_list-1)
+  For(i,tree->n_moves-1)
     {
-      for(j=i+1;j<tree->size_spr_list;j++)
+      for(j=i+1;j<tree->n_moves;j++)
         {
-          if(tree->spr_list[j]->depth_path > tree->spr_list[i]->depth_path)
+          if(tree->spr_list[j]->depth_path < tree->spr_list[i]->depth_path)
             {
               buff              = tree->spr_list[i];
               tree->spr_list[i] = tree->spr_list[j];
@@ -3128,20 +3128,41 @@ void Sort_Spr_List_LnL(t_tree *tree)
 }
 
 
+/*********************************************************/
+/*********************************************************/
+/* Sort list of SPR move by putting the more parsimonious moves first */
+void Sort_Spr_List_Pars(t_tree *tree)
+{
+  int i,j;
+  t_spr *buff;
+
+  For(i,tree->size_spr_list-1)
+    {
+      for(j=i+1;j<tree->size_spr_list;j++)
+        {
+          if(tree->spr_list[j]->pars < tree->spr_list[i]->pars)
+            {
+              buff              = tree->spr_list[i];
+              tree->spr_list[i] = tree->spr_list[j];
+              tree->spr_list[j] = buff;
+            }
+        }
+    }
+}
+
 
 /*********************************************************/
 /*********************************************************/
 /*********************************************************/
-/* Below are my functions for SPR search (Stephane Guindon, 2007) */
 
 void Randomize_Spr_List(t_tree *tree)
 {
   int i,j;
   t_spr *buff;
 
-  For(i,tree->size_spr_list)
+  For(i,tree->n_moves)
     {
-      j = (int)FLOOR(rand()/(RAND_MAX+1.)*tree->size_spr_list);
+      j = Rand_Int(0,tree->n_moves-1);
       buff              = tree->spr_list[i];
       tree->spr_list[i] = tree->spr_list[j];
       tree->spr_list[j] = buff;
@@ -3150,41 +3171,34 @@ void Randomize_Spr_List(t_tree *tree)
 
 /*********************************************************/
 
-int Spr(phydbl init_lnL, t_tree *tree)
+int Spr(phydbl init_lnL, phydbl prop_spr, t_tree *tree)
 {
-  int br;
-  int pars_diff, max_pars_diff, new_pars, old_pars;
+  int i,br;
+  int *br_idx;
   t_edge *b;
 
   Set_Both_Sides(YES,tree);
-  pars_diff        = -1;
-  max_pars_diff    = -1;
-  new_pars         = -1;
-  old_pars         = -1;
 
   Reset_Spr_List(tree);
 
-  For(br,2*tree->n_otu-3)
-    {
-      b = tree->a_edges[br];
+  br_idx = Permutate(2*tree->n_otu-3);
 
-      old_pars = tree->c_pars;
-      Spr_Subtree(b,b->left,tree);
-      new_pars = tree->c_pars;
+  /* For(i,2*tree->n_otu-3) */
+  For(i,MAX(1,(int)((2*tree->n_otu-3)*prop_spr)))
+    {
+      br = br_idx[i];
 
-      pars_diff =  new_pars - old_pars;
-      if(pars_diff > max_pars_diff) max_pars_diff = pars_diff;
+      if(!(br%10)) if(tree->io->print_json_trace == YES) JSON_Tree_Io(tree,tree->io->fp_out_json_trace); 
 
-      old_pars = tree->c_pars;
+      b = tree->a_edges[br];
+      Spr_Subtree(b,b->left,tree);
       Spr_Subtree(b,b->rght,tree);
-      new_pars = tree->c_pars;
-
-      pars_diff = new_pars - old_pars;
-      if(pars_diff > max_pars_diff) max_pars_diff = pars_diff;
     }
 
 /*   tree->mod->s_opt->pars_thresh = MAX(5,max_pars_diff); */
 
+  Free(br_idx);
+
   return 1;
 }
 
@@ -3193,13 +3207,12 @@ int Spr(phydbl init_lnL, t_tree *tree)
 void Spr_Subtree(t_edge *b, t_node *link, t_tree *tree)
 {
   int i;
-  int n_moves_pars, n_moves, curr_pars, min_pars, best_move;
+  int n_moves_pars, n_moves, min_pars, best_move_idx;
   t_spr *best_pars_move;
   t_edge *target, *residual;
-
-  best_move     = -1;
+  
+  best_move_idx = -1;
   tree->n_moves = 0;
-  curr_pars     = tree->c_pars;
 
   MIXT_Set_Pars_Thresh(tree);
 
@@ -3210,37 +3223,19 @@ void Spr_Subtree(t_edge *b, t_node *link, t_tree *tree)
     }
   else
     {
-      /* printf("\n. -1"); fflush(NULL); */
-      /* if(!Check_Lk_At_Given_Edge(NO,tree)) Exit("\n"); */
-
       if(!link->tax) Test_All_Spr_Targets(b,link,tree);
 
-      /* printf("\n. 0"); fflush(NULL); */
-      /* if(!Check_Lk_At_Given_Edge(NO,tree)) Exit("\n"); */
-
       if(tree->n_moves)
         {
-          n_moves_pars = 0;
-          n_moves      = 0;
-
-          For(i,tree->n_moves)
-            if(curr_pars - tree->spr_list[i]->pars >= -tree->mod->s_opt->pars_thresh)
-              n_moves_pars++;
-
-          For(i,tree->n_moves)
-            {
-              n_moves++;
-              /* if(n_moves > 15) break; */
-              if(n_moves > 5) break;
-              if(tree->spr_list[i]->lnL < tree->best_lnL - 2. * tree->mod->s_opt->max_delta_lnL_spr) break;
-            }
-
-          if(!tree->mod->s_opt->spr_lnL) n_moves = n_moves_pars;
+          /* n_moves_pars = MAX(5,(int)(0.1*tree->n_moves)); */
+          /* n_moves      = MAX(5,(int)(0.1*tree->n_moves)); */
+          n_moves_pars = MIN(5,tree->n_moves);
+          n_moves      = MIN(5,tree->n_moves);
 
-          if(!tree->io->fp_in_constraint_tree) n_moves = MAX(1,n_moves);
-          n_moves = MIN(n_moves,2*tree->n_otu-3);
-
-          if(tree->mod->s_opt->spr_pars)
+          if(tree->mod->s_opt->spr_lnL == NO)       n_moves = n_moves_pars;
+          if(tree->io->fp_in_constraint_tree == NO) n_moves = MAX(1,n_moves);
+          
+          if(tree->mod->s_opt->spr_pars == YES)
             {
               if(tree->io->fp_in_constraint_tree)
                 {
@@ -3251,7 +3246,6 @@ void Spr_Subtree(t_edge *b, t_node *link, t_tree *tree)
               min_pars = 1E+8;
               best_pars_move = NULL;
 
-
               For(i,n_moves)
                 if(tree->spr_list[i]->pars < min_pars)
                   {
@@ -3282,50 +3276,57 @@ void Spr_Subtree(t_edge *b, t_node *link, t_tree *tree)
               int apply_move = NO;
               phydbl accept_prob,u;
 
-              /* tree->both_sides = YES; */
-              /* Lk(NULL,tree); */
-              /* tree->both_sides = NO; */
-
-              /* printf("\n. 1"); fflush(NULL); */
-              /* if(!Check_Lk_At_Given_Edge(YES,tree)) Exit("\n"); */
-
-              /* Sort_Spr_List_Depth(tree); */
-              Sort_Spr_List_LnL(tree);
-
-              best_move = Evaluate_List_Of_Regraft_Pos_Triple(tree->spr_list,n_moves,tree);
+              if(tree->mod->s_opt->spr_lnL == YES) 
+                {
+                  Sort_Spr_List_LnL(tree);
+                  if(tree->spr_list[0]->lnL > tree->best_lnL)
+                    {
+                      /* n_moves = 1; */
+                      /* best_move_idx = Evaluate_List_Of_Regraft_Pos_Triple(tree->spr_list,n_moves,tree); */
+                      best_move_idx = 0;
+                    }
+                  else
+                    {
+                      best_move_idx = Evaluate_List_Of_Regraft_Pos_Triple(tree->spr_list,n_moves,tree);
+                    }
+                }
+              else
+                {
+                  best_move_idx = Evaluate_List_Of_Regraft_Pos_Triple(tree->spr_list,n_moves,tree);
+                }
 
-              /* printf("\n. 2"); fflush(NULL); */
-              /* if(!Check_Lk_At_Given_Edge(YES,tree)) Exit("\n"); */
+              /* For(i,n_moves) printf("\n. %d %f %d",i,tree->spr_list[i]->lnL,tree->spr_list[i]->pars); */
+              /* fflush(NULL); */
 
-              if(best_move > -1)
+              if(best_move_idx > -1)
                 {
-                  accept_prob = exp((tree->spr_list[best_move]->lnL - tree->best_lnL)/tree->annealing_temp);
-                  u = Uni();
-                  if(!(u > accept_prob)) apply_move = YES;
+                  if(Are_Equal(tree->annealing_temp,0.0,1.E-3) == NO)
+                    {
+                      accept_prob = exp((tree->spr_list[best_move_idx]->lnL - tree->best_lnL)/tree->annealing_temp);
+                      u = Uni();
+                      if(!(u > accept_prob)) apply_move = YES;
+                    }
+                  else
+                    {
+                      if(tree->spr_list[best_move_idx]->lnL > tree->best_lnL + tree->mod->s_opt->min_diff_lk_move)
+                        apply_move = YES;
+                    }
                 }
                 
-              /* if((best_move > -1) && (tree->spr_list[best_move]->lnL > tree->best_lnL + tree->mod->s_opt->min_diff_lk_move)) */
-              if((best_move > -1) && (apply_move == YES))
+              if((best_move_idx > -1) && (apply_move == YES))
                 {
-                  Try_One_Spr_Move_Triple(tree->spr_list[best_move],tree);
+                  Try_One_Spr_Move_Triple(tree->spr_list[best_move_idx],tree);
                 }
               else
                 {
                   Pars(NULL,tree);
-                  /* tree->both_sides = YES; */
-                  /* Lk(tree); */
-                  /* tree->both_sides = NO; */
                 }
-
-              /* printf("\n. 3"); fflush(NULL); */
-              /* if(!Check_Lk_At_Given_Edge(tree)) Exit("\n"); */
             }
         }
       Reset_Spr_List(tree);
     }
 }
 
-
 /*********************************************************/
 
 int Test_All_Spr_Targets(t_edge *b_pulled, t_node *n_link, t_tree *tree)
@@ -3333,7 +3334,8 @@ int Test_All_Spr_Targets(t_edge *b_pulled, t_node *n_link, t_tree *tree)
   t_node *n_opp_to_link,*n_v1,*n_v2;
   t_edge *b_target,*b_residual;
   int i,dir1,dir2;
-  phydbl *init_len_v1, *init_len_v2, *init_len_pulled;
+  scalar_dbl *init_l_v1, *init_l_v2, *init_l_pulled;
+  scalar_dbl *init_v_v1, *init_v_v2, *init_v_pulled;
   int best_found;
   phydbl init_lnL;
 
@@ -3347,7 +3349,8 @@ int Test_All_Spr_Targets(t_edge *b_pulled, t_node *n_link, t_tree *tree)
   b_target = b_residual = NULL;
   n_opp_to_link  = (n_link == b_pulled->rght)?(b_pulled->left):(b_pulled->rght);
 
-  init_len_pulled = MIXT_Get_Lengths_Of_This_Edge(b_pulled,tree);
+  init_l_pulled = Duplicate_Scalar_Dbl(b_pulled->l);
+  init_v_pulled = Duplicate_Scalar_Dbl(b_pulled->l_var);
 
   dir1 = dir2 = -1;
   For(i,3)
@@ -3359,83 +3362,86 @@ int Test_All_Spr_Targets(t_edge *b_pulled, t_node *n_link, t_tree *tree)
 
   if(n_link->v[dir1]->num < n_link->v[dir2]->num)
     {
-      n_v1        = n_link->v[dir1];
-      n_v2        = n_link->v[dir2];
-      init_len_v1 = MIXT_Get_Lengths_Of_This_Edge(n_link->b[dir1],tree);
-      init_len_v2 = MIXT_Get_Lengths_Of_This_Edge(n_link->b[dir2],tree);
+      n_v1      = n_link->v[dir1];
+      n_v2      = n_link->v[dir2];
+      init_l_v1 = Duplicate_Scalar_Dbl(n_link->b[dir1]->l);
+      init_l_v2 = Duplicate_Scalar_Dbl(n_link->b[dir2]->l);
+      init_v_v1 = Duplicate_Scalar_Dbl(n_link->b[dir1]->l_var);
+      init_v_v2 = Duplicate_Scalar_Dbl(n_link->b[dir2]->l_var);
     }
   else
     {
-      n_v1        = n_link->v[dir2];
-      n_v2        = n_link->v[dir1];
-      init_len_v1 = MIXT_Get_Lengths_Of_This_Edge(n_link->b[dir2],tree);
-      init_len_v2 = MIXT_Get_Lengths_Of_This_Edge(n_link->b[dir1],tree);
+      n_v1      = n_link->v[dir2];
+      n_v2      = n_link->v[dir1];
+      init_l_v1 = Duplicate_Scalar_Dbl(n_link->b[dir2]->l);
+      init_l_v2 = Duplicate_Scalar_Dbl(n_link->b[dir1]->l);
+      init_v_v1 = Duplicate_Scalar_Dbl(n_link->b[dir2]->l_var);
+      init_v_v2 = Duplicate_Scalar_Dbl(n_link->b[dir1]->l_var);
     }
 
   if(!(n_v1->tax && n_v2->tax)) /*! Pruning is meaningless otherwise */
     {
-
       Prune_Subtree(n_link,n_opp_to_link,&b_target,&b_residual,tree);
 
       if(tree->mod->s_opt->spr_lnL)
         {
-          Fast_Br_Len(b_target,tree,NO);
-          /* Update_PMat_At_Given_Edge(b_target,tree); */
+          /* Fast_Br_Len(b_target,tree,YES); */
+          Update_PMat_At_Given_Edge(b_target,tree);
         }
 
-      best_found = 0;
+      best_found = NO;
       tree->depth_curr_path = 0;
       tree->curr_path[0] = b_target->left;
       Test_One_Spr_Target_Recur(b_target->rght,
-                b_target->left,
-                b_pulled,n_link,b_residual,&best_found,tree);
-
-
-      tree->depth_curr_path = 0;
-      tree->curr_path[0] = b_target->rght;
-      Test_One_Spr_Target_Recur(b_target->left,
-                b_target->rght,
-                b_pulled,n_link,b_residual,&best_found,tree);
-
+                                b_target->left,
+                                b_pulled,n_link,b_residual,b_target,&best_found,tree);
+      
+      if(best_found == NO || tree->mod->s_opt->spr_lnL == NO)
+        {
+          tree->depth_curr_path = 0;
+          tree->curr_path[0] = b_target->rght;
+          Test_One_Spr_Target_Recur(b_target->left,
+                                    b_target->rght,
+                                    b_pulled,n_link,b_residual,b_target,&best_found,tree);
+        }
 
       Graft_Subtree(b_target,n_link,b_residual,tree);
 
+      if((n_link->v[dir1] != n_v1) || (n_link->v[dir2] != n_v2)) PhyML_Printf("\n== Warning: -- SWITCH NEEDED -- ! \n");
 
-      if((n_link->v[dir1] != n_v1) || (n_link->v[dir2] != n_v2))
-        PhyML_Printf("\n. Warning: -- SWITCH NEEDED -- ! \n");
+      Copy_Scalar_Dbl(init_l_v1,n_link->b[dir1]->l);
+      Copy_Scalar_Dbl(init_v_v1,n_link->b[dir1]->l_var);
 
-      /* n_link->b[dir1]->l->v = init_len_v1; */
-      /* n_link->b[dir2]->l->v = init_len_v2;  */
-      /* b_pulled->l->v = init_len_pulled; */
+      Copy_Scalar_Dbl(init_l_v2,n_link->b[dir2]->l);
+      Copy_Scalar_Dbl(init_v_v2,n_link->b[dir2]->l_var);
 
-      MIXT_Set_Lengths_Of_This_Edge(init_len_v1,n_link->b[dir1],tree);
-      MIXT_Set_Lengths_Of_This_Edge(init_len_v2,n_link->b[dir2],tree);
-      MIXT_Set_Lengths_Of_This_Edge(init_len_pulled,b_pulled,tree);
+      Copy_Scalar_Dbl(init_l_pulled,b_pulled->l);
+      Copy_Scalar_Dbl(init_v_pulled,b_pulled->l_var);
 
+      // really useful if spr_lnL == No ?
       Update_PMat_At_Given_Edge(n_link->b[dir1],tree);
       Update_PMat_At_Given_Edge(n_link->b[dir2],tree);
       Update_PMat_At_Given_Edge(b_pulled,tree);
 
-      /* if(tree->mod->s_opt->spr_lnL) */
-      /* 	{ */
-      /* I don't understand why this is required when spr_lnL = NO, but it is... */
-      MIXT_Set_Alias_Subpatt(YES,tree);
-      Update_P_Lk(tree,b_pulled,  n_link);
-      Update_P_Lk(tree,b_target,  n_link);
-      Update_P_Lk(tree,b_residual,n_link);
-      MIXT_Set_Alias_Subpatt(NO,tree);
-      /* 	} */
-      /* else */
-      /* 	{ */
-      Update_P_Pars(tree,b_pulled,  n_link);
-      Update_P_Pars(tree,b_target,  n_link);
-      Update_P_Pars(tree,b_residual,n_link);
-    /* } */
+      if(tree->mod->s_opt->spr_lnL == YES)
+      	{
+          MIXT_Set_Alias_Subpatt(YES,tree);
+          Update_P_Lk(tree,b_pulled,  n_link);
+          Update_P_Lk(tree,b_target,  n_link);
+          Update_P_Lk(tree,b_residual,n_link);
+          MIXT_Set_Alias_Subpatt(NO,tree);
+        }
+      else
+      	{
+          Update_P_Pars(tree,b_pulled,  n_link);
+          Update_P_Pars(tree,b_target,  n_link);
+          Update_P_Pars(tree,b_residual,n_link);
+        }
 
       For(i,3)
         if(n_link->v[i] != n_opp_to_link)
           {
-            if(tree->mod->s_opt->spr_lnL)
+            if(tree->mod->s_opt->spr_lnL == YES)
               {
                 MIXT_Set_Alias_Subpatt(YES,tree);
                 Pre_Order_Lk(n_link,n_link->v[i],tree);
@@ -3444,28 +3450,28 @@ int Test_All_Spr_Targets(t_edge *b_pulled, t_node *n_link, t_tree *tree)
             else
               Pre_Order_Pars(n_link,n_link->v[i],tree);
           }
-
-      /* printf("\n. 000000"); fflush(NULL); */
-      /* if(!Check_Lk_At_Given_Edge(NO,tree)) Exit("\n"); */
     }
 
   tree->c_lnL = init_lnL;
 
-  Free(init_len_v1);
-  Free(init_len_v2);
-  Free(init_len_pulled);
+  Free_Scalar_Dbl(init_l_v1);
+  Free_Scalar_Dbl(init_l_v2);
+  Free_Scalar_Dbl(init_l_pulled);
 
-  return 0;
+  Free_Scalar_Dbl(init_v_v1);
+  Free_Scalar_Dbl(init_v_v2);
+  Free_Scalar_Dbl(init_v_pulled);
 
+  return 0;
 }
 
 /*********************************************************/
 
-void Test_One_Spr_Target_Recur(t_node *a, t_node *d, t_edge *pulled, t_node *link, t_edge *residual, int *best_found, t_tree *tree)
+void Test_One_Spr_Target_Recur(t_node *a, t_node *d, t_edge *pulled, t_node *link, t_edge *residual, t_edge *init_target, int *best_found, t_tree *tree)
 {
   int i;
-
-  if(*best_found) return;
+  
+  if(*best_found == YES) return;
   
   if(d->tax) return;
   else
@@ -3476,8 +3482,7 @@ void Test_One_Spr_Target_Recur(t_node *a, t_node *d, t_edge *pulled, t_node *lin
         {
           if(d->v[i] != a)
             {
-              
-              if(tree->mod->s_opt->spr_lnL)
+              if(tree->mod->s_opt->spr_lnL == YES)
                 {
                   MIXT_Set_Alias_Subpatt(YES,tree);
                   Update_P_Lk(tree,d->b[i],d);
@@ -3488,19 +3493,20 @@ void Test_One_Spr_Target_Recur(t_node *a, t_node *d, t_edge *pulled, t_node *lin
               
               tree->depth_curr_path++;
               tree->curr_path[tree->depth_curr_path] = d->v[i];
-              
+
               if((tree->depth_curr_path <= tree->mod->s_opt->max_depth_path) &&
                  (tree->depth_curr_path >= tree->mod->s_opt->min_depth_path))
                 {
-                  move_lnL = Test_One_Spr_Target(d->b[i],pulled,link,residual,tree);
-                  if(move_lnL > tree->best_lnL + tree->mod->s_opt->min_diff_lk_move)
+                  move_lnL = Test_One_Spr_Target(d->b[i],pulled,link,residual,init_target,tree);
+                  if(move_lnL > tree->best_lnL + tree->mod->s_opt->min_diff_lk_move) 
                     {
-                      *best_found = 1;
+                      *best_found = YES;
+                      return;
                     }
                 }
-              
+                            
               if(tree->depth_curr_path < tree->mod->s_opt->max_depth_path)
-                Test_One_Spr_Target_Recur(d,d->v[i],pulled,link,residual,best_found,tree);
+                Test_One_Spr_Target_Recur(d,d->v[i],pulled,link,residual,init_target,best_found,tree);
               
               tree->depth_curr_path--;
             }
@@ -3510,18 +3516,17 @@ void Test_One_Spr_Target_Recur(t_node *a, t_node *d, t_edge *pulled, t_node *lin
 
 /*********************************************************/
 
-phydbl Test_One_Spr_Target(t_edge *b_target, t_edge *b_arrow, t_node *n_link, t_edge *b_residual, t_tree *tree)
+phydbl Test_One_Spr_Target(t_edge *b_target, t_edge *b_arrow, t_node *n_link, t_edge *b_residual, t_edge *init_target, t_tree *tree)
 {
-  phydbl *init_target_len, *init_arrow_len, *init_residual_len;
+  scalar_dbl *init_target_l, *init_arrow_l, *init_residual_l;
+  scalar_dbl *init_target_v, *init_arrow_v, *init_residual_v;
   int i,dir_v0,dir_v1,dir_v2;
-  phydbl *l0,*l1,*l2;
-  t_node *v1, *v2;
+  scalar_dbl *l0,*l1,*l2;
+  scalar_dbl *v0,*v1,*v2;
+  t_node *n1,*n2;
   phydbl init_lnL, move_lnL;
   int init_pars;
-  t_tree *orig_tree;
-  t_edge *orig_target, *orig_arrow;
-  t_node *orig_link;
-  t_spr *orig_move,*move;
+  t_spr *move;
 
   if(tree->mixt_tree != NULL)
     {
@@ -3535,25 +3540,46 @@ phydbl Test_One_Spr_Target(t_edge *b_target, t_edge *b_arrow, t_node *n_link, t_
   init_lnL  = tree->c_lnL;
   init_pars = tree->c_pars;
 
+  move = tree->spr_list[tree->size_spr_list];
+
+  if(move->init_target_l == NULL)
+    {
+      move->init_target_l = Duplicate_Scalar_Dbl(init_target->l);
+      move->init_target_v = Duplicate_Scalar_Dbl(init_target->l_var);
+    }
+  else
+    {
+      Copy_Scalar_Dbl(init_target->l,    move->init_target_l);
+      Copy_Scalar_Dbl(init_target->l_var,move->init_target_v);
+    }
+
   Graft_Subtree(b_target,n_link,b_residual,tree);
 
-  /* init_target_len   = b_target->l->v; */
-  /* init_arrow_len    = b_arrow->l->v; */
-  /* init_residual_len = b_residual->l->v; */
+  // Save edge lengths so that they can be recovered in the end
+  init_target_l   = Duplicate_Scalar_Dbl(b_target->l);
+  init_target_v   = Duplicate_Scalar_Dbl(b_target->l_var);
+
+  init_arrow_l    = Duplicate_Scalar_Dbl(b_arrow->l);
+  init_arrow_v    = Duplicate_Scalar_Dbl(b_arrow->l_var);
 
-  init_target_len   = MIXT_Get_Lengths_Of_This_Edge(b_target,tree);
-  init_arrow_len    = MIXT_Get_Lengths_Of_This_Edge(b_arrow,tree);
-  init_residual_len = MIXT_Get_Lengths_Of_This_Edge(b_residual,tree);
+  init_residual_l = Duplicate_Scalar_Dbl(b_residual->l);
+  init_residual_v = Duplicate_Scalar_Dbl(b_residual->l_var);
 
-  if(tree->mod->s_opt->spr_lnL)
+  if(tree->mod->s_opt->spr_lnL == YES)
     {
       MIXT_Set_Alias_Subpatt(YES,tree);
-      /*       move_lnL = Triple_Dist(n_link,tree,1); */
       Update_PMat_At_Given_Edge(b_target,tree);
       Update_PMat_At_Given_Edge(b_arrow,tree);
       Update_P_Lk(tree,b_residual,n_link);
       move_lnL = Lk(b_residual,tree);
       MIXT_Set_Alias_Subpatt(NO,tree);
+
+      /* if(FABS(move_lnL - tree->best_lnL < 10.)) */
+      /*   { */
+      /*     MIXT_Set_Alias_Subpatt(YES,tree); */
+      /*     move->lnL = Triple_Dist(n_link,tree,YES); */
+      /*     MIXT_Set_Alias_Subpatt(NO,tree); */
+      /*   } */
     }
   else
     {
@@ -3561,114 +3587,102 @@ phydbl Test_One_Spr_Target(t_edge *b_target, t_edge *b_arrow, t_node *n_link, t_
       Pars(b_residual,tree);
     }
 
-  v1 = (b_residual->left == n_link)?(b_residual->rght):(b_residual->left);
-  v2 = (b_target->left   == n_link)?(b_target->rght):(b_target->left);
+  n1 = (b_residual->left == n_link)?(b_residual->rght):(b_residual->left);
+  n2 = (b_target->left   == n_link)?(b_target->rght):(b_target->left);
   dir_v1 = dir_v2 = dir_v0 = -1;
   For(i,3)
     {
-      if(n_link->v[i]      == v1) dir_v1 = i;
-      else if(n_link->v[i] == v2) dir_v2 = i;
+      if(n_link->v[i]      == n1) dir_v1 = i;
+      else if(n_link->v[i] == n2) dir_v2 = i;
       else                        dir_v0 = i;
     }
 
-  l0 = MIXT_Get_Lengths_Of_This_Edge(n_link->b[dir_v0],tree);
+  l0 = Duplicate_Scalar_Dbl(n_link->b[dir_v0]->l);
+  v0 = Duplicate_Scalar_Dbl(n_link->b[dir_v0]->l_var);
+
   if(n_link->v[dir_v1]->num > n_link->v[dir_v2]->num)
     {
-      l1 = MIXT_Get_Lengths_Of_This_Edge(n_link->b[dir_v2],tree);
-      l2 = MIXT_Get_Lengths_Of_This_Edge(n_link->b[dir_v1],tree);
+      l1 = Duplicate_Scalar_Dbl(n_link->b[dir_v2]->l);
+      v1 = Duplicate_Scalar_Dbl(n_link->b[dir_v2]->l_var);
+      l2 = Duplicate_Scalar_Dbl(n_link->b[dir_v1]->l);
+      v2 = Duplicate_Scalar_Dbl(n_link->b[dir_v1]->l_var);
     }
   else
     {
-      l1 = MIXT_Get_Lengths_Of_This_Edge(n_link->b[dir_v1],tree);
-      l2 = MIXT_Get_Lengths_Of_This_Edge(n_link->b[dir_v2],tree);
+      l1 = Duplicate_Scalar_Dbl(n_link->b[dir_v1]->l);
+      v1 = Duplicate_Scalar_Dbl(n_link->b[dir_v1]->l_var);
+      l2 = Duplicate_Scalar_Dbl(n_link->b[dir_v2]->l);
+      v2 = Duplicate_Scalar_Dbl(n_link->b[dir_v2]->l_var);
     }
 
-  move = tree->spr_list[tree->size_spr_list];
   For(i,tree->depth_curr_path+1) move->path[i] = tree->curr_path[i];
-  move->depth_path    = tree->depth_curr_path;
-  move->pars          = tree->c_pars;
-  move->lnL           = tree->c_lnL;
 
-  orig_target = b_target;
-  orig_link   = n_link;
-  orig_arrow  = b_arrow;
-  orig_tree   = tree;
-  orig_move   = move;
-  i = 0;
-  do
+  if(move->l0 != NULL)
     {
-      move->l0            = l0[i];
-      move->l1            = l1[i];
-      move->l2            = l2[i];
+      Free_Scalar_Dbl(move->l0);
+      Free_Scalar_Dbl(move->v0);
+    }
 
-      if(tree->mod->gamma_mgf_bl == YES)
-        {
-          move->v0            = l0[i+1];
-          move->v1            = l1[i+1];
-          move->v2            = l2[i+1];
-        }
+  if(move->l1 != NULL)
+    {
+      Free_Scalar_Dbl(move->l1);
+      Free_Scalar_Dbl(move->v1);
+    }
 
-      move->b_target      = b_target;
-      move->n_link        = n_link;
-      move->b_opp_to_link = b_arrow;
-      move->dist          = b_target->topo_dist_btw_edges;
-      move->n_opp_to_link = (n_link==b_arrow->left)?(b_arrow->rght):(b_arrow->left);
+  if(move->l2 != NULL)
+    {
+      Free_Scalar_Dbl(move->l2);
+      Free_Scalar_Dbl(move->v2);
+    }
 
-      if(tree->next)
-        {
-          tree     = tree->next;
-          b_target = b_target->next;
-          b_arrow  = b_arrow->next;
-          n_link   = n_link->next;
-          move     = move->next;
-        }
-      else
-        {
-          tree     = tree->next;
-          b_target = b_target->next;
-          b_arrow  = b_arrow->next;
-          n_link   = n_link->next;
-          move     = move->next;
-        }
+  move->l0 = l0;
+  move->v0 = v0;
 
-      i+=2;
-    }
-  while(tree);
+  move->l1 = l1;
+  move->v1 = v1;
 
-  b_target = orig_target;
-  n_link   = orig_link;
-  b_arrow  = orig_arrow;
-  tree     = orig_tree;
-  move     = orig_move;
+  move->l2 = l2;
+  move->v2 = v2;
 
+  move->depth_path    = tree->depth_curr_path;
+  move->pars          = tree->c_pars;
+  move->lnL           = tree->c_lnL;
+  move->b_target      = b_target;
+  move->n_link        = n_link;
+  move->b_opp_to_link = b_arrow;
+  move->b_init_target = init_target;
+  move->dist          = b_target->topo_dist_btw_edges;
+  move->n_opp_to_link = (n_link==b_arrow->left)?(b_arrow->rght):(b_arrow->left);
+  
   Include_One_Spr_To_List_Of_Spr(move,tree);
 
-  /* b_target->l->v   = init_target_len; */
-  /* b_arrow->l->v    = init_arrow_len; */
-  /* b_residual->l->v = init_residual_len; */
+  Copy_Scalar_Dbl(init_target_l,b_target->l);
+  Copy_Scalar_Dbl(init_target_v,b_target->l_var);
 
-  MIXT_Set_Lengths_Of_This_Edge(init_target_len,b_target,tree);
-  MIXT_Set_Lengths_Of_This_Edge(init_arrow_len,b_arrow,tree);
-  MIXT_Set_Lengths_Of_This_Edge(init_residual_len,b_residual,tree);
+  Copy_Scalar_Dbl(init_arrow_l,b_arrow->l);
+  Copy_Scalar_Dbl(init_arrow_v,b_arrow->l_var);
+
+  Copy_Scalar_Dbl(init_residual_l,b_residual->l);
+  Copy_Scalar_Dbl(init_residual_v,b_residual->l_var);
 
   Prune_Subtree(n_link,
-        (n_link==b_arrow->left)?(b_arrow->rght):(b_arrow->left),
-        &b_target,
-        &b_residual,
-        tree);
+                (n_link==b_arrow->left)?(b_arrow->rght):(b_arrow->left),
+                &b_target,
+                &b_residual,
+                tree);
 
-  if(tree->mod->s_opt->spr_lnL) Update_PMat_At_Given_Edge(b_target,tree);
+  if(tree->mod->s_opt->spr_lnL == YES) Update_PMat_At_Given_Edge(b_target,tree);
 
   tree->c_lnL   = init_lnL;
   tree->c_pars  = init_pars;
 
-  Free(l0);
-  Free(l1);
-  Free(l2);
 
-  Free(init_target_len);
-  Free(init_arrow_len);
-  Free(init_residual_len);
+  Free_Scalar_Dbl(init_target_l);
+  Free_Scalar_Dbl(init_arrow_l);
+  Free_Scalar_Dbl(init_residual_l);
+  Free_Scalar_Dbl(init_target_v);
+  Free_Scalar_Dbl(init_arrow_v);
+  Free_Scalar_Dbl(init_residual_v);
 
   return move_lnL;
 }
@@ -3677,47 +3691,73 @@ phydbl Test_One_Spr_Target(t_edge *b_target, t_edge *b_arrow, t_node *n_link, t_
 
 void Speed_Spr_Loop(t_tree *tree)
 {
-  phydbl lk_old;
+  phydbl lk_old,delta_lnL;
+  int n_round;
 
   tree->best_pars                  = 1E+8;
-  tree->mod->s_opt->spr_lnL        = 0;
-  tree->mod->s_opt->spr_pars       = 0;
-  tree->mod->s_opt->quickdirty     = 0;
+  tree->mod->s_opt->spr_lnL        = NO;
+  tree->mod->s_opt->spr_pars       = NO;
+  tree->mod->s_opt->quickdirty     = NO;
 
   if((tree->mod->s_opt->print) && (!tree->io->quiet)) PhyML_Printf("\n\n. Maximizing likelihood (using SPR moves)...\n");
 
-  SPR_Shuffle(tree);
+  tree->mod->s_opt->max_depth_path = tree->n_otu;
+  Spr_Pars(0,10,tree);
   Set_Both_Sides(YES,tree);
   Lk(NULL,tree);
-  tree->best_lnL = tree->c_lnL;
 
-  /*****************************/
-  lk_old = UNLIKELY;
-  tree->mod->s_opt->max_depth_path    = tree->n_otu;
-  tree->mod->s_opt->max_delta_lnL_spr = (tree->io->datatype == NT)?(5.):(0.);
-  tree->mod->s_opt->spr_lnL           = NO;
+  n_round = 0;
   do
     {
-      lk_old = tree->c_lnL;
-      Speed_Spr(tree,1);
-      if(tree->n_improvements) Optimiz_All_Free_Param(tree,(tree->io->quiet)?(0):(tree->mod->s_opt->print));
-      if(!tree->n_improvements || FABS(lk_old-tree->c_lnL) < 1.) break;
+      Optimiz_All_Free_Param(tree,(tree->io->quiet)?(NO):(tree->mod->s_opt->print));
+      Optimize_Br_Len_Serie(tree);
     }
-  while(1);
+  while(++n_round != 3); 
+
+  tree->best_pars = tree->c_pars;
+  tree->best_lnL  = tree->c_lnL;
+
+
+
+  /*****************************/
+  if(tree->mod->s_opt->print == YES && tree->io->quiet == NO) PhyML_Printf("\n\n. First round of SPR moves...\n");
+  lk_old = tree->c_lnL;
+  tree->mod->s_opt->max_depth_path    = tree->n_otu;
+  tree->mod->s_opt->max_delta_lnL_spr = (tree->io->datatype == NT)?(0.):(0.);
+  tree->mod->s_opt->spr_lnL           = NO;
+  tree->mod->s_opt->spr_pars          = NO;
+  tree->mod->s_opt->min_diff_lk_move  = 0.1;
+  delta_lnL                           = 3.0;
+  Speed_Spr(tree,1.0,20,delta_lnL);
+  Optimiz_All_Free_Param(tree,(tree->io->quiet)?(NO):(tree->mod->s_opt->print));
+
+
+  /*****************************/
+  if(tree->mod->s_opt->print == YES && tree->io->quiet == NO) PhyML_Printf("\n\n. Second round of SPR moves...\n");
+  lk_old = tree->c_lnL;
+  tree->mod->s_opt->max_depth_path    = 15;
+  tree->mod->s_opt->max_delta_lnL_spr = (tree->io->datatype == NT)?(5.):(0.);
+  tree->mod->s_opt->spr_lnL           = YES;
+  tree->mod->s_opt->spr_pars          = NO;
+  tree->mod->s_opt->min_diff_lk_move  = 0.01;
+  delta_lnL                           = 1.0;
+  Speed_Spr(tree,1.0,20,delta_lnL);
+  Optimiz_All_Free_Param(tree,(tree->io->quiet)?(NO):(tree->mod->s_opt->print));
   /*****************************/
 
 
   /*****************************/
+  tree->mod->s_opt->min_diff_lk_move  = 0.001;
   lk_old = UNLIKELY;
   do
     {
       lk_old = tree->c_lnL;
-      if(!Simu(tree,10)) break;
-      Optimiz_All_Free_Param(tree,(tree->io->quiet)?(0):(tree->mod->s_opt->print));
+      if(!Simu(tree,5)) break;
     }
   while(FABS(lk_old - tree->c_lnL) > tree->mod->s_opt->min_diff_lk_local);
   /*****************************/
 
+  Optimiz_All_Free_Param(tree,(tree->io->quiet)?(NO):(tree->mod->s_opt->print));
 
   /*****************************/
   do
@@ -3735,7 +3775,7 @@ void Speed_Spr_Loop(t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-void Speed_Spr(t_tree *tree, int max_cycles)
+void Speed_Spr(t_tree *tree, phydbl prop_spr, int max_cycles, phydbl delta_lnL)
 {
   int step,old_pars;
   phydbl old_lnL;
@@ -3765,21 +3805,22 @@ void Speed_Spr(t_tree *tree, int max_cycles)
       old_lnL  = tree->c_lnL;
       old_pars = tree->c_pars;
 
-      tree->max_spr_depth          = 0;
-      tree->n_improvements         = 0;
-      tree->perform_spr_right_away = 1;
-      Spr(UNLIKELY,tree);
+      tree->max_spr_depth  = 0;
+      tree->n_improvements = 0;
+      Spr(UNLIKELY,prop_spr,tree);
 
-      if(!tree->mod->s_opt->spr_pars)
+      if(tree->mod->s_opt->spr_pars == NO)
         {
-          /* Optimise branch lengths */
-          Optimize_Br_Len_Serie(tree);
-          /* Update partial likelihoods */
-          Set_Both_Sides(YES,tree);
-          Lk(NULL,tree);
-          
-          /* Print log-likelihood and parsimony scores */
-          if((tree->mod->s_opt->print) && (!tree->io->quiet)) Print_Lk(tree,"[Branch lengths     ]");
+          if(tree->n_improvements > 0)
+            {
+              /* Optimise branch lengths */
+              Optimize_Br_Len_Serie(tree);
+              /* Update partial likelihoods */
+              Set_Both_Sides(YES,tree);
+              Lk(NULL,tree);
+              /* Print log-likelihood and parsimony scores */
+              if((tree->mod->s_opt->print) && (!tree->io->quiet)) Print_Lk(tree,"[Branch lengths     ]");
+            }
         }
       else
         {
@@ -3795,6 +3836,8 @@ void Speed_Spr(t_tree *tree, int max_cycles)
           if((tree->io->print_site_lnl) && (!tree->mod->s_opt->spr_pars)) Print_Site_Lk(tree,tree->io->fp_out_lk); fflush(tree->io->fp_out_lk);
           Free(s);
         }
+
+      if(tree->io->print_json_trace == YES) JSON_Tree_Io(tree,tree->io->fp_out_json_trace); 
       
       /* Record the current best log-likelihood and parsimony */
       tree->best_lnL  = tree->c_lnL;
@@ -3824,25 +3867,24 @@ void Speed_Spr(t_tree *tree, int max_cycles)
 
       /* Exit if no improvements after complete optimization */
       if(step+1 > max_cycles) break;
-      if((!tree->mod->s_opt->spr_pars) && (FABS(old_lnL-tree->c_lnL) < tree->mod->s_opt->min_diff_lk_global)) break;
-/*       if(( tree->mod->s_opt->spr_pars) && (FABS(old_pars-tree->c_pars) < 1.)) break; */
+      if((tree->mod->s_opt->spr_pars == NO)  && (FABS(old_lnL-tree->c_lnL)   < delta_lnL)) break;
+      if((tree->mod->s_opt->spr_pars == YES) && (FABS(old_pars-tree->c_pars) < 1)) break;
       if(!tree->n_improvements) break;
-
-    }while(1);
+    }
+  while(1);
 }
 
 /*********************************************************/
 
 int Evaluate_List_Of_Regraft_Pos_Triple(t_spr **spr_list, int list_size, t_tree *tree)
 {
-  t_spr *move,*orig_move;
+  t_spr *move;
   t_edge *init_target, *b_residual;
-  int i,j,best_move,n;
+  int i,j,best_move;
   int dir_v0, dir_v1, dir_v2;
-  phydbl *recorded_l;
+  scalar_dbl *recorded_l,*recorded_v;
   phydbl best_lnL,init_lnL;
   int recorded;
-  t_tree *orig_tree;
 
   if(tree->mixt_tree != NULL)
     {
@@ -3854,7 +3896,7 @@ int Evaluate_List_Of_Regraft_Pos_Triple(t_spr **spr_list, int list_size, t_tree
   init_target = b_residual = NULL;
   best_move = -1;
   init_lnL = tree->c_lnL;
-  recorded_l = NULL;
+  recorded_v = recorded_l = NULL;
 
   if(!list_size && !tree->io->fp_in_constraint_tree)
     {
@@ -3863,7 +3905,6 @@ int Evaluate_List_Of_Regraft_Pos_Triple(t_spr **spr_list, int list_size, t_tree
       Exit("\n");
     }
 
-
   recorded = NO;
   For(i,list_size)
     {
@@ -3882,7 +3923,11 @@ int Evaluate_List_Of_Regraft_Pos_Triple(t_spr **spr_list, int list_size, t_tree
           Record_Br_Len(tree);
           
           /* Prune subtree */
-          Prune_Subtree(move->n_link,move->n_opp_to_link,&init_target,&b_residual,tree);
+          Prune_Subtree(move->n_link,
+                        move->n_opp_to_link,
+                        &init_target,
+                        &b_residual,
+                        tree);
           
           if(recorded == NO)
             {
@@ -3895,63 +3940,29 @@ int Evaluate_List_Of_Regraft_Pos_Triple(t_spr **spr_list, int list_size, t_tree
               recorded = YES;
               
               Fast_Br_Len(init_target,tree,NO);
-              
+
               /*! Record branch length at prune site */
-              recorded_l = MIXT_Get_Lengths_Of_This_Edge(init_target,tree);
-              
-              /*! Make sure recorded_l has been updated beforehand */
-              orig_move = move;
-              orig_tree = tree;
-              n = 0;
-              do
+              if(recorded_l == NULL)
                 {
-                  move->init_target_l = recorded_l[n];
-                  move->init_target_v = recorded_l[n+1];
-                  n+=2;
-                  
-                  
-                  if(tree->next)
-                    {
-                      move = move->next;
-                      tree = tree->next;
-                    }
-                  else
-                    {
-                      move = move->next;
-                      tree = tree->next;
-                    }
+                  recorded_l = Duplicate_Scalar_Dbl(init_target->l);
+                  recorded_v = Duplicate_Scalar_Dbl(init_target->l_var);
                 }
-              while(tree);
-              move = orig_move;
-              tree = orig_tree;
+              else
+                {
+                  Copy_Scalar_Dbl(init_target->l,recorded_l);
+                  Copy_Scalar_Dbl(init_target->l_var,recorded_v);
+                }
+
+              Copy_Scalar_Dbl(recorded_l,move->init_target_l);
+              Copy_Scalar_Dbl(recorded_v,move->init_target_v);
             }
           else
             {
-              MIXT_Set_Lengths_Of_This_Edge(recorded_l,init_target,tree);
-              
-              orig_move = move;
-              orig_tree = tree;
-              n = 0;
-              do
-                {
-                  move->init_target_l = recorded_l[n];
-                  move->init_target_v = recorded_l[n+1];
-                  n+=2;
-                  
-                  if(tree->next)
-                    {
-                      move = move->next;
-                      tree = tree->next;
-                    }
-                  else
-                    {
-                      move = move->next;
-                      tree = tree->next;
-                    }
-                }
-              while(tree);
-              move = orig_move;
-              tree = orig_tree;
+              Copy_Scalar_Dbl(recorded_l,move->b_init_target->l);
+              Copy_Scalar_Dbl(recorded_v,move->b_init_target->l_var);
+
+              Copy_Scalar_Dbl(recorded_l,move->init_target_l);
+              Copy_Scalar_Dbl(recorded_v,move->init_target_v);
             }
           
           /* Update the change proba matrix at prune position */
@@ -3965,123 +3976,50 @@ int Evaluate_List_Of_Regraft_Pos_Triple(t_spr **spr_list, int list_size, t_tree
           
           /* Regraft subtree */
           Graft_Subtree(move->b_target,move->n_link,b_residual,tree);
-          
-          dir_v1 = dir_v2 = dir_v0 = -1;
-          For(j,3)
-            {
-              if(move->n_link->v[j] == move->n_opp_to_link) dir_v0 = j;
-              else if(dir_v1 < 0)                           dir_v1 = j;
-              else                                          dir_v2 = j;
-            }
-          
-          orig_tree = tree;
-          orig_move = move;
-          do
-            {
-              move->n_link->b[dir_v0]->l->v = move->l0;
-              move->n_link->b[dir_v0]->l_var->v = move->v0;
-              
-              if(move->n_link->v[dir_v1]->num > move->n_link->v[dir_v2]->num)
-                {
-                  move->n_link->b[dir_v2]->l->v = move->l1;
-                  move->n_link->b[dir_v1]->l->v = move->l2;
-                  
-                  if(tree->io->mod->gamma_mgf_bl == YES)
-                    {
-                      move->n_link->b[dir_v2]->l_var->v = move->v1;
-                      move->n_link->b[dir_v1]->l_var->v = move->v2;
-                    }
-                }
-              else
-                {
-                  move->n_link->b[dir_v1]->l->v = move->l1;
-                  move->n_link->b[dir_v2]->l->v = move->l2;
-                  
-                  if(tree->io->mod->gamma_mgf_bl == YES)
-                    {
-                      move->n_link->b[dir_v1]->l_var->v = move->v1;
-                      move->n_link->b[dir_v2]->l_var->v = move->v2;
-                    }
-                }
-              
-              if(tree->next)
-                {
-                  move = move->next;
-                  tree = tree->next;
-                }
-              else
-                {
-                  move = move->next;
-                  tree = tree->next;
-                }
-              
-            }
-          while(tree);
-          move = orig_move;
-          tree = orig_tree;
-          
+                    
           MIXT_Set_Alias_Subpatt(YES,tree);
           move->lnL = Triple_Dist(move->n_link,tree,YES);
+
           MIXT_Set_Alias_Subpatt(NO,tree);
-          
+
           if((move->lnL < best_lnL) && (move->lnL > best_lnL - tree->mod->s_opt->max_delta_lnL_spr))
             {
               /* Estimate the three t_edge lengths at the regraft site */
+              MIXT_Set_Alias_Subpatt(YES,tree);
               move->lnL = Triple_Dist(move->n_link,tree,NO);
+              MIXT_Set_Alias_Subpatt(NO,tree);
             }
+
+          /* printf("\n. %d/%d move->lnL= %f best_lnL=%f absolute_best=%f",i,list_size,move->lnL,best_lnL,tree->best_lnL); */
           
           /* Record updated branch lengths for this move */
-          orig_move = move;
-          orig_tree = tree;
-          do
+          dir_v1 = dir_v2 = dir_v0 = -1;
+          For(j,3)
             {
-              move->l0 = move->n_link->b[dir_v0]->l->v;
-              move->v0 = move->n_link->b[dir_v0]->l_var->v;
-              
-              if(move->n_link->v[dir_v1]->num > move->n_link->v[dir_v2]->num)
-                {
-                  move->l1 = move->n_link->b[dir_v2]->l->v;
-                  move->l2 = move->n_link->b[dir_v1]->l->v;
-                  
-                  if(tree->io->mod->gamma_mgf_bl == YES)
-                    {
-                      move->v1 = move->n_link->b[dir_v2]->l_var->v;
-                      move->v2 = move->n_link->b[dir_v1]->l_var->v;
-                    }
-                }
-              else
-                {
-                  move->l1 = move->n_link->b[dir_v1]->l->v;
-                  move->l2 = move->n_link->b[dir_v2]->l->v;
-                  
-                  if(tree->io->mod->gamma_mgf_bl == YES)
-                    {
-                      move->v1 = move->n_link->b[dir_v1]->l_var->v;
-                      move->v2 = move->n_link->b[dir_v2]->l_var->v;
-                    }
-                }
-              
-              /* printf("\n. %f %f %f %f",move->l0,move->l1,move->l2,move->lnL); */
-              /* For(j,2*tree->n_otu-3) */
-              /*   printf("\n== %d %f %f", */
-              /*          j, */
-              /*          tree->a_edges[j]->gamma_prior_mean, */
-              /*          tree->a_edges[j]->l_var->v); */
-              
-              if(tree->next)
-                {
-                  move = move->next;
-                  tree = tree->next;
-                }
-              else
-                {
-                  move = move->next;
-                  tree = tree->next;
-                }
+              if(move->n_link->v[j] == move->n_opp_to_link) dir_v0 = j;
+              else if(dir_v1 < 0)                           dir_v1 = j;
+              else                                          dir_v2 = j;
+            }
+
+          Copy_Scalar_Dbl(move->n_link->b[dir_v0]->l,    move->l0);
+          Copy_Scalar_Dbl(move->n_link->b[dir_v0]->l_var,move->v0);
+
+          if(move->n_link->v[dir_v1]->num > move->n_link->v[dir_v2]->num)
+            {
+              Copy_Scalar_Dbl(move->n_link->b[dir_v2]->l,    move->l1);
+              Copy_Scalar_Dbl(move->n_link->b[dir_v2]->l_var,move->v1);
+
+              Copy_Scalar_Dbl(move->n_link->b[dir_v1]->l,    move->l2);
+              Copy_Scalar_Dbl(move->n_link->b[dir_v1]->l_var,move->v2);
+            }
+          else
+            {
+              Copy_Scalar_Dbl(move->n_link->b[dir_v1]->l,    move->l1);
+              Copy_Scalar_Dbl(move->n_link->b[dir_v1]->l_var,move->v1);
+
+              Copy_Scalar_Dbl(move->n_link->b[dir_v2]->l,    move->l2);
+              Copy_Scalar_Dbl(move->n_link->b[dir_v2]->l_var,move->v2);
             }
-          while(tree);
-          move = orig_move;
-          tree = orig_tree;
           
           if(move->lnL > best_lnL + tree->mod->s_opt->min_diff_lk_move)
             {
@@ -4121,11 +4059,14 @@ int Evaluate_List_Of_Regraft_Pos_Triple(t_spr **spr_list, int list_size, t_tree
           tree->c_lnL = init_lnL;
         }
       
+
       /* Bail out as soon as you've found a true improvement */
+      /* if(move->lnL > tree->best_lnL + 1.0) break; */
       if(move->lnL > tree->best_lnL + tree->mod->s_opt->min_diff_lk_move) break;
+      
     }
   
-  /*   PhyML_Printf("\n. [ %4d/%4d ]",i,list_size); */
+  /* PhyML_Printf("\n. [ %4d/%4d ] %f",i,list_size,tree->best_lnL); */
   /*   PhyML_Printf("\n. max_improv = %f",max_improv); */
   
   
@@ -4168,7 +4109,8 @@ int Evaluate_List_Of_Regraft_Pos_Triple(t_spr **spr_list, int list_size, t_tree
     }
 #endif
   
-  Free(recorded_l);
+  Free_Scalar_Dbl(recorded_l);
+  Free_Scalar_Dbl(recorded_v);
   
   return best_move;
 }
@@ -4181,9 +4123,6 @@ int Try_One_Spr_Move_Triple(t_spr *move, t_tree *tree)
   int j;
   int dir_v0, dir_v1, dir_v2;
   int accept;
-  t_edge *orig_b;
-  t_spr *orig_move;
-  t_tree *orig_tree;
 
   if(tree->mixt_tree != NULL)
     {
@@ -4194,36 +4133,13 @@ int Try_One_Spr_Move_Triple(t_spr *move, t_tree *tree)
   Record_Br_Len(tree);
 
   Prune_Subtree(move->n_link,
-        move->n_opp_to_link,
-        &init_target,
-        &b_residual,
-        tree);
-
-  orig_tree = tree;
-  orig_b    = init_target;
-  orig_move = move;
-  do
-    {
-      init_target->l->v             = move->init_target_l;
-      init_target->l_var->v = move->init_target_v;
-
-      if(tree->next)
-        {
-          init_target = init_target->next;
-          move        = move->next;
-          tree        = tree->next;
-        }
-      else
-        {
-          init_target = init_target->next;
-          move        = move->next;
-          tree        = tree->next;
-        }
-    }
-  while(tree);
-  init_target = orig_b;
-  move        = orig_move;
-  tree        = orig_tree;
+                move->n_opp_to_link,
+                &init_target,
+                &b_residual,
+                tree);
+  
+  Copy_Scalar_Dbl(move->init_target_l,init_target->l);
+  Copy_Scalar_Dbl(move->init_target_v,init_target->l_var);
 
   Graft_Subtree(move->b_target,move->n_link,b_residual,tree);
 
@@ -4235,51 +4151,25 @@ int Try_One_Spr_Move_Triple(t_spr *move, t_tree *tree)
       else                                          dir_v2 = j;
     }
 
-  orig_move = move;
-  orig_tree = tree;
-  do
-    {
-      move->n_link->b[dir_v0]->l->v = move->l0;
-      move->n_link->b[dir_v0]->l_var->v = move->v0;
-
-      if(move->n_link->v[dir_v1]->num > move->n_link->v[dir_v2]->num)
-        {
-          move->n_link->b[dir_v2]->l->v = move->l1;
-          move->n_link->b[dir_v1]->l->v = move->l2;
-
-              if(tree->io->mod->gamma_mgf_bl == YES)
-                {
-                  move->n_link->b[dir_v2]->l_var->v = move->v1;
-                  move->n_link->b[dir_v1]->l_var->v = move->v2;
-                }
-        }
-      else
-        {
-          move->n_link->b[dir_v1]->l->v = move->l1;
-          move->n_link->b[dir_v2]->l->v = move->l2;
+  Copy_Scalar_Dbl(move->l0,move->n_link->b[dir_v0]->l);
+  Copy_Scalar_Dbl(move->v0,move->n_link->b[dir_v0]->l_var);
 
-              if(tree->io->mod->gamma_mgf_bl == YES)
-                {
-                  move->n_link->b[dir_v1]->l_var->v = move->v1;
-                  move->n_link->b[dir_v2]->l_var->v = move->v2;
-                }
-        }
+  if(move->n_link->v[dir_v1]->num > move->n_link->v[dir_v2]->num)
+    {
+      Copy_Scalar_Dbl(move->l1,move->n_link->b[dir_v2]->l);
+      Copy_Scalar_Dbl(move->v1,move->n_link->b[dir_v2]->l_var);
 
-      if(tree->next)
-        {
-          move = move->next;
-          tree = tree->next;
-        }
-      else
-        {
-          move = move->next;
-          tree = tree->next;
-        }
+      Copy_Scalar_Dbl(move->l2,move->n_link->b[dir_v1]->l);
+      Copy_Scalar_Dbl(move->v2,move->n_link->b[dir_v1]->l_var);
+    }
+  else
+    {
+      Copy_Scalar_Dbl(move->l1,move->n_link->b[dir_v1]->l);
+      Copy_Scalar_Dbl(move->v1,move->n_link->b[dir_v1]->l_var);
 
+      Copy_Scalar_Dbl(move->l2,move->n_link->b[dir_v2]->l);
+      Copy_Scalar_Dbl(move->v2,move->n_link->b[dir_v2]->l_var);
     }
-  while(tree);
-  move = orig_move;
-  tree = orig_tree;
 
   accept = YES;
   if(!Check_Topo_Constraints(tree,tree->io->cstr_tree)) accept = NO;
@@ -4295,41 +4185,22 @@ int Try_One_Spr_Move_Triple(t_spr *move, t_tree *tree)
 
       if(FABS(tree->c_lnL - move->lnL) > tree->mod->s_opt->min_diff_lk_move)
         {
-          int i;
           PhyML_Printf("\n== c_lnL = %f move_lnL = %f", tree->c_lnL,move->lnL);
-          printf("\n== l0=%f l1=%f l2=%f v0=%f v1=%f v2=%f",move->l0,move->l1,move->l2,move->v0,move->v1,move->v2);
-          For(i,2*tree->n_otu-3)
-            printf("\n== %d %f %f",
-                   i,
-                   tree->a_edges[i]->l->v,
-                   tree->a_edges[i]->l_var->v);
-
-          /* printf("\n. %f %f  %f %f", */
-          /*        tree->next->c_lnL, */
-          /*        tree->next->next->c_lnL, */
-          /*        tree->next->next->c_lnL, */
-          /*        tree->next->next->next->c_lnL); */
+          PhyML_Printf("\n== %d l0=%G l1=%G l2=%G v0=%G v1=%G v2=%G",move->n_link->num,move->l0->v,move->l1->v,move->l2->v,move->v0->v,move->v1->v,move->v2->v);
+          PhyML_Printf("\n== Gamma MGF? %d",tree->io->mod->gamma_mgf_bl);
           PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__);
+          Check_Lk_At_Given_Edge(YES,tree);
+          /* { */
+          /*   int i; */
+          /*   For(i,2*tree->n_otu-1) */
+          /*     printf("\n. Edge %d %G %G", */
+          /*            i, */
+          /*            tree->a_edges[i]->l->v, */
+          /*            tree->a_edges[i]->l_var->v); */
+          /* } */
           Exit("\n");
         }
 
-      //
-/*       if(!(tree->n_improvements % tree->mod->s_opt->br_len_in_spr)) */
-/* 	{ */
-/* 	  tree->mod->s_opt->brent_it_max = 10; */
-/* 	  Optimize_Br_Len_Serie(tree->a_nodes[0], */
-/* 				tree->a_nodes[0]->v[0], */
-/* 				tree->a_nodes[0]->b[0], */
-/* 				tree, */
-/* 				tree->data); */
-/* 	  tree->mod->s_opt->brent_it_max = 500; */
-
-/* 	  tree->both_sides = 1; */
-/* 	  Lk(tree); */
-/* 	} */
-      //
-
-
       if((tree->mod->s_opt->print) && (!tree->io->quiet))
         {
           Print_Lk_And_Pars(tree);
@@ -4349,18 +4220,18 @@ int Try_One_Spr_Move_Triple(t_spr *move, t_tree *tree)
     }
 
   Prune_Subtree(move->n_link,
-        move->n_opp_to_link,
-        &move->b_target,
-        &b_residual,
-        tree);
+                move->n_opp_to_link,
+                &move->b_target,
+                &b_residual,
+                tree);
 
   Graft_Subtree(init_target,
-        move->n_link,
-        b_residual,
-        tree);
-
+                move->n_link,
+                b_residual,
+                tree);
+  
   Restore_Br_Len(tree);
-
+  
   Set_Both_Sides(YES,tree);
   MIXT_Set_Alias_Subpatt(YES,tree);
   Lk(NULL,tree);
@@ -4444,8 +4315,8 @@ void Include_One_Spr_To_List_Of_Spr(t_spr *move, t_tree *tree)
       Exit("\n");
     }
 
-  if((( tree->mod->s_opt->spr_lnL) && (move->lnL  > tree->spr_list[tree->size_spr_list-1]->lnL)) ||
-     ((!tree->mod->s_opt->spr_lnL) && (move->pars <= tree->spr_list[tree->size_spr_list-1]->pars)))
+  if(((tree->mod->s_opt->spr_lnL == YES) && (move->lnL  > tree->spr_list[tree->size_spr_list-1]->lnL)) ||
+     ((tree->mod->s_opt->spr_lnL == NO) && (move->pars <= tree->spr_list[tree->size_spr_list-1]->pars)))
     {
       move_list = tree->spr_list[tree->size_spr_list-1];
 
@@ -4454,23 +4325,63 @@ void Include_One_Spr_To_List_Of_Spr(t_spr *move, t_tree *tree)
       move_list->lnL           = move->lnL;
       move_list->dist          = move->dist;
 
+
+      if(move_list->l0 == NULL)
+        {
+          move_list->l0 = Duplicate_Scalar_Dbl(move->l0);
+          move_list->v0 = Duplicate_Scalar_Dbl(move->v0);
+        }
+      else
+        {
+          Copy_Scalar_Dbl(move->l0,move_list->l0);
+          Copy_Scalar_Dbl(move->v0,move_list->v0);
+        }
+
+      if(move_list->l1 == NULL)
+        {
+          move_list->l1 = Duplicate_Scalar_Dbl(move->l1);
+          move_list->v1 = Duplicate_Scalar_Dbl(move->v1);
+        }
+      else
+        {
+          Copy_Scalar_Dbl(move->l1,move_list->l1);
+          Copy_Scalar_Dbl(move->v1,move_list->v1);
+        }
+
+      if(move_list->l2 == NULL)
+        {
+          move_list->l2 = Duplicate_Scalar_Dbl(move->l2);
+          move_list->v2 = Duplicate_Scalar_Dbl(move->v2);
+        }
+      else
+        {
+          Copy_Scalar_Dbl(move->l2,move_list->l2);
+          Copy_Scalar_Dbl(move->v2,move_list->v2);
+        }
+
+
+      if(move_list->init_target_l == NULL)
+        {
+          move_list->init_target_l = Duplicate_Scalar_Dbl(move->init_target_l);     
+          move_list->init_target_v = Duplicate_Scalar_Dbl(move->init_target_v);     
+        }
+      else
+        { 
+          Copy_Scalar_Dbl(move->init_target_l,move_list->init_target_l);     
+          Copy_Scalar_Dbl(move->init_target_v,move_list->init_target_v);     
+        }
+
       orig_move      = move;
       orig_move_list = move_list;
       orig_tree      = tree;
       do
         {
-          move_list->l0            = move->l0;
-          move_list->l1            = move->l1;
-          move_list->l2            = move->l2;
-          move_list->v0            = move->v0;
-          move_list->v1            = move->v1;
-          move_list->v2            = move->v2;
           move_list->b_target      = move->b_target;
           move_list->n_link        = move->n_link;
           move_list->n_opp_to_link = move->n_opp_to_link;
           move_list->b_opp_to_link = move->b_opp_to_link;
-          
-          
+          move_list->b_init_target = move->b_init_target;
+
           if(tree->next)
             {
               move      = move->next;
@@ -4493,8 +4404,8 @@ void Include_One_Spr_To_List_Of_Spr(t_spr *move, t_tree *tree)
       
       for(i=tree->size_spr_list-1;i>0;i--)
         {
-          if((( tree->mod->s_opt->spr_lnL) && (tree->spr_list[i]->lnL > tree->spr_list[i-1]->lnL)) ||
-             ((!tree->mod->s_opt->spr_lnL) && (tree->spr_list[i]->pars <=  tree->spr_list[i-1]->pars)))
+          if(((tree->mod->s_opt->spr_lnL == YES) && (tree->spr_list[i]->lnL > tree->spr_list[i-1]->lnL)) ||
+             ((tree->mod->s_opt->spr_lnL == NO) && (tree->spr_list[i]->pars <=  tree->spr_list[i-1]->pars)))
             {
               
               orig_tree = tree;
@@ -4505,7 +4416,7 @@ void Include_One_Spr_To_List_Of_Spr(t_spr *move, t_tree *tree)
                   tree->spr_list[i]   = buff_spr;
                   
                   if(tree->next) tree = tree->next;
-                  else            tree = tree->next;
+                  else           tree = tree->next;
                 }
               while(tree);
               tree = orig_tree;
@@ -4616,21 +4527,24 @@ int Check_Spr_Move_Validity(t_spr *this_spr_move, t_tree *tree)
 
 /*********************************************************/
 
-void Spr_Pars(t_tree *tree)
-{
+void Spr_Pars(int threshold, int n_round_max, t_tree *tree)
+{  
+  int curr_pars;
 
   PhyML_Printf("\n. Minimizing parsimony...\n");
 
-  tree->best_pars = 1E+8;
-  tree->best_lnL  = UNLIKELY;
-  tree->mod->s_opt->spr_lnL = 0;
+  tree->best_pars           = 1E+8;
+  tree->best_lnL            = UNLIKELY;
+  tree->mod->s_opt->spr_lnL = NO;
+  curr_pars                 = tree->c_pars;
 
-  tree->mod->s_opt->spr_pars = 1;
+  tree->mod->s_opt->spr_pars = YES;
   do
     {
-      Speed_Spr(tree,1);
-    }while(tree->n_improvements);
-  tree->mod->s_opt->spr_pars = 0;
+      curr_pars = tree->c_pars;
+      Speed_Spr(tree,1.0,1,0.0);
+    }
+  while(tree->n_improvements && FABS(tree->c_pars - curr_pars) > threshold);
 
   PhyML_Printf("\n");
 }
@@ -4638,10 +4552,10 @@ void Spr_Pars(t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-void SPR_Shuffle(t_tree *mixt_tree)
+void Spr_Shuffle(t_tree *mixt_tree)
 {
   phydbl lk_old;
-  int *orig_catg,n;
+  int *orig_catg,n,n_iter;
   t_tree *tree,**tree_list;
 
   if(mixt_tree->mod->s_opt->print) PhyML_Printf("\n\n. Refining the tree...\n");
@@ -4693,16 +4607,17 @@ void SPR_Shuffle(t_tree *mixt_tree)
   Lk(NULL,mixt_tree);
 
 
-  /* mixt_tree->mod->s_opt->print             = YES; */
   mixt_tree->best_pars                     = 1E+8;
+  mixt_tree->mod->s_opt->spr_lnL           = NO;
   mixt_tree->mod->s_opt->spr_pars          = NO;
   mixt_tree->mod->s_opt->quickdirty        = NO;
   mixt_tree->best_lnL                      = mixt_tree->c_lnL;
   mixt_tree->mod->s_opt->max_delta_lnL_spr = 0.;
   mixt_tree->mod->s_opt->max_depth_path    = mixt_tree->n_otu;
-  mixt_tree->mod->s_opt->spr_lnL           = NO;
+  mixt_tree->mod->s_opt->min_diff_lk_move  = 0.1;
+  mixt_tree->annealing_temp                = 0.0;
 
-  mixt_tree->annealing_temp = 4.;
+  n_iter = 0;
   do
     {
       Set_Both_Sides(YES,mixt_tree);
@@ -4716,21 +4631,17 @@ void SPR_Shuffle(t_tree *mixt_tree)
       mixt_tree->best_lnL       = mixt_tree->c_lnL;
 
       lk_old = mixt_tree->c_lnL;
-      Spr(UNLIKELY,mixt_tree);
-
-      Optimiz_All_Free_Param(mixt_tree,(mixt_tree->io->quiet)?(0):(mixt_tree->mod->s_opt->print));
-
-      Optimize_Br_Len_Serie(mixt_tree);
+      Spr(UNLIKELY,1.0,mixt_tree);
 
       mixt_tree->annealing_temp -= 2.;
 
       if(mixt_tree->annealing_temp < 0.0) mixt_tree->annealing_temp = 0.0;
 
-      if((mixt_tree->n_improvements < 20 || mixt_tree->max_spr_depth  < 5 || (FABS(lk_old-mixt_tree->c_lnL) < 1.)) &&
-         (Are_Equal(mixt_tree->annealing_temp,0.0,1.E-6))) break;
+      if(mixt_tree->n_improvements < 5      || 
+         mixt_tree->max_spr_depth  < 2      || 
+         FABS(lk_old-mixt_tree->c_lnL) < 5. ||
+         ++n_iter > 10) break;
       
-      /* PhyML_Printf("\n. Temperature: %f",mixt_tree->annealing_temp); */
-
     }
   while(1);
 
@@ -4783,14 +4694,156 @@ void SPR_Shuffle(t_tree *mixt_tree)
 
 }
 
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void Spr_Random_Explore(t_tree *tree, phydbl anneal_temp, phydbl prop_spr, int do_rnd, int max_cycles)
+{
+  int step,i,n_targets,n_rand,no_improvement;
+  t_tree *best_tree;
+  scalar_dbl **best_bl;
+  t_node *rnd_node;
+  t_edge *b_target,*b_residual,**target_list,*rnd_edge;
+  phydbl true_best_lnL;
+
+  if(tree->lock_topo == YES)
+    {
+      PhyML_Printf("\n== The tree topology is locked.");
+      PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__);
+      Exit("\n");
+    }
+
+  Set_Both_Sides(YES,tree);
+  Pars(NULL,tree);
+  Lk(NULL,tree);
+
+  tree->mod->s_opt->max_depth_path    = (int)(tree->n_otu/3);
+  tree->mod->s_opt->max_delta_lnL_spr = (tree->io->datatype == NT)?(5.):(0.);
+  tree->mod->s_opt->min_diff_lk_move  = 0.1;
+  tree->mod->s_opt->spr_lnL           = NO;
+  tree->mod->s_opt->spr_pars          = NO;
+  tree->mod->s_opt->deepest_path      = 0;
+  tree->best_pars                     = tree->c_pars;
+  step                                = 0;
+  true_best_lnL                       = tree->c_lnL;
+  best_tree                           = Make_Tree_From_Scratch(tree->n_otu,tree->data);
+  best_bl                             = Copy_Br_Len(tree);
+  target_list                         = (t_edge **)mCalloc(2*tree->n_otu-3,sizeof(t_edge *));
+  n_targets                           = 0;
+  no_improvement                      = 0;
+  tree->annealing_temp                = anneal_temp;
+  Copy_Tree(tree,best_tree);
+
+  do
+    {
 
+      if(do_rnd == YES)
+        {
+          n_rand = 0;
+          do
+            {
+              rnd_node = tree->a_nodes[Rand_Int(tree->n_otu,2*tree->n_otu-3)];
+              assert(rnd_node != tree->n_root && rnd_node->tax == NO);
+              
+              rnd_edge = rnd_node->b[Rand_Int(0,2)];
+              
+              Prune_Subtree(rnd_node,
+                            rnd_node == rnd_edge->left ? rnd_edge->rght : rnd_edge->left,
+                            &b_target,
+                            &b_residual,
+                            tree);
+              
+              n_targets = 0;
+              For(i,3)
+                if(b_target->left->v[i] != b_target->rght)
+                  Get_List_Of_Adjacent_Targets(b_target->left,b_target->left->v[i],NULL,&target_list,&n_targets,0,5);
+              
+              For(i,3)
+                if(b_target->rght->v[i] != b_target->left)
+                  Get_List_Of_Adjacent_Targets(b_target->rght,b_target->rght->v[i],NULL,&target_list,&n_targets,0,5);
+              
+              if(n_targets > 0) b_target = target_list[Rand_Int(0,n_targets-1)];
+              
+              assert(b_target != NULL);
+              
+              Graft_Subtree(b_target,rnd_node,b_residual,tree);
+              
+              n_rand++;
+            }
+          while(n_rand != 1);
+        }
+          
+      Set_Both_Sides(YES,tree);
+      Lk(NULL,tree);
+      Pars(NULL,tree);
+      
+      Print_Lk_And_Pars(tree);
+            
+      if(tree->annealing_temp < 0.0) tree->annealing_temp = 0.0;
+      if(prop_spr > 1.0)             prop_spr = 1.0;
+      
+      tree->best_lnL       = tree->c_lnL;
+      tree->best_pars      = tree->c_pars;
+      tree->n_improvements = 0;
+      tree->max_spr_depth  = 0;
+      Spr(UNLIKELY,prop_spr,tree);
+      /* Simu(tree,5); */
+      
+      tree->annealing_temp -= 0.5;
+      prop_spr+=0.2;
 
+      Set_Both_Sides(YES,tree);
+      Optimiz_All_Free_Param(tree,(tree->io->quiet)?(0):(tree->mod->s_opt->print));
+      Optimize_Br_Len_Serie(tree);
 
+      if(tree->io->print_trace)
+        {
+          char *s = Write_Tree(tree,NO);
+          PhyML_Fprintf(tree->io->fp_out_trace,"[%f]%s\n",tree->c_lnL,s); fflush(tree->io->fp_out_trace);
+          if((tree->io->print_site_lnl) && (!tree->mod->s_opt->spr_pars)) Print_Site_Lk(tree,tree->io->fp_out_lk); fflush(tree->io->fp_out_lk);
+          Free(s);
+        }
 
+      if(tree->io->print_json_trace == YES) JSON_Tree_Io(tree,tree->io->fp_out_json_trace); 
+      
+      /* Record the current best log-likelihood and parsimony */
+      if(tree->c_lnL > true_best_lnL)
+        {
+          no_improvement = 0;
+          true_best_lnL = tree->c_lnL;
+          /* PhyML_Printf("\n. Better tree found: %f",tree->c_lnL); */
+          For(i,2*tree->n_otu-1) Free_Scalar_Dbl(best_bl[i]);
+          Free(best_bl);
+          best_bl = Copy_Br_Len(tree);
+          Copy_Tree(tree,best_tree); /* Record tree topology, branch lengths and model parameters */
+        }
+      else
+        {
+          no_improvement++;
+        }
+      
+      Transfer_Br_Len_To_Tree(best_bl,tree);
+      Copy_Tree(best_tree,tree);
 
+    }
+  while(++step <= max_cycles && tree->n_improvements > 0 && tree->max_spr_depth  > 1);
 
+  Free(target_list);
 
+}
 
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
 
 /*
 ** EOF: spr.c
diff --git a/src/spr.h b/src/spr.h
index f10867e..5e16953 100644
--- a/src/spr.h
+++ b/src/spr.h
@@ -55,17 +55,17 @@ void PostOrder_w      (t_tree *tree, t_node *v, t_edge *v_e, t_node *w, t_edge *
 
 
 
-void Speed_Spr(t_tree *tree, int max_cycles);
+void Speed_Spr(t_tree *tree, phydbl prop_spr, int max_cycles, phydbl delta_lnL);
 void Speed_Spr_Loop(t_tree *tree);
 void Make_Spr_List(t_tree *tree);
 void Init_One_Spr(t_spr *a_spr);
 t_spr *Make_One_Spr(t_tree *tree);
-int Spr(phydbl init_lnL, t_tree *tree);
+int Spr(phydbl init_lnL, phydbl prop_spr, t_tree *tree);
 int Spr_Recur(t_node *a, t_node *d, t_tree *tree);
 int Test_All_Spr_Targets(t_edge *pulled, t_node *link, t_tree *tree);
 void Randomize_Spr_List(t_tree *tree);
-void Test_One_Spr_Target_Recur(t_node *a, t_node *d, t_edge *pulled, t_node *link, t_edge *residual, int *best_found, t_tree *tree);
-phydbl Test_One_Spr_Target(t_edge *target, t_edge *arrow, t_node *link, t_edge *residual, t_tree *tree);
+void Test_One_Spr_Target_Recur(t_node *a, t_node *d, t_edge *pulled, t_node *link, t_edge *residual, t_edge *init_target, int *best_found, t_tree *tree);
+phydbl Test_One_Spr_Target(t_edge *target, t_edge *arrow, t_node *link, t_edge *residual, t_edge *init_target, t_tree *tree);
 void Apply_Spr_Moves_One_By_One(t_tree *tree);
 int Try_One_Spr_Move_Triple(t_spr *move, t_tree *tree);
 int Try_One_Spr_Move_Full(t_spr *move, t_tree *tree);
@@ -77,10 +77,12 @@ int Evaluate_List_Of_Regraft_Pos_Triple(t_spr **spr_list, int list_size, t_tree
 void Best_Spr(t_tree *tree);
 int Check_Spr_Move_Validity(t_spr *this_spr_move, t_tree *tree);
 void Spr_Subtree(t_edge *b, t_node *link, t_tree *tree);
-void Spr_Pars(t_tree *tree);
-void SPR_Shuffle(t_tree *tree);
+void Spr_Pars(int threshold, int n_round_max, t_tree *tree);
+void Spr_Shuffle(t_tree *tree);
 void Sort_Spr_List_Depth(t_tree *tree);
 void Sort_Spr_List_LnL(t_tree *tree);
+void Spr_Random_Explore(t_tree *tree, phydbl anneal_temp, phydbl prop_spr, int do_rnd, int max_cycles);
+void Sort_Spr_List_Pars(t_tree *tree);
 
 
 
diff --git a/src/stats.c b/src/stats.c
index 742b188..d0d2950 100644
--- a/src/stats.c
+++ b/src/stats.c
@@ -5140,6 +5140,7 @@ void Random_String(char *s, int len)
 {
   int i;
   For(i,len) s[i] = Rand_Int(97,121);
+  s[i] = '\0';
 }
 
 //////////////////////////////////////////////////////////////
@@ -5196,9 +5197,9 @@ t_poly *Rpoly(int n)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-phydbl Area_Of_Poly_Monte_Carlo(t_poly **poly, int n_poly, t_geo_coord *lim)
+phydbl Area_Of_Poly_Monte_Carlo(t_poly *poly, t_geo_coord *lim)
 {
-  int n_hit,n_trials,trial,i;
+  int n_hit,n_trials,trial;
   t_geo_coord *point;
 
   point = (t_geo_coord *)GEO_Make_Geo_Coord(2);
@@ -5210,14 +5211,15 @@ phydbl Area_Of_Poly_Monte_Carlo(t_poly **poly, int n_poly, t_geo_coord *lim)
     {
       point->lonlat[0] = Uni()*lim->lonlat[0];
       point->lonlat[1] = Uni()*lim->lonlat[1];
-      For(i,n_poly) if(Is_In_Polygon(point,poly[i]) == YES) { n_hit++; break; }
+      if(Is_In_Polygon(point,poly) == YES) n_hit++;
       trial++;
     }
   while(trial < n_trials);
 
+
   Free_Geo_Coord(point);
 
-  return((phydbl)(n_hit)/n_trials);
+  return((phydbl)(n_hit)/n_trials*lim->lonlat[0]*lim->lonlat[1]);
 }
 
 /*////////////////////////////////////////////////////////////
@@ -5230,6 +5232,9 @@ int Is_In_Polygon(t_geo_coord *point, t_poly *poly)
   phydbl x_intersect;
   short int is_in;
 
+  assert(point);
+  assert(poly);
+
   /* Coordinates of the point to test */
   x = point->lonlat[0];
   y = point->lonlat[1];
diff --git a/src/stats.h b/src/stats.h
index 472fbde..00a26bc 100644
--- a/src/stats.h
+++ b/src/stats.h
@@ -112,7 +112,7 @@ int *Random_Permut(int n);
 phydbl Dexp_Trunc(phydbl x, phydbl lambda, phydbl left, phydbl rght);
 phydbl Rexp_Trunc(phydbl lambda, phydbl left, phydbl rght);
 t_poly *Rpoly(int n);
-phydbl Area_Of_Poly_Monte_Carlo(t_poly **poly, int n_poly, t_geo_coord *lim);
+phydbl Area_Of_Poly_Monte_Carlo(t_poly *poly, t_geo_coord *lim);
 int Is_In_Polygon(t_geo_coord *point, t_poly *poly);
 phydbl Variance(phydbl *x, int l);
 phydbl Bessi0(phydbl x);
diff --git a/src/times.c b/src/times.c
index b6ce7b4..27a0e4e 100644
--- a/src/times.c
+++ b/src/times.c
@@ -39,10 +39,11 @@ int TIMES_main(int argc, char **argv)
 #ifdef MPI
   int rc;
   rc = MPI_Init(&argc,&argv);
-  if (rc != MPI_SUCCESS) {
-    PhyML_Printf("\n. Error starting MPI program. Terminating.\n");
-    MPI_Abort(MPI_COMM_WORLD, rc);
-  }
+  if (rc != MPI_SUCCESS) 
+    {
+      PhyML_Printf("\n== Error starting MPI program. Terminating.\n");
+      MPI_Abort(MPI_COMM_WORLD, rc);
+    }
   MPI_Comm_size(MPI_COMM_WORLD,&Global_numTask);
   MPI_Comm_rank(MPI_COMM_WORLD,&Global_myRank);
 #endif
@@ -512,7 +513,6 @@ void TIMES_Print_Node_Times(t_node *a, t_node *d, t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void TIMES_Set_All_Node_Priors(t_tree *tree)
 {
   int i;
@@ -631,9 +631,9 @@ void TIMES_Set_All_Node_Priors_Top_Down(t_node *a, t_node *d, t_tree *tree)
 	  
 	  if(tree->rates->t_prior_max[d->num] < tree->rates->t_prior_min[d->num])
 	    {
-	      PhyML_Printf("\n. prior_min=%f prior_max=%f",tree->rates->t_prior_min[d->num],tree->rates->t_prior_max[d->num]);
-	      PhyML_Printf("\n. Inconsistency in the prior settings detected at t_node %d",d->num);
-	      PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__);
+	      PhyML_Printf("\n== prior_min=%f prior_max=%f",tree->rates->t_prior_min[d->num],tree->rates->t_prior_max[d->num]);
+	      PhyML_Printf("\n== Inconsistency in the prior settings detected at t_node %d",d->num);
+	      PhyML_Printf("\n== Err. in file %s at line %d (function %s)\n\n",__FILE__,__LINE__,__FUNCTION__);
 	      Warn_And_Exit("\n");
 	    }
 	}
@@ -963,20 +963,11 @@ phydbl TIMES_Lk_Yule_Order(t_tree *tree)
 phydbl TIMES_Lk_Times(t_tree *tree)
 {
   
-  #ifdef PHYTIME
+#ifdef PHYTIME
   tree->rates->c_lnL_times =  TIMES_Lk_Yule_Order(tree);
-  #elif INVITEE
-  /* tree->rates->c_lnL_times = TIMES_Calib_Cond_Prob(tree); */
-  /* tree->rates->c_lnL_times =  TIMES_Lk_Yule_Order(tree); */
-
-  tree->rates->c_lnL_times =  TIMES_Lk_Yule_Order_Root_Cond(tree);
-  if(isinf(tree->rates->c_lnL_times)) return(tree->rates->c_lnL_times);
-  else
-    {
-      if(tree->rates->update_time_norm_const == YES) tree->rates->log_K_cur = K_Constant_Prior_Times_Log(tree);
-      tree->rates->c_lnL_times += tree->rates->log_K_cur;
-    }
-  #endif
+#elif defined(DATE)
+  tree->rates->c_lnL_times =  TIMES_Lk_Birth_Death(tree);
+#endif
 
   return(tree->rates->c_lnL_times);
 }
@@ -1309,7 +1300,6 @@ void TIMES_Lk_Uniform_Post(t_node *a, t_node *d, t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 /* Set the root position so that most of the taxa in the outgroup 
    correspond to the most ancient time point.
 */
@@ -1428,6 +1418,8 @@ void TIMES_Update_Node_Ordering(t_tree *tree)
   phydbl *t;
   int swap = NO;
 
+  For(i,2*tree->n_otu-1) tree->rates->t_rank[i] = i;
+
   t = tree->rates->nd_t;
 
   do
@@ -1438,7 +1430,7 @@ void TIMES_Update_Node_Ordering(t_tree *tree)
 	  if(t[tree->rates->t_rank[i]] > t[tree->rates->t_rank[i+1]]) // Sort in ascending order
 	    {
 	      swap = YES;
-	      buff                       = tree->rates->t_rank[i];
+	      buff                     = tree->rates->t_rank[i];
 	      tree->rates->t_rank[i]   = tree->rates->t_rank[i+1];
 	      tree->rates->t_rank[i+1] = buff;
 	    }	    
@@ -1446,10 +1438,9 @@ void TIMES_Update_Node_Ordering(t_tree *tree)
     }
   while(swap == YES);
 
-  /* For(i,2*tree->n_otu-1) */
-  /*   { */
-  /*     printf("\n. ..... %f",t[tree->rates->t_rank[i]]); */
-  /*   } */
+  /* For(i,2*tree->n_otu-1) PhyML_Printf("\n. node %3d time: %12f", */
+  /*                                     tree->rates->t_rank[i], */
+  /*                                     tree->rates->nd_t[tree->rates->t_rank[i]]); */
 }
 
 //////////////////////////////////////////////////////////////
@@ -1498,7 +1489,7 @@ void TIMES_Set_Calibration(t_tree *tree)
       tree->rates->t_prior_max[i] = BIG; 
    }
 
-  cal = tree->rates->calib;
+  cal = tree->rates->a_cal[0];
   while(cal)
     {
       /* if(cal->is_active == YES) */
@@ -1551,7 +1542,6 @@ void TIMES_Reset_Prior_Times(t_tree *tree)
 // statistics 'simplification' as described in Yang and Rannala, 2005. 
 phydbl TIMES_Lk_Yule_Order_Root_Cond(t_tree *tree)
 {
-
   int j;
   phydbl *t,*tf;
   t_node *n;
@@ -1632,4 +1622,463 @@ phydbl TIMES_Lk_Yule_Order_Root_Cond(t_tree *tree)
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
+// Log of prob density of internal node ages conditional on tree height, under
+// the birth death process with complete sampling.
+phydbl TIMES_Lk_Birth_Death(t_tree *tree)
+{
+  int i;
+  phydbl lnL;
+  phydbl p0t1,p0t,p1t,gt,vt1;
+  phydbl b,d;
+  phydbl t1,t;
+
+  lnL = 0.0;
+  b   = tree->rates->birth_rate;
+  d   = tree->rates->death_rate;
+  t1  = FABS(tree->rates->nd_t[tree->n_root->num]);
+
+  // Normalizing factor. Need to call this function first
+  // so that t_prior_min/max are up to date for what's next
+  lnL -= LOG(DATE_J_Sum_Product(tree));
+
+  if(Are_Equal(b,d,1.E-6) == NO)
+    {
+      p0t1 = (b-d)/(b-d*EXP((d-b)*t1));
+      vt1  = 1. - p0t1*EXP((d-b)*t1);
+      
+      // Equation 4, 5, 6, 7 in Yang and Rannala (2006)
+      For(i,2*tree->n_otu-1)
+        {
+          // Node age outside its calibration boundaries
+          if(tree->rates->nd_t[i] > tree->rates->t_prior_max[i] ||
+             tree->rates->nd_t[i] < tree->rates->t_prior_min[i]) 
+            {
+              tree->rates->c_lnL_times = UNLIKELY;
+              return UNLIKELY;
+            }
+
+          if(tree->a_nodes[i]->tax == NO && tree->a_nodes[i] != tree->n_root)
+            {
+              t   = FABS(tree->rates->nd_t[i]);              
+              p0t = (b-d)/(b-d*EXP((d-b)*t));
+              p1t = p0t*p0t*EXP((d-b)*t);
+              gt  = b*p1t/vt1;
+              lnL += LOG(gt);
+            }
+        }
+    }
+  else
+    {
+      // Equation 8 in Yang and Rannala (2006)
+      For(i,2*tree->n_otu-1)
+        {
+          // Node age outside its calibration boundaries
+          if(tree->rates->nd_t[i] > tree->rates->t_prior_max[i] ||
+             tree->rates->nd_t[i] < tree->rates->t_prior_min[i]) 
+            {
+              tree->rates->c_lnL_times = UNLIKELY;
+              return UNLIKELY;
+            }
+
+          if(tree->a_nodes[i]->tax == NO && tree->a_nodes[i] != tree->n_root)
+            {
+              t   = FABS(tree->rates->nd_t[i]);
+              gt = (1.+b*t1)/(t1*(1.+b*t)*(1.+b*t));
+              lnL += LOG(gt);
+            }
+        }
+    }
+    
+  tree->rates->c_lnL_times = lnL;
+
+  if(isnan(lnL) || isinf(FABS(lnL)))
+    {
+      tree->rates->c_lnL_times = UNLIKELY;
+      return UNLIKELY;
+    }
+
+
+  return(lnL);
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+// Generate a subtree including all taxa in tax_list. The age of the root of that
+// subtree is t_mrca. All nodes in the subtree are thus younger than that.
+void TIMES_Connect_List_Of_Taxa(t_node **tax_list, int list_size, phydbl t_mrca, phydbl *times, int *nd_num, t_tree *mixt_tree)
+{
+  phydbl t_upper_bound, t_lower_bound;
+  int i,j,n_anc,*permut;
+  t_node *n,**anc,*new_mrca;
+
+  t_lower_bound = t_mrca;
+  t_upper_bound = 0.0;
+  n             = NULL;
+  anc           = NULL;
+  new_mrca      = NULL;
+  permut        = NULL;
+  
+  
+  // Find the upper bound for all the new node ages that 
+  // will be created in this function
+  For(i,list_size)
+    {
+      n = tax_list[i];
+      while(n->v[0] != NULL) n = n->v[0];
+      if(times[n->num] < t_upper_bound) t_upper_bound = times[n->num];
+    }
+  
+  /* printf("\n. upper: %f lower: %f t_mrca: %f\n",t_upper_bound,t_lower_bound,t_mrca); */
+  assert(t_upper_bound > t_lower_bound);
+  
+  // Get the list of current mrcas to all taxa in tax_list. There should be
+  // at least one of these
+  n_anc = 0;
+  For(i,list_size)
+    {
+      n = tax_list[i];
+      while(n->v[0] != NULL) n = n->v[0];
+      For(j,n_anc) if(anc[j] == n) break;
+      if(j == n_anc)
+        {
+          if(n_anc == 0) anc = (t_node **)mCalloc(1,sizeof(t_node *));
+          else           anc = (t_node **)mRealloc(anc,n_anc+1,sizeof(t_node *));
+          anc[n_anc] = n;
+          n_anc++;
+        }
+    }
+
+  /* printf("\n. n_anc: %d",n_anc); */
+  /* For(i,n_anc) PhyML_Printf("\n. anc: %d",anc[i]->num); */
+  
+  if(n_anc == 1) // All the nodes in tax_list are already connected. Bail out.
+    {
+      Free(anc);
+      return;
+    }
+  
+  // Connect randomly and set ages
+  permut = Permutate(n_anc);
+  i = 0;
+  do
+    {
+      new_mrca               = mixt_tree->a_nodes[*nd_num];
+      anc[permut[i]]->v[0]   = new_mrca;
+      anc[permut[i+1]]->v[0] = new_mrca;
+      new_mrca->v[1]         = anc[permut[i]];
+      new_mrca->v[2]         = anc[permut[i+1]];
+      new_mrca->v[0]         = NULL;
+      times[new_mrca->num]   = Uni()*(t_upper_bound - t_lower_bound) + t_lower_bound;
+      printf("\n. new_mrca->num: %d time: %f [%f %f] t_mrca: %f %d connect to %d %d [%f %f]",
+             new_mrca->num,
+             times[new_mrca->num],
+             t_lower_bound,
+             t_upper_bound,
+             t_mrca,
+             new_mrca->num,
+             new_mrca->v[1]->num,
+             new_mrca->v[2]->num,
+             times[new_mrca->v[1]->num],
+             times[new_mrca->v[2]->num]
+             );
+      fflush(NULL);
+
+      t_upper_bound          = times[new_mrca->num]; // Might give a funny distribution of node ages, but should work nonetheless...
+      anc[permut[i+1]]       = new_mrca;
+      n_anc--;
+      i++;
+      (*nd_num) += 1;
+      if(n_anc == 1) times[new_mrca->num] = t_mrca;
+    }
+  while(n_anc != 1);
+  
+  Free(permut);
+  Free(anc);
+}
+  
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+// Generate a  random rooted tree with node ages fullfiling the
+// time constraints defined in the list of calibration cal_list 
+void TIMES_Randomize_Tree_With_Time_Constraints(t_cal *cal_list, t_tree *mixt_tree)
+{
+  t_node **tips,**nd_list;
+  phydbl *times,*cal_times,time_oldest_cal;
+  int i,j,k,nd_num,*cal_ordering,n_cal,swap,list_size,tmp,orig_is_mixt_tree,repeat,n_max_repeats;
+  t_cal *cal;
+  
+  assert(mixt_tree->rates);
+  
+  tips    = (t_node **)mCalloc(mixt_tree->n_otu,sizeof(t_node *));
+  nd_list = (t_node **)mCalloc(mixt_tree->n_otu,sizeof(t_node *));
+  
+  times                   = mixt_tree->rates->nd_t;
+  orig_is_mixt_tree       = mixt_tree->is_mixt_tree;
+  mixt_tree->is_mixt_tree = NO;
+  n_max_repeats           = 1000;
+
+  For(repeat,n_max_repeats)
+    {
+      nd_num = mixt_tree->n_otu;
+  
+      PhyML_Printf("\n\n. Repeat %d",repeat);
+
+      For(i,mixt_tree->n_otu) tips[i] = mixt_tree->a_nodes[i];
+      For(i,mixt_tree->n_otu) mixt_tree->a_nodes[i]->v[0] = NULL; 
+
+
+      // Set a time for each calibration 
+      cal_times = (phydbl *)mCalloc(1,sizeof(phydbl));
+      time_oldest_cal = 0.0;
+      n_cal = 0;
+      cal = cal_list;
+      while(cal != NULL)
+        {
+          if(cal->is_primary == YES)
+            {
+              if(n_cal > 0) cal_times = (phydbl *)mRealloc(cal_times,n_cal+1,sizeof(phydbl));
+              
+              cal_times[n_cal] = Uni()*(cal->upper - cal->lower) + cal->lower;
+                            
+              if(cal_times[n_cal] < time_oldest_cal) time_oldest_cal = cal_times[n_cal];
+              
+              n_cal++;
+            }
+          cal = cal->next;
+        }
+ 
+      /* printf("\n. n_cal : %d",n_cal); */
+      /* Exit("\n"); */
+     
+      cal_ordering = (int *)mCalloc(n_cal,sizeof(int));
+      For(i,n_cal) cal_ordering[i] = i;
+      
+      // Find the ordering of calibration times from youngest to oldest
+      do
+        {
+          swap = NO;
+          For(i,n_cal-1) 
+            {
+              if(cal_times[cal_ordering[i]] < cal_times[cal_ordering[i+1]])
+                {
+                  tmp               = cal_ordering[i+1];
+                  cal_ordering[i+1] = cal_ordering[i];
+                  cal_ordering[i]   = tmp;
+                  swap = YES;
+                }
+            }
+        }
+      while(swap == YES);
+      
+      For(i,n_cal-1) assert(cal_times[cal_ordering[i]] > cal_times[cal_ordering[i+1]]);
+      
+      /* For(i,n_cal) */
+      /*   { */
+      /*     printf("\n. %d -> %f", */
+      /*            cal_ordering[i], */
+      /*            cal_times[cal_ordering[i]]); fflush(NULL); */
+      /*   } */
+        
+      // Connect all taxa that appear in all primary calibrations
+      For(i,n_cal)
+        {
+          cal = cal_list;
+          j = 0;
+          while(j!=cal_ordering[i]) 
+            { 
+              if(cal->is_primary == YES) j++; 
+              cal = cal->next; 
+              assert(cal); 
+            }
+          
+          list_size = 0;
+          For(j,cal->n_target_tax) 
+            {
+              For(k,mixt_tree->n_otu)  
+                {
+                  if(!strcmp(cal->target_tax[j],tips[k]->name))
+                    {
+                      nd_list[list_size] = tips[k];
+                      list_size++;
+                      break;
+                    }
+                }
+            }
+          
+          assert(list_size == cal->n_target_tax);
+          
+          /* For(j,n_cal) */
+          /*   { */
+          /*     printf("\n. %d -> %f", */
+          /*            cal_ordering[j], */
+          /*            cal_times[cal_ordering[j]]); */
+          /*     fflush(NULL); */
+          /*   } */
+
+          /* For(j,cal->n_target_tax) PhyML_Printf("\n. %s [%d]",nd_list[j]->name,nd_list[j]->num); */
+          /* PhyML_Printf("\n. Time: %f [%f %f]", */
+          /*              cal_times[cal_ordering[i]], */
+          /*              cal->lower, */
+          /*              cal->upper); */
+          
+          /* For(k,list_size) printf("\n@ %s",nd_list[k]->name); */
+          /* printf("\n"); */
+
+          TIMES_Connect_List_Of_Taxa(nd_list, 
+                                     cal->n_target_tax, 
+                                     cal_times[cal_ordering[i]], 
+                                     times, 
+                                     &nd_num,
+                                     mixt_tree);
+
+        }
+      
+      Free(cal_times);
+      Free(cal_ordering);
+      
+      
+      // Connect all remaining taxa
+      For(i,mixt_tree->n_otu) nd_list[i] = NULL;
+      list_size = 0;
+      For(i,mixt_tree->n_otu) 
+        if(tips[i]->v[0] == NULL) // Tip is not connected yet
+          {
+            nd_list[list_size] = tips[i];
+            list_size++;
+          }
+      
+      if(list_size > 0)
+        {
+          For(i,mixt_tree->n_otu) 
+            if(tips[i]->v[0] != NULL) // Add one connected tip to the list
+              {
+                nd_list[list_size] = tips[i];
+                list_size++;
+                break;
+              }
+          
+          TIMES_Connect_List_Of_Taxa(nd_list, 
+                                     list_size,
+                                     Uni()*time_oldest_cal + time_oldest_cal, 
+                                     times, 
+                                     &nd_num,
+                                     mixt_tree);
+          
+        }
+      
+            
+
+      // Adding root node 
+      mixt_tree->n_root = mixt_tree->a_nodes[2*mixt_tree->n_otu-2];
+      mixt_tree->n_root->v[1]->v[0] = mixt_tree->n_root->v[2];
+      mixt_tree->n_root->v[2]->v[0] = mixt_tree->n_root->v[1];
+      Update_Ancestors(mixt_tree->n_root,mixt_tree->n_root->v[2],mixt_tree);
+      Update_Ancestors(mixt_tree->n_root,mixt_tree->n_root->v[1],mixt_tree);
+      mixt_tree->n_root->anc = NULL;
+
+      // Adding root edge
+      mixt_tree->num_curr_branch_available = 0;
+      Connect_Edges_To_Nodes_Recur(mixt_tree->a_nodes[0],mixt_tree->a_nodes[0]->v[0],mixt_tree);
+      Fill_Dir_Table(mixt_tree);
+      Update_Dirs(mixt_tree);
+      
+      For(i,2*mixt_tree->n_otu-3)
+        {
+          if(((mixt_tree->a_edges[i]->left == mixt_tree->n_root->v[1]) || (mixt_tree->a_edges[i]->rght == mixt_tree->n_root->v[1])) &&
+             ((mixt_tree->a_edges[i]->left == mixt_tree->n_root->v[2]) || (mixt_tree->a_edges[i]->rght == mixt_tree->n_root->v[2])))
+            {
+              Add_Root(mixt_tree->a_edges[i],mixt_tree);
+              break;
+            }
+        }
+      
+      DATE_Assign_Primary_Calibration(mixt_tree);
+      DATE_Update_T_Prior_MinMax(mixt_tree);
+
+      {
+        Print_Node(mixt_tree->n_root,mixt_tree->n_root->v[1],mixt_tree);
+        Print_Node(mixt_tree->n_root,mixt_tree->n_root->v[2],mixt_tree);
+
+        int i;
+        For(i,mixt_tree->rates->n_cal)
+          {
+            PhyML_Printf("\n. Node number to which calibration [%d] applies to is [%d]",i,Find_Clade(mixt_tree->rates->a_cal[i]->target_tax,
+                                                                                                     mixt_tree->rates->a_cal[i]->n_target_tax,
+                                                                                                     mixt_tree));
+            PhyML_Printf("\n. Lower bound set to: %15f time units.",mixt_tree->rates->a_cal[i]->lower);
+            PhyML_Printf("\n. Upper bound set to: %15f time units.",mixt_tree->rates->a_cal[i]->upper);
+          }
+      }
+
+
+
+      if(!DATE_Check_Calibration_Constraints(mixt_tree) ||
+         !DATE_Check_Time_Constraints(mixt_tree))
+        {
+          PhyML_Printf("\n. Could not generate tree");
+        }
+      else break; // Tree successfully generated
+    }
+
+  if(repeat == n_max_repeats)
+    {
+      PhyML_Printf("\n\n");
+      PhyML_Printf("\n== A random tree satisfying the calibration constraints provided");
+      PhyML_Printf("\n== could not be generated. It probably means that there are some");
+      PhyML_Printf("\n== inconsistencies in the calibration data. For instance, the calibration");
+      PhyML_Printf("\n== time interval for the MRCA of a clade with taxa {X,Y} (noted as [a,b])");
+      PhyML_Printf("\n== cannot be strictly older than the interval corresponding to taxa ");
+      PhyML_Printf("\n== {X,Z,Y} (noted as [c,d]), i.e., b cannot be smaller (older) than c. ");
+      PhyML_Printf("\n== Also, please remember that the present time corresponds to a time");
+      PhyML_Printf("\n== value equal to zero and past events have negative time values.");
+      Exit("\n");
+    }
+
+  For(j,mixt_tree->n_otu) printf("\n. %s",mixt_tree->a_nodes[j]->name);
+        
+  assert(i != 2*mixt_tree->n_otu-3);
+
+  mixt_tree->is_mixt_tree = orig_is_mixt_tree;
 
+  if(mixt_tree->is_mixt_tree == YES)
+    {
+      t_tree *tree;
+      
+      // Propagate tree topology and reorganize partial lk struct along edges
+      tree = mixt_tree->next;
+      do
+        {
+          For(i,2*tree->n_otu-1)
+            {
+              tree->a_nodes[i]->v[0] = tree->prev->a_nodes[i]->v[0] ? tree->a_nodes[tree->prev->a_nodes[i]->v[0]->num] : NULL;
+              tree->a_nodes[i]->v[1] = tree->prev->a_nodes[i]->v[1] ? tree->a_nodes[tree->prev->a_nodes[i]->v[1]->num] : NULL;
+              tree->a_nodes[i]->v[2] = tree->prev->a_nodes[i]->v[2] ? tree->a_nodes[tree->prev->a_nodes[i]->v[2]->num] : NULL;
+            }
+          tree->num_curr_branch_available = 0;
+          Connect_Edges_To_Nodes_Recur(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree);
+          Fill_Dir_Table(tree);
+          Update_Dirs(tree);
+          Add_Root(tree->a_edges[tree->prev->e_root->num],tree);
+          Reorganize_Edges_Given_Lk_Struct(tree);
+          
+          /* { */
+          /*   printf("\n === \n"); */
+          /*   Print_Node(tree->n_root,tree->n_root->v[1],tree); */
+          /*   Print_Node(tree->n_root,tree->n_root->v[2],tree); */
+          /* } */
+          
+          tree = tree->next;
+        }
+      while(tree);
+    }
+  
+  /* printf("\n >>> \n"); */
+  /* Print_Node(mixt_tree->n_root,mixt_tree->n_root->v[1],mixt_tree); */
+  /* Print_Node(mixt_tree->n_root,mixt_tree->n_root->v[2],mixt_tree); */
+
+  /* PhyML_Printf("\n. %s \n",Write_Tree(mixt_tree,NO)); */
+
+  Free(tips);
+  Free(nd_list);
+}
diff --git a/src/times.h b/src/times.h
index 1cd5457..06f3396 100644
--- a/src/times.h
+++ b/src/times.h
@@ -70,5 +70,8 @@ void TIMES_Label_Edges_With_Calibration_Intervals(t_tree *tree);
 void TIMES_Record_Prior_Times(t_tree *tree);
 void TIMES_Reset_Prior_Times(t_tree *tree);
 phydbl TIMES_Lk_Yule_Order_Root_Cond(t_tree *tree);
+void TIMES_Connect_List_Of_Taxa(t_node **tax_list, int list_size, phydbl t_mrca, phydbl *times, int *nd_num, t_tree *mixt_tree);
+void TIMES_Randomize_Tree_With_Time_Constraints(t_cal *cal_list, t_tree *tree);
+phydbl TIMES_Lk_Birth_Death(t_tree *tree);
 
 #endif
diff --git a/src/utilities.c b/src/utilities.c
index 7ea9267..07a70a6 100644
--- a/src/utilities.c
+++ b/src/utilities.c
@@ -179,12 +179,15 @@ calign *Compact_Data(align **data, option *io)
 {
   calign *cdata_tmp,*cdata;
   int i,j,k,site;
-  int n_patt,which_patt,n_invar;
+  int n_patt,which_patt;
   char **sp_names;
-  int n_otu, n_sites;
+  int n_otu;
   pnode *proot;
   int compress;
   int n_ambigu,is_ambigu;
+  scalar_dbl *io_wght;
+  phydbl len,inc,n_invar;
+
 
   n_otu      = io->n_otu;
   n_patt     = 0;
@@ -197,8 +200,10 @@ calign *Compact_Data(align **data, option *io)
       strcpy(sp_names[i],data[i]->name);
     }
 
-  cdata_tmp = Make_Cseq(n_otu,data[0]->len,io->state_len,data[0]->len,sp_names);
-  proot     = (pnode *)Create_Pnode(T_MAX_ALPHABET);
+  cdata_tmp = Make_Calign(n_otu,data[0]->len,io->state_len,data[0]->len,sp_names);
+  Init_Calign(n_otu,data[0]->len,data[0]->len,cdata_tmp);
+
+  proot = (pnode *)Create_Pnode(T_MAX_ALPHABET);
 
   For(i,n_otu) Free(sp_names[i]);
   Free(sp_names);
@@ -209,24 +214,45 @@ calign *Compact_Data(align **data, option *io)
       Exit("\n");
     }
 
+  // Read in weights given in input file
+  io_wght = NULL;
+  if(io->has_io_weights == YES) 
+    {
+      io_wght = Read_Io_Weights(io);
+      if(Scalar_Len(io_wght) - data[0]->len > 0)
+        {
+          PhyML_Printf("\n== Sequence length (%d) differs from number of weights (%d).\n",
+                       data[0]->len,
+                       Scalar_Len(io_wght));
+          Exit("\n");
+        }
+    }
+
   compress = io->colalias;
   n_ambigu = 0;
-  is_ambigu = 0;
+  is_ambigu = NO;
 
-  if(!io->quiet && !compress)
-    {
-      PhyML_Printf("\n== WARNING: sequences are not compressed !\n");
-    }
+  if(!io->quiet && !compress) PhyML_Printf("\n== WARNING: sequences are not compressed !\n");
 
+  inc = -1.0;
+  len = 0.0;
   Fors(site,data[0]->len,io->state_len)
-    {
-      if(io->rm_ambigu)
+    {      
+      if(io->has_io_weights == YES)
+        inc = Scalar_Elem(site,io_wght);
+      else                
+        inc = 1.;
+      
+      // Sequence length taking into account input weights, if any
+      len += inc;
+
+      if(io->rm_ambigu == YES)
         {
-          is_ambigu = 0;
+          is_ambigu = NO;
           For(j,n_otu) if(Is_Ambigu(data[j]->state+site,io->datatype,io->state_len)) break;
           if(j != n_otu)
             {
-              is_ambigu = 1;
+              is_ambigu = YES;
               n_ambigu++;
             }
         }
@@ -287,13 +313,13 @@ calign *Compact_Data(align **data, option *io)
               else cdata_tmp->invar[n_patt] = -1;
               
               cdata_tmp->sitepatt[site] = n_patt;
-              cdata_tmp->wght[n_patt]  += 1;
-              n_patt                   += 1;
+              cdata_tmp->wght[n_patt] += inc;
+              n_patt += 1;
             }
           else
             {
-              cdata_tmp->sitepatt[site]    = which_patt;
-              cdata_tmp->wght[which_patt] += 1;
+              cdata_tmp->sitepatt[site] = which_patt;
+              cdata_tmp->wght[which_patt] += inc;
             }
         }
     }
@@ -306,45 +332,38 @@ calign *Compact_Data(align **data, option *io)
   
   if(!io->quiet) PhyML_Printf("\n. %d patterns found (out of a total of %d sites). \n",n_patt,data[0]->len);
 
-  if((io->rm_ambigu) && (n_ambigu)) PhyML_Printf("\n. Removed %d columns of the alignment as they contain ambiguous characters (e.g., gaps) \n",n_ambigu);
+  if((io->rm_ambigu == YES) && (n_ambigu > 0)) PhyML_Printf("\n. Removed %d columns of the alignment as they contain ambiguous characters (e.g., gaps) \n",n_ambigu);
 
-/*   For(i,n_otu) */
-/*     { */
-/*       For(j,cdata_tmp->crunch_len) */
-/* 	{ */
-/* 	  printf("%c",cdata_tmp->c_seq[i]->state[j*io->state_len+1]); */
-/* 	} */
-/*       printf("\n"); */
-/*     } */
+  n_invar=0.0;
+  For(i,cdata_tmp->crunch_len) if(cdata_tmp->invar[i] > -1.) n_invar+=cdata_tmp->wght[i];
 
-  n_invar=0;
-  For(i,cdata_tmp->crunch_len)
+  if(io->quiet == NO) 
     {
-      if(cdata_tmp->invar[i] > -1.) n_invar+=(int)cdata_tmp->wght[i];
+      if((n_invar - ceil(n_invar)) < 1.E-10)     
+        PhyML_Printf("\n. %d sites without polymorphism (%.2f%c).\n",(int)n_invar,100.*(phydbl)n_invar/len,'%');
+      else
+        PhyML_Printf("\n. %f sites without polymorphism (%.2f%c).\n",n_invar,100.*(phydbl)n_invar/len,'%');
     }
 
-  if(!io->quiet) PhyML_Printf("\n. %d sites without polymorphism (%.2f%c).\n",n_invar,100.*(phydbl)n_invar/data[0]->len,'%');
-
-  cdata_tmp->obs_pinvar = (phydbl)n_invar/data[0]->len;
+  cdata_tmp->obs_pinvar = (phydbl)n_invar/len;
 
   cdata_tmp->io = io;
 
-  n_sites = 0;
-  For(i,cdata_tmp->crunch_len) n_sites += cdata_tmp->wght[i];
-  if(n_sites != data[0]->len / io->state_len) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);    
-
+  
   if(io->datatype == NT)      Get_Base_Freqs(cdata_tmp);
   else if(io->datatype == AA) Get_AA_Freqs(cdata_tmp);
   else {/* Uniform state frequency distribution.*/}
 
   cdata = Copy_Cseq(cdata_tmp,io);
 
-  Free_Cseq(cdata_tmp);
+  Free_Calign(cdata_tmp);
   Free_Prefix_Tree(proot,T_MAX_ALPHABET);
 
   Check_Ambiguities(cdata,io->datatype,io->state_len);
   Set_D_States(cdata,io->datatype,io->state_len);
 
+  if(io_wght != NULL) Free_Scalar_Dbl(io_wght);
+
   return cdata;
 }
 
@@ -364,7 +383,7 @@ calign *Compact_Cdata(calign *data, option *io)
   cdata         = (calign *)mCalloc(1,sizeof(calign));
   cdata->n_otu  = n_otu;
   cdata->c_seq  = (align **)mCalloc(n_otu,sizeof(align *));
-  cdata->wght   = (int *)mCalloc(data->crunch_len,sizeof(int));
+  cdata->wght   = (phydbl *)mCalloc(data->crunch_len,sizeof(phydbl));
   cdata->b_frq  = (phydbl *)mCalloc(io->mod->ns,sizeof(phydbl));
   cdata->ambigu = (short int *)mCalloc(data->crunch_len,sizeof(short int));
   cdata->invar  = (short int *)mCalloc(data->crunch_len,sizeof(short int));
@@ -385,7 +404,7 @@ calign *Compact_Cdata(calign *data, option *io)
 
   For(site,data->crunch_len)
     {
-      if(data->wght[site])
+      if(data->wght[site] > 0.0)
         {
           For(k,n_patt)
             {
@@ -403,10 +422,7 @@ calign *Compact_Cdata(calign *data, option *io)
                   break;
                 }
             }
-          
-          /*       /\* TO DO *\/ */
-          /*       k = n_patt; */
-          
+                    
           if(k == n_patt)
             {
               For(j,n_otu) Copy_One_State(data->c_seq[j]->state+site*io->state_len,
@@ -510,13 +526,12 @@ pnode *Create_Pnode(int size)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Get_Base_Freqs(calign *data)
 {
   int i,j,k;
   phydbl A,C,G,T;
   phydbl fA,fC,fG,fT;
-  int w;
+  phydbl w;
 
   fA = fC = fG = fT = .25;
 
@@ -524,57 +539,57 @@ void Get_Base_Freqs(calign *data)
     {
       A = C = G = T = .0;
       For(i,data->n_otu)
-    {
-      For(j,data->crunch_len)
-        {
-          w = data->wght[j];
-          if(w)
         {
-          switch(data->c_seq[i]->state[j])
+          For(j,data->crunch_len)
             {
-            case 'A' : A+=w;
-              break;
-            case 'C' : C+=w;
-              break;
-            case 'G' : G+=w;
-              break;
-            case 'T' : T+=w;
-              break;
-            case 'U' : T+=w;
-              break;
-            case 'M' : C+=w*fC/(fC+fA); A+=w*fA/(fA+fC);
-              break;
-            case 'R' : G+=w*fG/(fA+fG); A+=w*fA/(fA+fG);
-              break;
-            case 'W' : T+=w*fT/(fA+fT); A+=w*fA/(fA+fT);
-              break;
-            case 'S' : C+=w*fC/(fC+fG); G+=w*fG/(fC+fG);
-              break;
-            case 'Y' : C+=w*fC/(fC+fT); T+=w*fT/(fT+fC);
-              break;
-            case 'K' : G+=w*fG/(fG+fT); T+=w*fT/(fT+fG);
-              break;
-            case 'B' : C+=w*fC/(fC+fG+fT); G+=w*fG/(fC+fG+fT); T+=w*fT/(fC+fG+fT);
-              break;
-            case 'D' : A+=w*fA/(fA+fG+fT); G+=w*fG/(fA+fG+fT); T+=w*fT/(fA+fG+fT);
-              break;
-            case 'H' : A+=w*fA/(fA+fC+fT); C+=w*fC/(fA+fC+fT); T+=w*fT/(fA+fC+fT);
-              break;
-            case 'V' : A+=w*fA/(fA+fC+fG); C+=w*fC/(fA+fC+fG); G+=w*fG/(fA+fC+fG);
-              break;
-            case 'N' : case 'X' : case '?' : case 'O' : case '-' :
-              A+=w*fA; C+=w*fC; G+=w*fG; T+=w*fT; break;
-            default : break;
+              w = data->wght[j];
+              if(w)
+                {
+                  switch(data->c_seq[i]->state[j])
+                    {
+                    case 'A' : A+=w;
+                      break;
+                    case 'C' : C+=w;
+                      break;
+                    case 'G' : G+=w;
+                      break;
+                    case 'T' : T+=w;
+                      break;
+                    case 'U' : T+=w;
+                      break;
+                    case 'M' : C+=w*fC/(fC+fA); A+=w*fA/(fA+fC);
+                      break;
+                    case 'R' : G+=w*fG/(fA+fG); A+=w*fA/(fA+fG);
+                      break;
+                    case 'W' : T+=w*fT/(fA+fT); A+=w*fA/(fA+fT);
+                      break;
+                    case 'S' : C+=w*fC/(fC+fG); G+=w*fG/(fC+fG);
+                      break;
+                    case 'Y' : C+=w*fC/(fC+fT); T+=w*fT/(fT+fC);
+                      break;
+                    case 'K' : G+=w*fG/(fG+fT); T+=w*fT/(fT+fG);
+                      break;
+                    case 'B' : C+=w*fC/(fC+fG+fT); G+=w*fG/(fC+fG+fT); T+=w*fT/(fC+fG+fT);
+                      break;
+                    case 'D' : A+=w*fA/(fA+fG+fT); G+=w*fG/(fA+fG+fT); T+=w*fT/(fA+fG+fT);
+                      break;
+                    case 'H' : A+=w*fA/(fA+fC+fT); C+=w*fC/(fA+fC+fT); T+=w*fT/(fA+fC+fT);
+                      break;
+                    case 'V' : A+=w*fA/(fA+fC+fG); C+=w*fC/(fA+fC+fG); G+=w*fG/(fA+fC+fG);
+                      break;
+                    case 'N' : case 'X' : case '?' : case 'O' : case '-' :
+                      A+=w*fA; C+=w*fC; G+=w*fG; T+=w*fT; break;
+                    default : break;
+                    }
+                }
             }
         }
-        }
-    }
       fA = A/(A+C+G+T);
       fC = C/(A+C+G+T);
       fG = G/(A+C+G+T);
       fT = T/(A+C+G+T);
     }
-
+  
   data->b_frq[0] = fA;
   data->b_frq[1] = fC;
   data->b_frq[2] = fG;
@@ -677,7 +692,6 @@ void Get_AA_Freqs(calign *data)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 // Swap the nodes on the left and right of e1 with the nodes
 // on the left and right of e2 respectively, or on the
 // right and left of e2 if swap == YES
@@ -723,7 +737,7 @@ void Swap_Nodes_On_Edges(t_edge *e1, t_edge *e2, int swap, t_tree *tree)
 /*////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////*/
 /* As opposed to Connect_Edges_To_Nodes_Recur, the ordering of 
-   edges connected to tips changes does not depend on the topology
+   edges connected to tips does not depend on the topology
 */
 void Connect_Edges_To_Nodes_Serial(t_tree *tree)
 {
@@ -796,7 +810,7 @@ void Connect_One_Edge_To_Two_Nodes(t_node *a, t_node *d, t_edge *b, t_tree *tree
   b->left       = a;
   b->rght       = d;
   if(a->tax) {b->rght = a; b->left = d;} /* root */
-  /* a tip is necessary on the right hand side of the t_edge */
+  /* a tip is necessarily on the righthand side of the t_edge */
 
   tree->num_curr_branch_available += 1;
 
@@ -804,9 +818,9 @@ void Connect_One_Edge_To_Two_Nodes(t_node *a, t_node *d, t_edge *b, t_tree *tree
     (Set_Edge_Dirs(b,a,d,tree)):
     (Set_Edge_Dirs(b,d,a,tree));
 
-  b->l->v                    = a->l[b->l_r];
-  if(a->tax) b->l->v         = a->l[b->r_l];
-  b->l_old->v                = b->l->v;
+  b->l->v            = a->l[b->l_r];
+  if(a->tax) b->l->v = a->l[b->r_l];
+  b->l_old->v        = b->l->v;
 }
 
 //////////////////////////////////////////////////////////////
@@ -852,7 +866,6 @@ void Exit(char *message)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void *mCalloc(int nb, size_t size)
 {
   void *allocated;
@@ -1330,7 +1343,6 @@ void Share_Spr_Struct(t_tree *t_full, t_tree *t_empt)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Share_Pars_Struct(t_tree *t_full, t_tree *t_empt)
 {
   int i;
@@ -1354,8 +1366,6 @@ void Share_Pars_Struct(t_tree *t_full, t_tree *t_empt)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
-
 int Sort_Edges_NNI_Score(t_tree *tree, t_edge **sorted_edges, int n_elem)
 {
   int i,j;
@@ -1423,22 +1433,22 @@ void NNI(t_tree *tree, t_edge *b_fcus, int do_swap)
   t_node *v1,*v2,*v3,*v4;
   phydbl lk0, lk1, lk2;
   phydbl lk0_init, lk1_init, lk2_init;
-  phydbl *l0,*l1,*l2;
+  scalar_dbl *len0,*len1,*len2;
+  scalar_dbl *var0,*var1,*var2;
   phydbl l_infa, l_infb;
   phydbl lk_init;
-  t_edge *b;
-  int i;
-
+  
   if(tree->prev) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);    
 
   lk_init                = tree->c_lnL;
-  b_fcus->nni->init_l    = b_fcus->l->v;
   b_fcus->nni->init_lk   = tree->c_lnL;;
   b_fcus->nni->best_conf = 0;
   b_fcus->nni->score     = +1.0;
   lk0 = lk1 = lk2        = UNLIKELY;
   v1 = v2 = v3 = v4      = NULL;
 
+  if(b_fcus->nni->init_l != NULL)  Copy_Scalar_Dbl(b_fcus->l,b_fcus->nni->init_l);
+  else                             b_fcus->nni->init_l = Duplicate_Scalar_Dbl(b_fcus->l);
 
   v1                     = b_fcus->left->v[b_fcus->l_v1];
   v2                     = b_fcus->left->v[b_fcus->l_v2];
@@ -1451,7 +1461,7 @@ void NNI(t_tree *tree, t_edge *b_fcus, int do_swap)
   if(v3->num < v4->num) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
 
 
-  /***********/
+  /************************************************************/
   Swap(v2,b_fcus->left,b_fcus->rght,v3,tree);
   Set_Both_Sides(YES,tree);
 
@@ -1461,15 +1471,19 @@ void NNI(t_tree *tree, t_edge *b_fcus, int do_swap)
 
   l_infa = 10.;
   l_infb = tree->mod->l_min/b_fcus->l->v;
+  lk1    = lk1_init;
 
-  if(tree->mod->s_opt->fast_nni)
-    {
-      Fast_Br_Len(b_fcus,tree,1);
-      lk1 = Lk(b_fcus,tree);
-    }
-  else
+  if(tree->mod->s_opt->nni_br_len_opt == YES)
     {
-      lk1 = Br_Len_Brent(l_infb,l_infa,b_fcus,tree);
+      if(tree->mod->s_opt->fast_nni)
+        {
+          Fast_Br_Len(b_fcus,tree,1);
+          lk1 = Lk(b_fcus,tree);
+        }
+      else 
+        {
+          lk1 = Br_Len_Brent(l_infb,l_infa,b_fcus,tree);
+        }
     }
 
   if(lk1 < lk1_init - tree->mod->s_opt->min_diff_lk_local)
@@ -1479,13 +1493,13 @@ void NNI(t_tree *tree, t_edge *b_fcus, int do_swap)
       PhyML_Printf("\n== Err. in NNI (1)");
     }
 
-  /* l1  = b_fcus->l->v; */
-  l1  = MIXT_Get_Lengths_Of_This_Edge(b_fcus,tree);
+  len1 = Duplicate_Scalar_Dbl(b_fcus->l);
+  var1 = Duplicate_Scalar_Dbl(b_fcus->l_var);
   Swap(v3,b_fcus->left,b_fcus->rght,v2,tree);
-  /***********/
+  /************************************************************/
 
 
-  /***********/
+  /************************************************************/
   Swap(v2,b_fcus->left,b_fcus->rght,v4,tree);
   Restore_Br_Len(tree);
   Set_Both_Sides(YES,tree);
@@ -1496,15 +1510,20 @@ void NNI(t_tree *tree, t_edge *b_fcus, int do_swap)
 
   l_infa = 10.;
   l_infb = tree->mod->l_min/b_fcus->l->v;
+ 
+  lk2    = lk2_init;
 
-  if(tree->mod->s_opt->fast_nni)
-    {
-      Fast_Br_Len(b_fcus,tree,1);
-      lk2 = Lk(b_fcus,tree);
-    }
-  else
+  if(tree->mod->s_opt->nni_br_len_opt == YES)
     {
-      lk2 = Br_Len_Brent(l_infb,l_infa,b_fcus,tree);
+      if(tree->mod->s_opt->fast_nni)
+        {
+          Fast_Br_Len(b_fcus,tree,1);
+          lk2 = Lk(b_fcus,tree);
+        }
+      else 
+        {
+          lk2 = Br_Len_Brent(l_infb,l_infa,b_fcus,tree);
+        }
     }
 
   if(lk2 < lk2_init - tree->mod->s_opt->min_diff_lk_local)
@@ -1514,14 +1533,14 @@ void NNI(t_tree *tree, t_edge *b_fcus, int do_swap)
       PhyML_Printf("\n== Err. in NNI (2)");
    }
 
-  /* l2  = b_fcus->l->v; */
-  l2  = MIXT_Get_Lengths_Of_This_Edge(b_fcus,tree);
+  len2 = Duplicate_Scalar_Dbl(b_fcus->l);
+  var2 = Duplicate_Scalar_Dbl(b_fcus->l_var);
   Swap(v4,b_fcus->left,b_fcus->rght,v2,tree);
-  /***********/
+  /************************************************************/
 
 
 
-  /***********/
+  /************************************************************/
   Restore_Br_Len(tree);
   Set_Both_Sides(YES,tree);
 
@@ -1529,28 +1548,33 @@ void NNI(t_tree *tree, t_edge *b_fcus, int do_swap)
   lk0_init = Update_Lk_At_Given_Edge(b_fcus,tree);
   MIXT_Set_Alias_Subpatt(NO,tree);
 
+
   if(FABS(lk0_init - lk_init) > tree->mod->s_opt->min_diff_lk_local)
     {
       PhyML_Printf("\n== lk_init = %f; lk = %f diff = %f l = %G",
-           lk_init,
-           lk0_init,
-           lk_init-lk0_init,
-           b_fcus->l->v);
+                   lk_init,
+                   lk0_init,
+                   lk_init-lk0_init,
+                   b_fcus->l->v);
       PhyML_Printf("\n== Curr_lnL = %f",Lk(NULL,tree));
       Exit("\n== Err. in NNI (3)");
     }
 
   l_infa = 10.;
   l_infb = tree->mod->l_min/b_fcus->l->v;
+  lk0    = lk0_init;
 
-  if(tree->mod->s_opt->fast_nni)
-    {
-      Fast_Br_Len(b_fcus,tree,1);
-      lk0 = Lk(b_fcus,tree);
-    }
-  else
+  if(tree->mod->s_opt->nni_br_len_opt == YES)
     {
-      lk0 = Br_Len_Brent(l_infb,l_infa,b_fcus,tree);
+      if(tree->mod->s_opt->fast_nni)
+        {
+          Fast_Br_Len(b_fcus,tree,1);
+          lk0 = Lk(b_fcus,tree);
+        }
+      else 
+        {
+          lk0 = Br_Len_Brent(l_infb,l_infa,b_fcus,tree);
+        }
     }
 
   if(lk0 < lk_init - tree->mod->s_opt->min_diff_lk_local)
@@ -1561,25 +1585,44 @@ void NNI(t_tree *tree, t_edge *b_fcus, int do_swap)
       Exit("\n");
     }
 
-  /* l0 = b_fcus->l->v; */
-  l0  = MIXT_Get_Lengths_Of_This_Edge(b_fcus,tree);
-  /***********/
+  len0 = Duplicate_Scalar_Dbl(b_fcus->l);
+  var0 = Duplicate_Scalar_Dbl(b_fcus->l_var);
+  /************************************************************/
 
   b_fcus->nni->lk0 = lk0;
   b_fcus->nni->lk1 = lk1;
   b_fcus->nni->lk2 = lk2;
+  
+  if(b_fcus->nni->l0 == NULL) b_fcus->nni->l0 = Duplicate_Scalar_Dbl(len0);
+  else                        Copy_Scalar_Dbl(len0,b_fcus->nni->l0);
 
-  b = b_fcus;
-  i = 0;
-  do
-    {
-      b->nni->l0 = l0[i];
-      b->nni->l1 = l1[i];
-      b->nni->l2 = l2[i];
-      b = b->next;
-      i++;
-    }
-  while(b);
+  if(b_fcus->nni->l1 == NULL) b_fcus->nni->l1 = Duplicate_Scalar_Dbl(len1);
+  else                        Copy_Scalar_Dbl(len1,b_fcus->nni->l1);
+
+  if(b_fcus->nni->l2 == NULL) b_fcus->nni->l2 = Duplicate_Scalar_Dbl(len2);
+  else                        Copy_Scalar_Dbl(len2,b_fcus->nni->l2);
+
+  if(b_fcus->nni->v0 == NULL) b_fcus->nni->v0 = Duplicate_Scalar_Dbl(var0);
+  else                        Copy_Scalar_Dbl(var0,b_fcus->nni->v0);
+
+  if(b_fcus->nni->v1 == NULL) b_fcus->nni->v1 = Duplicate_Scalar_Dbl(var1);
+  else                        Copy_Scalar_Dbl(var1,b_fcus->nni->v1);
+
+  if(b_fcus->nni->v2 == NULL) b_fcus->nni->v2 = Duplicate_Scalar_Dbl(var2);
+  else                        Copy_Scalar_Dbl(var2,b_fcus->nni->v2);
+
+
+  /* b = b_fcus; */
+  /* i = 0; */
+  /* do */
+  /*   { */
+  /*     b->nni->l0 = l0[i]; */
+  /*     b->nni->l1 = l1[i]; */
+  /*     b->nni->l2 = l2[i]; */
+  /*     b = b->next; */
+  /*     i++; */
+  /*   } */
+  /* while(b); */
 
   b_fcus->nni->score = lk0 - MAX(lk1,lk2);
 
@@ -1598,18 +1641,22 @@ void NNI(t_tree *tree, t_edge *b_fcus, int do_swap)
       b_fcus->nni->swap_node_v2 = NULL;
       b_fcus->nni->swap_node_v3 = NULL;
       b_fcus->nni->swap_node_v4 = NULL;
+      
+      if(b_fcus->nni->best_l == NULL) b_fcus->nni->best_l = Duplicate_Scalar_Dbl(len0);
+      else                            Copy_Scalar_Dbl(len0,b_fcus->nni->best_l);
 
-      b = b_fcus;
-      i = 0;
-      do
-    {
-      b->nni->best_l = l0[i];
-          b = b->next;
-      i++;
-    }
-      while(b);
-
-
+      if(b_fcus->nni->best_v == NULL) b_fcus->nni->best_v = Duplicate_Scalar_Dbl(var0);
+      else                            Copy_Scalar_Dbl(var0,b_fcus->nni->best_v);
+      
+      /* b = b_fcus; */
+      /* i = 0; */
+      /* do */
+      /*   { */
+      /*     b->nni->best_l = l0[i]; */
+      /*     b = b->next; */
+      /*     i++; */
+      /*   } */
+      /* while(b); */
     }
   else if(lk1 > MAX(lk0,lk2))
     {
@@ -1618,18 +1665,23 @@ void NNI(t_tree *tree, t_edge *b_fcus, int do_swap)
       b_fcus->nni->swap_node_v2 = b_fcus->left;
       b_fcus->nni->swap_node_v3 = b_fcus->rght;
       b_fcus->nni->swap_node_v4 = v3;
+      
+      if(b_fcus->nni->best_l == NULL) b_fcus->nni->best_l = Duplicate_Scalar_Dbl(len1);
+      else                            Copy_Scalar_Dbl(len1,b_fcus->nni->best_l);
 
-      b = b_fcus;
-      i = 0;
-      do
-    {
-      b->nni->best_l = l1[i];
-          b = b->next;
-      i++;
-    }
-      while(b);
+      if(b_fcus->nni->best_v == NULL) b_fcus->nni->best_v = Duplicate_Scalar_Dbl(var1);
+      else                            Copy_Scalar_Dbl(var1,b_fcus->nni->best_v);
 
 
+      /* b = b_fcus; */
+      /* i = 0; */
+      /* do */
+      /*   { */
+      /*     b->nni->best_l = l1[i]; */
+      /*     b = b->next; */
+      /*     i++; */
+      /*   } */
+      /* while(b); */
     }
   else if(lk2 > MAX(lk0,lk1))
     {
@@ -1639,18 +1691,22 @@ void NNI(t_tree *tree, t_edge *b_fcus, int do_swap)
       b_fcus->nni->swap_node_v3 = b_fcus->rght;
       b_fcus->nni->swap_node_v4 = v4;
 
-      b = b_fcus;
-      i = 0;
-      do
-    {
-      b->nni->best_l = l2[i];
-          b = b->next;
-      i++;
-    }
-      while(b);
+      if(b_fcus->nni->best_l == NULL) b_fcus->nni->best_l = Duplicate_Scalar_Dbl(len2);
+      else                            Copy_Scalar_Dbl(len2,b_fcus->nni->best_l);
 
+      if(b_fcus->nni->best_v == NULL) b_fcus->nni->best_v = Duplicate_Scalar_Dbl(var2);
+      else                            Copy_Scalar_Dbl(var2,b_fcus->nni->best_v);
 
 
+      /* b = b_fcus; */
+      /* i = 0; */
+      /* do */
+      /*   { */
+      /*     b->nni->best_l = l2[i]; */
+      /*     b = b->next; */
+      /*     i++; */
+      /*   } */
+      /* while(b); */
     }
   else
     {
@@ -1661,61 +1717,90 @@ void NNI(t_tree *tree, t_edge *b_fcus, int do_swap)
       b_fcus->nni->swap_node_v3 = NULL;
       b_fcus->nni->swap_node_v4 = NULL;
 
+      if(b_fcus->nni->best_l == NULL) b_fcus->nni->best_l = Duplicate_Scalar_Dbl(len0);
+      else                            Copy_Scalar_Dbl(len0,b_fcus->nni->best_l);
 
-      b = b_fcus;
-      i = 0;
-      do
-    {
-      b->nni->best_l = l0[i];
-          b = b->next;
-      i++;
-    }
-      while(b);
+      if(b_fcus->nni->best_v == NULL) b_fcus->nni->best_v = Duplicate_Scalar_Dbl(var0);
+      else                            Copy_Scalar_Dbl(var0,b_fcus->nni->best_v);
 
 
+      /* b = b_fcus; */
+      /* i = 0; */
+      /* do */
+      /*   { */
+      /*     b->nni->best_l = l0[i]; */
+      /*     b = b->next; */
+      /*     i++; */
+      /*   } */
+      /* while(b); */
     }
 
-  if((do_swap) && ((lk1 > lk0) || (lk2 > lk0)))
-    {
-      tree->n_swap++;
-      PhyML_Printf("\n. Swap t_edge %d -> %f",b_fcus->num,MAX(lk1,lk2));
 
-      if(lk1 > lk2)
+  if(do_swap == YES)
     {
-      tree->best_lnL = lk1;
-      Swap(v2,b_fcus->left,b_fcus->rght,v3,tree);
-
-      b = b_fcus;
-      i = 0;
-      do
+      if((lk1 > lk0) || (lk2 > lk0))
         {
-          b->l->v = l1[i];
-              b = b->next;
-          i++;
-        }
-      while(b);
+          tree->n_swap++;
 
-          Set_Both_Sides(YES,tree);
-      Lk(NULL,tree);
-    }
+          if(lk1 > lk2)
+            {
+              tree->best_lnL = lk1;
+              Swap(v2,b_fcus->left,b_fcus->rght,v3,tree);
+              
+              if(b_fcus->nni->best_l == NULL) b_fcus->nni->best_l = Duplicate_Scalar_Dbl(len1);
+              else                            Copy_Scalar_Dbl(len1,b_fcus->nni->best_l);
+              
+              if(b_fcus->nni->best_v == NULL) b_fcus->nni->best_v = Duplicate_Scalar_Dbl(var1);
+              else                            Copy_Scalar_Dbl(var1,b_fcus->nni->best_v);
+
+              /* Copy_Scalar_Dbl(len1,b_fcus->nni->best_l); */
+              /* Copy_Scalar_Dbl(var1,b_fcus->nni->best_v); */
+
+              /* b = b_fcus; */
+              /* i = 0; */
+              /* do */
+              /*   { */
+              /*     b->l->v = l1[i]; */
+              /*     b = b->next; */
+              /*     i++; */
+              /*   } */
+              /* while(b); */
+            }
+          else
+            {
+              tree->best_lnL = lk2;
+              Swap(v2,b_fcus->left,b_fcus->rght,v4,tree);
+              
+              if(b_fcus->nni->best_l == NULL) b_fcus->nni->best_l = Duplicate_Scalar_Dbl(len2);
+              else                            Copy_Scalar_Dbl(len2,b_fcus->nni->best_l);
+              
+              if(b_fcus->nni->best_v == NULL) b_fcus->nni->best_v = Duplicate_Scalar_Dbl(var2);
+              else                            Copy_Scalar_Dbl(var2,b_fcus->nni->best_v);
+
+              /* Copy_Scalar_Dbl(len2,b_fcus->nni->best_l); */
+              /* Copy_Scalar_Dbl(var2,b_fcus->nni->best_v); */
+
+              /* b = b_fcus; */
+              /* i = 0; */
+              /* do */
+              /*   { */
+              /*     b->l->v = l2[i]; */
+              /*     b = b->next; */
+              /*     i++; */
+              /*   } */
+              /* while(b); */
+            }
+          
+          Update_Lk_At_Given_Edge(b_fcus,tree);
+          /* Set_Both_Sides(YES,tree); */
+          /* Lk(NULL,tree); */
+        }
       else
-    {
-      tree->best_lnL = lk2;
-      Swap(v2,b_fcus->left,b_fcus->rght,v4,tree);
-
-      b = b_fcus;
-      i = 0;
-      do
         {
-          b->l->v = l2[i];
-              b = b->next;
-          i++;
+          tree->best_lnL = lk0;
+          // No change of topology done but length of central
+          // edge is optimal.
         }
-      while(b);
-
-          Set_Both_Sides(YES,tree);
-      Lk(NULL,tree);
-    }
     }
   else
     {
@@ -1724,9 +1809,13 @@ void NNI(t_tree *tree, t_edge *b_fcus, int do_swap)
       tree->c_lnL = lk_init;
     }
 
-  Free(l0);
-  Free(l1);
-  Free(l2);
+  Free_Scalar_Dbl(len0);
+  Free_Scalar_Dbl(len1);
+  Free_Scalar_Dbl(len2);
+  Free_Scalar_Dbl(var0);
+  Free_Scalar_Dbl(var1);
+  Free_Scalar_Dbl(var2);
+
 }
 
 //////////////////////////////////////////////////////////////
@@ -1834,9 +1923,9 @@ void Swap(t_node *a, t_node *b, t_node *c, t_node *d, t_tree *tree)
   /* \             /d      \             /a
    *  \           /         \           /
    *   \b__...__c/    ->     \b__...__c/
-   *   /         \	         /  		\
-   *  /           \	        /   	   	 \
-   * /a            \  	   /d             \
+   *   /         \	     /         \
+   *  /           \	    /   	\
+   * /a            \  	   /d            \
    *
    * nodes b and c are not necessarily on the same branch
    */
@@ -1848,20 +1937,22 @@ void Swap(t_node *a, t_node *b, t_node *c, t_node *d, t_tree *tree)
 #endif
 
   ab = ba = cd = dc = bc = -1;
-
+  
   For(i,3) if(a->v[i] == b) { ab = i; break; }
   For(i,3) if(b->v[i] == a) { ba = i; break; }
   For(i,3) if(c->v[i] == d) { cd = i; break; }
   For(i,3) if(d->v[i] == c) { dc = i; break; }
   For(i,3) if(b->v[i] == c) { bc = i; break; }
-
+  
 #ifdef DEBUG
   if(ab < 0 || ba < 0 || cd < 0 || dc < 0)
     {
-      PhyML_Printf("\n== Nodes %d %d %d %d\n",a->num,b->num,c->num,d->num);
+      PhyML_Printf("\n== Nodes %d %d %d %d.",a->num,b->num,c->num,d->num);
       Generic_Exit(__FILE__,__LINE__,__FUNCTION__);    
     }
 #endif
+  
+
 
   a->v[ab] = c;
   d->v[dc] = b;
@@ -1869,15 +1960,15 @@ void Swap(t_node *a, t_node *b, t_node *c, t_node *d, t_tree *tree)
   c->v[cd] = a;
   b->b[ba] = d->b[dc];
   c->b[cd] = a->b[ab];
-
+  
   (a->b[ab]->left == b)?
-  (a->b[ab]->left = c):
-  (a->b[ab]->rght = c);
-
+    (a->b[ab]->left = c):
+    (a->b[ab]->rght = c);
+  
   (d->b[dc]->left == c)?
-  (d->b[dc]->left = b):
-  (d->b[dc]->rght = b);
-
+    (d->b[dc]->left = b):
+    (d->b[dc]->rght = b);
+  
   For(i,3)
     {
       if(a->b[ab]->left->v[i] == a->b[ab]->rght) a->b[ab]->l_r = i;
@@ -1885,36 +1976,45 @@ void Swap(t_node *a, t_node *b, t_node *c, t_node *d, t_tree *tree)
       if(d->b[dc]->left->v[i] == d->b[dc]->rght) d->b[dc]->l_r = i;
       if(d->b[dc]->rght->v[i] == d->b[dc]->left) d->b[dc]->r_l = i;
     }
-
+  
   a->b[ab]->l_v1 = a->b[ab]->l_v2 =
-  a->b[ab]->r_v1 = a->b[ab]->r_v2 =
-  d->b[dc]->l_v1 = d->b[dc]->l_v2 =
-  d->b[dc]->r_v1 = d->b[dc]->r_v2 = -1;
-
+    a->b[ab]->r_v1 = a->b[ab]->r_v2 =
+    d->b[dc]->l_v1 = d->b[dc]->l_v2 =
+    d->b[dc]->r_v1 = d->b[dc]->r_v2 = -1;
+  
   For(i,3)
     {
       if(i != a->b[ab]->l_r)
-    {
-      if(a->b[ab]->l_v1 < 0) a->b[ab]->l_v1 = i;
-      else a->b[ab]->l_v2 = i;
-    }
+        {
+          if(a->b[ab]->l_v1 < 0) a->b[ab]->l_v1 = i;
+          else a->b[ab]->l_v2 = i;
+        }
       if(i != a->b[ab]->r_l)
-    {
-      if(a->b[ab]->r_v1 < 0) a->b[ab]->r_v1 = i;
-      else a->b[ab]->r_v2 = i;
-    }
+        {
+          if(a->b[ab]->r_v1 < 0) a->b[ab]->r_v1 = i;
+          else a->b[ab]->r_v2 = i;
+        }
       if(i != d->b[dc]->l_r)
-    {
-      if(d->b[dc]->l_v1 < 0) d->b[dc]->l_v1 = i;
-      else d->b[dc]->l_v2 = i;
-    }
+        {
+          if(d->b[dc]->l_v1 < 0) d->b[dc]->l_v1 = i;
+          else d->b[dc]->l_v2 = i;
+        }
       if(i != d->b[dc]->r_l)
-    {
-      if(d->b[dc]->r_v1 < 0) d->b[dc]->r_v1 = i;
-      else d->b[dc]->r_v2 = i;
-    }
+        {
+          if(d->b[dc]->r_v1 < 0) d->b[dc]->r_v1 = i;
+          else d->b[dc]->r_v2 = i;
+        }
     }
+
   Update_Dirs(tree);
+  
+  if(tree->n_root != NULL)
+    {
+      tree->n_root->v[1] = tree->e_root->left;
+      tree->n_root->v[2] = tree->e_root->rght;
+      tree->n_root->b[1]->rght = tree->e_root->left;
+      tree->n_root->b[2]->rght = tree->e_root->rght;
+    }
 
   if(tree->next)
     Swap(a->next,b->next,c->next,d->next,tree->next);
@@ -1992,7 +2092,6 @@ calign *Copy_Cseq(calign *ori, option *io)
   n_otu = ori->n_otu;
   c_len = ori->crunch_len;
 
-
   sp_names = (char **)mCalloc(n_otu,sizeof(char *));
   For(i,n_otu)
     {
@@ -2000,7 +2099,8 @@ calign *Copy_Cseq(calign *ori, option *io)
       strcpy(sp_names[i],ori->c_seq[i]->name);
     }
 
-  new = Make_Cseq(n_otu,c_len+1,io->state_len,ori->init_len,sp_names);
+  new = Make_Calign(n_otu,c_len+1,io->state_len,ori->init_len,sp_names);
+  Init_Calign(n_otu,c_len+1,ori->init_len,new);
 
   new->obs_pinvar = ori->obs_pinvar;
 
@@ -2834,15 +2934,16 @@ void Bootstrap(t_tree *tree)
           boot_tree->mat = boot_mat;
         }
 
-      boot_tree->mod                = boot_mod;
-      boot_tree->io                 = tree->io;
-      boot_tree->data               = boot_data;
-      boot_tree->mod->s_opt->print  = NO;
-      boot_tree->n_pattern          = boot_tree->data->crunch_len;
-      boot_tree->io->print_site_lnl = 0;
-      boot_tree->io->print_trace    = 0;
-      boot_tree->n_root             = NULL;
-      boot_tree->e_root             = NULL;
+      boot_tree->mod                  = boot_mod;
+      boot_tree->io                   = tree->io;
+      boot_tree->data                 = boot_data;
+      boot_tree->mod->s_opt->print    = NO;
+      boot_tree->n_pattern            = boot_tree->data->crunch_len;
+      boot_tree->io->print_site_lnl   = NO;
+      boot_tree->io->print_trace      = NO;
+      boot_tree->io->print_json_trace = NO;
+      boot_tree->n_root               = NULL;
+      boot_tree->e_root               = NULL;
 
 
       Set_Both_Sides(YES,boot_tree);
@@ -2855,7 +2956,6 @@ void Bootstrap(t_tree *tree)
       Share_Lk_Struct(tree,boot_tree);
       Share_Spr_Struct(tree,boot_tree);
       Share_Pars_Struct(tree,boot_tree);
-      Fill_Dir_Table(boot_tree);
       Update_Dirs(boot_tree);
 
       if(tree->mod->s_opt->greedy) Init_P_Lk_Tips_Double(boot_tree);
@@ -2944,7 +3044,7 @@ void Bootstrap(t_tree *tree)
       fclose(tree->io->fp_out_boot_stats);
     }
 
-  Free_Cseq(boot_data);
+  Free_Calign(boot_data);
   Free(site_num);
 }
 
@@ -3414,7 +3514,7 @@ void Record_Model(t_mod *ori, t_mod *cpy)
     {
       cpy->e_frq->pi->v[i]          = ori->e_frq->pi->v[i];
       cpy->e_frq->pi_unscaled->v[i] = ori->e_frq->pi_unscaled->v[i];
-      cpy->user_b_freq->v[i] = ori->user_b_freq->v[i];
+      cpy->e_frq->user_b_freq->v[i] = ori->e_frq->user_b_freq->v[i];
     }
   
   For(i,cpy->ns*cpy->ns) cpy->r_mat->qmat->v[i] = ori->r_mat->qmat->v[i];
@@ -3473,7 +3573,6 @@ void Test_Node_Table_Consistency(t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Get_Bip(t_node *a, t_node *d, t_tree *tree)
 {
   int i,j;
@@ -4518,8 +4617,8 @@ void Copy_Tree(t_tree *ori, t_tree *cpy)
       cpy->a_edges[i]->l_old->v         = ori->a_edges[i]->l_old->v;
       cpy->a_edges[i]->l_var->v         = ori->a_edges[i]->l_var->v;
       cpy->a_edges[i]->l_var_old->v     = ori->a_edges[i]->l_var_old->v;
-      cpy->a_edges[i]->left             = cpy->a_nodes[ori->a_edges[i]->left->num];
-      cpy->a_edges[i]->rght             = cpy->a_nodes[ori->a_edges[i]->rght->num];
+      cpy->a_edges[i]->left             = ori->a_edges[i]->left ? cpy->a_nodes[ori->a_edges[i]->left->num] : NULL;
+      cpy->a_edges[i]->rght             = ori->a_edges[i]->rght ? cpy->a_nodes[ori->a_edges[i]->rght->num] : NULL;
       cpy->a_edges[i]->l_v1             = ori->a_edges[i]->l_v1;
       cpy->a_edges[i]->l_v2             = ori->a_edges[i]->l_v2;
       cpy->a_edges[i]->r_v1             = ori->a_edges[i]->r_v1;
@@ -4535,8 +4634,6 @@ void Copy_Tree(t_tree *ori, t_tree *cpy)
     }
 
 
-
-
   For(i,ori->n_otu)
     {
       cpy->a_nodes[i]->tax = YES;
@@ -4589,7 +4686,6 @@ void Prune_Subtree(t_node *a, t_node *d, t_edge **target, t_edge **residual, t_t
   t_edge *b1, *b2;
   int dir_v1, dir_v2;
   int i;
-/*   phydbl ***buff_p_lk; */
   phydbl *buff_p_lk;
   int *buff_scale;
   int *buff_p_pars, *buff_pars, *buff_p_lk_loc, *buff_patt_id;
@@ -4622,9 +4718,8 @@ void Prune_Subtree(t_node *a, t_node *d, t_edge **target, t_edge **residual, t_t
       b1 = a->b[dir_v2];
       b2 = a->b[dir_v1];
     }
-  assert(NULL != b1 && NULL != b2);
 
-  /* if(v1->tax && v2->tax) PhyML_Printf("\n. Pruning is meaningless here.\n"); */
+  assert(NULL != b1 && NULL != b2);
 
   a->v[dir_v1] = NULL;
   a->v[dir_v2] = NULL;
@@ -4641,180 +4736,189 @@ void Prune_Subtree(t_node *a, t_node *d, t_edge **target, t_edge **residual, t_t
 
       if(v2 == b2->left)
         {
-          buff_p_lk            = b1->p_lk_rght;
-          b1->p_lk_rght        = b2->p_lk_left;
-          b2->p_lk_left        = buff_p_lk;
-
-          buff_p_lk_tip        = b1->p_lk_tip_r;
-          b1->p_lk_tip_r       = b2->p_lk_tip_l;
-          b2->p_lk_tip_l       = buff_p_lk_tip;
-
+          if(tree->is_mixt_tree == NO)
+            {
+              buff_p_lk            = b1->p_lk_rght;
+              b1->p_lk_rght        = b2->p_lk_left;
+              b2->p_lk_left        = buff_p_lk;
+              
+              buff_p_lk_tip        = b1->p_lk_tip_r;
+              b1->p_lk_tip_r       = b2->p_lk_tip_l;
+              b2->p_lk_tip_l       = buff_p_lk_tip;
+              
 #ifdef BEAGLE
-          temp                 = b1->p_lk_rght_idx;
-          b1->p_lk_rght_idx    = b2->p_lk_left_idx;
-          b2->p_lk_left_idx    = temp;
+              temp                 = b1->p_lk_rght_idx;
+              b1->p_lk_rght_idx    = b2->p_lk_left_idx;
+              b2->p_lk_left_idx    = temp;
 #endif
-          buff_scale           = b1->sum_scale_rght;
-          b1->sum_scale_rght   = b2->sum_scale_left;
-          b2->sum_scale_left   = buff_scale;
-
-          buff_scale             = b1->sum_scale_rght_cat;
-          b1->sum_scale_rght_cat = b2->sum_scale_left_cat;
-          b2->sum_scale_left_cat = buff_scale;
-
-          buff_pars            = b1->pars_r;
-          b1->pars_r           = b2->pars_l;
-          b2->pars_l           = buff_pars;
-
-          buff_ui              = b1->ui_r;
-          b1->ui_r             = b2->ui_l;
-          b2->ui_l             = buff_ui;
-
-          buff_p_pars          = b1->p_pars_r;
-          b1->p_pars_r         = b2->p_pars_l;
-          b2->p_pars_l         = buff_p_pars;
-
-          buff_p_lk_loc        = b1->p_lk_loc_rght;
-          b1->p_lk_loc_rght    = b2->p_lk_loc_left;
-          b2->p_lk_loc_left    = buff_p_lk_loc;
-
-          buff_patt_id         = b1->patt_id_rght;
-          b1->patt_id_rght     = b2->patt_id_left;
-          b2->patt_id_left     = buff_patt_id;
-
+              buff_scale           = b1->sum_scale_rght;
+              b1->sum_scale_rght   = b2->sum_scale_left;
+              b2->sum_scale_left   = buff_scale;
+              
+              buff_scale             = b1->sum_scale_rght_cat;
+              b1->sum_scale_rght_cat = b2->sum_scale_left_cat;
+              b2->sum_scale_left_cat = buff_scale;
+              
+              buff_pars            = b1->pars_r;
+              b1->pars_r           = b2->pars_l;
+              b2->pars_l           = buff_pars;
+              
+              buff_ui              = b1->ui_r;
+              b1->ui_r             = b2->ui_l;
+              b2->ui_l             = buff_ui;
+              
+              buff_p_pars          = b1->p_pars_r;
+              b1->p_pars_r         = b2->p_pars_l;
+              b2->p_pars_l         = buff_p_pars;
+              
+              buff_p_lk_loc        = b1->p_lk_loc_rght;
+              b1->p_lk_loc_rght    = b2->p_lk_loc_left;
+              b2->p_lk_loc_left    = buff_p_lk_loc;
+              
+              buff_patt_id         = b1->patt_id_rght;
+              b1->patt_id_rght     = b2->patt_id_left;
+              b2->patt_id_left     = buff_patt_id;
+            }
         }
       else
         {
-          buff_p_lk            = b1->p_lk_rght; /* b1->p_lk_rght = NULL if b1->rght->tax */
-          b1->p_lk_rght        = b2->p_lk_rght; /* b2->p_lk_rght = NULL if b2->rght->tax */
-          b2->p_lk_rght        = buff_p_lk;
-
-          buff_p_lk_tip        = b1->p_lk_tip_r;
-          b1->p_lk_tip_r       = b2->p_lk_tip_r;
-          b2->p_lk_tip_r       = buff_p_lk_tip;
+          if(tree->is_mixt_tree == NO)
+            {
+              buff_p_lk            = b1->p_lk_rght; /* b1->p_lk_rght = NULL if b1->rght->tax */
+              b1->p_lk_rght        = b2->p_lk_rght; /* b2->p_lk_rght = NULL if b2->rght->tax */
+              b2->p_lk_rght        = buff_p_lk;
+              
+              buff_p_lk_tip        = b1->p_lk_tip_r;
+              b1->p_lk_tip_r       = b2->p_lk_tip_r;
+              b2->p_lk_tip_r       = buff_p_lk_tip;
 #ifdef BEAGLE
-          temp                 = b1->p_lk_rght_idx;
-          b1->p_lk_rght_idx    = b2->p_lk_rght_idx;
-          b2->p_lk_rght_idx    = temp;
-
-          b2->p_lk_tip_idx     = b1->p_lk_tip_idx;
+              temp                 = b1->p_lk_rght_idx;
+              b1->p_lk_rght_idx    = b2->p_lk_rght_idx;
+              b2->p_lk_rght_idx    = temp;
+              
+              b2->p_lk_tip_idx     = b1->p_lk_tip_idx;
 #endif
-          buff_scale           = b1->sum_scale_rght;
-          b1->sum_scale_rght   = b2->sum_scale_rght;
-          b2->sum_scale_rght   = buff_scale;
-
-          buff_pars            = b1->pars_r;
-          b1->pars_r           = b2->pars_r;
-          b2->pars_r           = buff_pars;
-
-          buff_ui              = b1->ui_r;
-          b1->ui_r             = b2->ui_r;
-          b2->ui_r             = buff_ui;
-
-          buff_p_pars          = b1->p_pars_r;
-          b1->p_pars_r         = b2->p_pars_r;
-          b2->p_pars_r         = buff_p_pars;
-
-          buff_p_lk_loc        = b1->p_lk_loc_rght;
-          b1->p_lk_loc_rght    = b2->p_lk_loc_rght;
-          b2->p_lk_loc_rght    = buff_p_lk_loc;
-
-          buff_patt_id         = b1->patt_id_rght;
-          b1->patt_id_rght     = b2->patt_id_rght;
-          b2->patt_id_rght     = buff_patt_id;
-
-        }
-    }
-  else
-    {
-      b1->left = v2;
+              buff_scale           = b1->sum_scale_rght;
+              b1->sum_scale_rght   = b2->sum_scale_rght;
+              b2->sum_scale_rght   = buff_scale;
+              
+              buff_pars            = b1->pars_r;
+              b1->pars_r           = b2->pars_r;
+              b2->pars_r           = buff_pars;
+              
+              buff_ui              = b1->ui_r;
+              b1->ui_r             = b2->ui_r;
+              b2->ui_r             = buff_ui;
+              
+              buff_p_pars          = b1->p_pars_r;
+              b1->p_pars_r         = b2->p_pars_r;
+              b2->p_pars_r         = buff_p_pars;
+              
+              buff_p_lk_loc        = b1->p_lk_loc_rght;
+              b1->p_lk_loc_rght    = b2->p_lk_loc_rght;
+              b2->p_lk_loc_rght    = buff_p_lk_loc;
+              
+              buff_patt_id         = b1->patt_id_rght;
+              b1->patt_id_rght     = b2->patt_id_rght;
+              b2->patt_id_rght     = buff_patt_id;
+            }
+        }
+    }
+  else
+    {
+      b1->left = v2;
 
       if(v2 == b2->left)
         {
-          buff_p_lk            = b1->p_lk_left;
-          b1->p_lk_left        = b2->p_lk_left;
-          b2->p_lk_left        = buff_p_lk;
-
-          buff_p_lk_tip        = b1->p_lk_tip_l;
-          b1->p_lk_tip_l       = b2->p_lk_tip_l;
-          b2->p_lk_tip_l       = buff_p_lk_tip;
+          if(tree->is_mixt_tree == NO)
+            {
+              buff_p_lk            = b1->p_lk_left;
+              b1->p_lk_left        = b2->p_lk_left;
+              b2->p_lk_left        = buff_p_lk;
+              
+              buff_p_lk_tip        = b1->p_lk_tip_l;
+              b1->p_lk_tip_l       = b2->p_lk_tip_l;
+              b2->p_lk_tip_l       = buff_p_lk_tip;
 #ifdef BEAGLE
-          temp                 = b1->p_lk_left_idx;
-          b1->p_lk_left_idx    = b2->p_lk_left_idx;
-          b2->p_lk_left_idx    = temp;
+              temp                 = b1->p_lk_left_idx;
+              b1->p_lk_left_idx    = b2->p_lk_left_idx;
+              b2->p_lk_left_idx    = temp;
 #endif
-          buff_scale           = b1->sum_scale_left;
-          b1->sum_scale_left   = b2->sum_scale_left;
-          b2->sum_scale_left   = buff_scale;
-
-          buff_scale             = b1->sum_scale_left_cat;
-          b1->sum_scale_left_cat = b2->sum_scale_left_cat;
-          b2->sum_scale_left_cat = buff_scale;
-
-          buff_pars            = b1->pars_l;
-          b1->pars_l           = b2->pars_l;
-          b2->pars_l           = buff_pars;
-
-          buff_ui              = b1->ui_l;
-          b1->ui_l             = b2->ui_l;
-          b2->ui_l             = buff_ui;
-
-          buff_p_pars          = b1->p_pars_l;
-          b1->p_pars_l         = b2->p_pars_l;
-          b2->p_pars_l         = buff_p_pars;
-
-          buff_p_lk_loc        = b1->p_lk_loc_left;
-          b1->p_lk_loc_left    = b2->p_lk_loc_left;
-          b2->p_lk_loc_left    = buff_p_lk_loc;
-
-          buff_patt_id         = b1->patt_id_left;
-          b1->patt_id_left     = b2->patt_id_left;
-          b2->patt_id_left     = buff_patt_id;
-
+              buff_scale           = b1->sum_scale_left;
+              b1->sum_scale_left   = b2->sum_scale_left;
+              b2->sum_scale_left   = buff_scale;
+              
+              buff_scale             = b1->sum_scale_left_cat;
+              b1->sum_scale_left_cat = b2->sum_scale_left_cat;
+              b2->sum_scale_left_cat = buff_scale;
+              
+              buff_pars            = b1->pars_l;
+              b1->pars_l           = b2->pars_l;
+              b2->pars_l           = buff_pars;
+              
+              buff_ui              = b1->ui_l;
+              b1->ui_l             = b2->ui_l;
+              b2->ui_l             = buff_ui;
+              
+              buff_p_pars          = b1->p_pars_l;
+              b1->p_pars_l         = b2->p_pars_l;
+              b2->p_pars_l         = buff_p_pars;
+              
+              buff_p_lk_loc        = b1->p_lk_loc_left;
+              b1->p_lk_loc_left    = b2->p_lk_loc_left;
+              b2->p_lk_loc_left    = buff_p_lk_loc;
+              
+              buff_patt_id         = b1->patt_id_left;
+              b1->patt_id_left     = b2->patt_id_left;
+              b2->patt_id_left     = buff_patt_id;
+            }
         }
       else
         {
-          buff_p_lk            = b1->p_lk_left;
-          b1->p_lk_left        = b2->p_lk_rght; /* b2->p_lk_rght = NULL if b2->rght->tax */
-          b2->p_lk_rght        = buff_p_lk;
-
-          buff_p_lk_tip        = b1->p_lk_tip_l;
-          b1->p_lk_tip_l       = b2->p_lk_tip_r;
-          b2->p_lk_tip_r       = buff_p_lk_tip;
+          if(tree->is_mixt_tree == NO)
+            {
+              buff_p_lk            = b1->p_lk_left;
+              b1->p_lk_left        = b2->p_lk_rght; /* b2->p_lk_rght = NULL if b2->rght->tax */
+              b2->p_lk_rght        = buff_p_lk;
+              
+              buff_p_lk_tip        = b1->p_lk_tip_l;
+              b1->p_lk_tip_l       = b2->p_lk_tip_r;
+              b2->p_lk_tip_r       = buff_p_lk_tip;
 #ifdef BEAGLE
-          temp                 = b1->p_lk_left_idx;
-          b1->p_lk_left_idx    = b2->p_lk_rght_idx;
-          b2->p_lk_rght_idx    = temp;
-
-          b2->p_lk_tip_idx     = b1->p_lk_tip_idx;
+              temp                 = b1->p_lk_left_idx;
+              b1->p_lk_left_idx    = b2->p_lk_rght_idx;
+              b2->p_lk_rght_idx    = temp;
+              
+              b2->p_lk_tip_idx     = b1->p_lk_tip_idx;
 #endif
-          buff_scale           = b1->sum_scale_left;
-          b1->sum_scale_left   = b2->sum_scale_rght;
-          b2->sum_scale_rght   = buff_scale;
-
-          buff_scale             = b1->sum_scale_left_cat;
-          b1->sum_scale_left_cat = b2->sum_scale_rght_cat;
-          b2->sum_scale_rght_cat = buff_scale;
-
-          buff_pars            = b1->pars_l;
-          b1->pars_l           = b2->pars_r;
-          b2->pars_r           = buff_pars;
-
-          buff_ui              = b1->ui_l;
-          b1->ui_l             = b2->ui_r;
-          b2->ui_r             = buff_ui;
-
-          buff_p_pars          = b1->p_pars_l;
-          b1->p_pars_l         = b2->p_pars_r;
-          b2->p_pars_r         = buff_p_pars;
-
-          buff_p_lk_loc        = b1->p_lk_loc_left;
-          b1->p_lk_loc_left    = b2->p_lk_loc_rght;
-          b2->p_lk_loc_rght    = buff_p_lk_loc;
-
-          buff_patt_id         = b1->patt_id_left;
-          b1->patt_id_left     = b2->patt_id_rght;
-          b2->patt_id_rght     = buff_patt_id;
+              buff_scale           = b1->sum_scale_left;
+              b1->sum_scale_left   = b2->sum_scale_rght;
+              b2->sum_scale_rght   = buff_scale;
+              
+              buff_scale             = b1->sum_scale_left_cat;
+              b1->sum_scale_left_cat = b2->sum_scale_rght_cat;
+              b2->sum_scale_rght_cat = buff_scale;
+              
+              buff_pars            = b1->pars_l;
+              b1->pars_l           = b2->pars_r;
+              b2->pars_r           = buff_pars;
+              
+              buff_ui              = b1->ui_l;
+              b1->ui_l             = b2->ui_r;
+              b2->ui_r             = buff_ui;
+              
+              buff_p_pars          = b1->p_pars_l;
+              b1->p_pars_l         = b2->p_pars_r;
+              b2->p_pars_r         = buff_p_pars;
+              
+              buff_p_lk_loc        = b1->p_lk_loc_left;
+              b1->p_lk_loc_left    = b2->p_lk_loc_rght;
+              b2->p_lk_loc_rght    = buff_p_lk_loc;
+              
+              buff_patt_id         = b1->patt_id_left;
+              b1->patt_id_left     = b2->patt_id_rght;
+              b2->patt_id_rght     = buff_patt_id;
+            }
         }
     }
 
@@ -4837,8 +4941,8 @@ void Prune_Subtree(t_node *a, t_node *d, t_edge **target, t_edge **residual, t_t
   For(i,3)
     if(v1->v[i] == a)
       {
-    v1->v[i] = v2;
-    break;
+        v1->v[i] = v2;
+        break;
       }
 
 #ifdef DEBUG
@@ -4851,7 +4955,8 @@ void Prune_Subtree(t_node *a, t_node *d, t_edge **target, t_edge **residual, t_t
 
   if(b1->l->onoff == ON)
     {
-      b1->l->v += b2->l->v;
+      b1->l->v     += b2->l->v;
+      b1->l_var->v += b2->l_var->v;
     }
 
   (v1 == b1->left)?
@@ -4862,31 +4967,28 @@ void Prune_Subtree(t_node *a, t_node *d, t_edge **target, t_edge **residual, t_t
   if(residual) (*residual) = b2;
 
 
-  if(tree->n_root)
+  if(tree->n_root && tree->n_root->v[1] == a) tree->n_root->v[1] = NULL;
+  if(tree->n_root && tree->n_root->v[2] == a) tree->n_root->v[2] = NULL;
+
+  if((*target) == tree->e_root)
     {
-      if(tree->n_root->v[1] == a) tree->n_root->v[1] = NULL;
-      if(tree->n_root->v[2] == a) tree->n_root->v[2] = NULL;
+      tree->n_root->v[1]       = (*target)->left;
+      tree->n_root->v[2]       = (*target)->rght;
+      tree->n_root->b[1]->rght = (*target)->left;
+      tree->n_root->b[2]->rght = (*target)->rght;
     }
 
-  /* if(tree->n_root) */
-  /*   { */
-  /*     tree->n_root->v[1]       = tree->e_root->left; */
-  /*     tree->n_root->v[2]       = tree->e_root->rght; */
-  /*     tree->n_root->b[1]->rght = tree->e_root->left; */
-  /*     tree->n_root->b[2]->rght = tree->e_root->rght; */
-  /*   } */
 
 #ifdef DEBUG
   if(b1->left->tax == YES && b1->rght->tax == NO)
     {
       PhyML_Printf("\n== b1->left->num = %d",b1->left->num);
-      PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__);
+      PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__);
       Warn_And_Exit("");
     }
 #endif
 
   if(tree->is_mixt_tree == YES) MIXT_Prune_Subtree(a,d,target,residual,tree);
-
 }
 
 //////////////////////////////////////////////////////////////
@@ -4926,96 +5028,106 @@ void Graft_Subtree(t_edge *target, t_node *link, t_edge *residual, t_tree *tree)
       v1                           = target->left;
       v2                           = target->rght;
 
-      buff_p_lk                    = residual->p_lk_rght;
-      residual->p_lk_rght          = target->p_lk_rght;
-      target->p_lk_rght            = buff_p_lk;
-
-      buff_p_lk_tip                = residual->p_lk_tip_r;
-      residual->p_lk_tip_r         = target->p_lk_tip_r;
-      target->p_lk_tip_r           = buff_p_lk_tip;
-
+      if(tree->is_mixt_tree == NO)
+        {
+          buff_p_lk                    = residual->p_lk_rght;
+          residual->p_lk_rght          = target->p_lk_rght;
+          target->p_lk_rght            = buff_p_lk;
+          
+          buff_p_lk_tip                = residual->p_lk_tip_r;
+          residual->p_lk_tip_r         = target->p_lk_tip_r;
+          target->p_lk_tip_r           = buff_p_lk_tip;
+          
 #ifdef BEAGLE
-      temp                         = residual->p_lk_rght_idx;
-      residual->p_lk_rght_idx      = target->p_lk_rght_idx;
-      target->p_lk_rght_idx        = temp;
-
-      temp                         = residual->p_lk_tip_idx;
-      residual->p_lk_tip_idx       = target->p_lk_tip_idx;
-      target->p_lk_tip_idx         = temp;
+          temp                         = residual->p_lk_rght_idx;
+          residual->p_lk_rght_idx      = target->p_lk_rght_idx;
+          target->p_lk_rght_idx        = temp;
+          
+          temp                         = residual->p_lk_tip_idx;
+          residual->p_lk_tip_idx       = target->p_lk_tip_idx;
+          target->p_lk_tip_idx         = temp;
 #endif
+          
+          buff_scale                   = residual->sum_scale_rght;
+          residual->sum_scale_rght     = target->sum_scale_rght;
+          target->sum_scale_rght       = buff_scale;
+          
+          buff_scale                   = residual->sum_scale_rght_cat;
+          residual->sum_scale_rght_cat = target->sum_scale_rght_cat;
+          target->sum_scale_rght_cat   = buff_scale;
 
-      buff_scale                   = residual->sum_scale_rght;
-      residual->sum_scale_rght     = target->sum_scale_rght;
-      target->sum_scale_rght       = buff_scale;
-
-      buff_pars                    = residual->pars_r;
-      residual->pars_r             = target->pars_r;
-      target->pars_r               = buff_pars;
-
-      buff_ui                      = residual->ui_r;
-      residual->ui_r               = target->ui_r;
-      target->ui_r                 = buff_ui;
-
-      buff_p_pars                  = residual->p_pars_r;
-      residual->p_pars_r           = target->p_pars_r;
-      target->p_pars_r             = buff_p_pars;
-
-      buff_p_lk_loc                = residual->p_lk_loc_rght;
-      residual->p_lk_loc_rght      = target->p_lk_loc_rght;
-      target->p_lk_loc_rght        = buff_p_lk_loc;
-
-      buff_patt_id                 = residual->patt_id_rght;
-      residual->patt_id_rght       = target->patt_id_rght;
-      target->patt_id_rght         = buff_patt_id;
+          buff_pars                    = residual->pars_r;
+          residual->pars_r             = target->pars_r;
+          target->pars_r               = buff_pars;
+          
+          buff_ui                      = residual->ui_r;
+          residual->ui_r               = target->ui_r;
+          target->ui_r                 = buff_ui;
+          
+          buff_p_pars                  = residual->p_pars_r;
+          residual->p_pars_r           = target->p_pars_r;
+          target->p_pars_r             = buff_p_pars;
+          
+          buff_p_lk_loc                = residual->p_lk_loc_rght;
+          residual->p_lk_loc_rght      = target->p_lk_loc_rght;
+          target->p_lk_loc_rght        = buff_p_lk_loc;
+          
+          buff_patt_id                 = residual->patt_id_rght;
+          residual->patt_id_rght       = target->patt_id_rght;
+          target->patt_id_rght         = buff_patt_id;
+        }
     }
   else
     {
       v1                           = target->rght;
       v2                           = target->left;
 
-      buff_p_lk                    = residual->p_lk_rght;
-      residual->p_lk_rght          = target->p_lk_left;
-      target->p_lk_left            = buff_p_lk;
-
-      buff_p_lk_tip                = residual->p_lk_tip_r;
-      residual->p_lk_tip_r         = target->p_lk_tip_l;
-      target->p_lk_tip_l           = buff_p_lk_tip;
-
+      if(tree->is_mixt_tree == NO)
+        {
+          buff_p_lk                    = residual->p_lk_rght;
+          residual->p_lk_rght          = target->p_lk_left;
+          target->p_lk_left            = buff_p_lk;
+          
+          buff_p_lk_tip                = residual->p_lk_tip_r;
+          residual->p_lk_tip_r         = target->p_lk_tip_l;
+          target->p_lk_tip_l           = buff_p_lk_tip;
+          
 #ifdef BEAGLE
-      temp                         = residual->p_lk_rght_idx;
-      residual->p_lk_rght_idx      = target->p_lk_left_idx;
-      target->p_lk_left_idx        = temp;
+          temp                         = residual->p_lk_rght_idx;
+          residual->p_lk_rght_idx      = target->p_lk_left_idx;
+          target->p_lk_left_idx        = temp;
 #endif
-
-      buff_scale                   = residual->sum_scale_rght;
-      residual->sum_scale_rght     = target->sum_scale_left;
-      target->sum_scale_left       = buff_scale;
-
-      buff_scale                   = residual->sum_scale_rght_cat;
-      residual->sum_scale_rght_cat = target->sum_scale_left_cat;
-      target->sum_scale_left_cat   = buff_scale;
-
-      buff_pars                    = residual->pars_r;
-      residual->pars_r             = target->pars_l;
-      target->pars_l               = buff_pars;
-
-      buff_ui                      = residual->ui_r;
-      residual->ui_r               = target->ui_l;
-      target->ui_l                 = buff_ui;
-
-      buff_p_pars                  = residual->p_pars_r;
-      residual->p_pars_r           = target->p_pars_l;
-      target->p_pars_l             = buff_p_pars;
-
-      buff_p_lk_loc                = residual->p_lk_loc_rght;
-      residual->p_lk_loc_rght      = target->p_lk_loc_left;
-      target->p_lk_loc_left        = buff_p_lk_loc;
-
-      buff_patt_id                 = residual->patt_id_rght;
-      residual->patt_id_rght       = target->patt_id_left;
-      target->patt_id_left         = buff_patt_id;
+          
+          buff_scale                   = residual->sum_scale_rght;
+          residual->sum_scale_rght     = target->sum_scale_left;
+          target->sum_scale_left       = buff_scale;
+          
+          buff_scale                   = residual->sum_scale_rght_cat;
+          residual->sum_scale_rght_cat = target->sum_scale_left_cat;
+          target->sum_scale_left_cat   = buff_scale;
+          
+          buff_pars                    = residual->pars_r;
+          residual->pars_r             = target->pars_l;
+          target->pars_l               = buff_pars;
+          
+          buff_ui                      = residual->ui_r;
+          residual->ui_r               = target->ui_l;
+          target->ui_l                 = buff_ui;
+          
+          buff_p_pars                  = residual->p_pars_r;
+          residual->p_pars_r           = target->p_pars_l;
+          target->p_pars_l             = buff_p_pars;
+          
+          buff_p_lk_loc                = residual->p_lk_loc_rght;
+          residual->p_lk_loc_rght      = target->p_lk_loc_left;
+          target->p_lk_loc_left        = buff_p_lk_loc;
+          
+          buff_patt_id                 = residual->patt_id_rght;
+          residual->patt_id_rght       = target->patt_id_left;
+          target->patt_id_left         = buff_patt_id;
+        }
     }
-
+  
 
   For(i,3)
     if(v2->b[i] == target)
@@ -5048,23 +5160,37 @@ void Graft_Subtree(t_edge *target, t_node *link, t_edge *residual, t_tree *tree)
       }
 
   if(target->l->onoff == ON)
-    target->l->v /= 2.;
+    {
+      target->l->v     /= 2.;
+      target->l_var->v /= 2.;
+    }
 
   if(residual->l->onoff == ON)
-    residual->l->v = target->l->v;
+    {
+      residual->l->v     = target->l->v;
+      residual->l_var->v = target->l_var->v;
+    }
 
   Set_Edge_Dirs(target,target->left,target->rght,tree);
   Set_Edge_Dirs(residual,residual->left,residual->rght,tree);
   Set_Edge_Dirs(b_up,b_up->left,b_up->rght,tree);
 
-  /* if(tree->n_root) */
-  /*   { */
-  /*     tree->n_root->v[1]       = tree->e_root->left; */
-  /*     tree->n_root->v[2]       = tree->e_root->rght; */
-  /*     tree->n_root->b[1]->rght = tree->e_root->left; */
-  /*     tree->n_root->b[2]->rght = tree->e_root->rght; */
-  /*   } */
 
+  if(tree->n_root && b_up == tree->e_root)
+    {
+      assert((tree->n_root->v[1] == NULL && tree->n_root->v[2] != NULL) ||
+             (tree->n_root->v[1] != NULL && tree->n_root->v[2] == NULL));
+      if(tree->n_root->v[1] == NULL) tree->n_root->v[1] = link;      
+      if(tree->n_root->v[2] == NULL) tree->n_root->v[2] = link;      
+    }
+
+  if(target == tree->e_root)
+    {
+      tree->n_root->v[1]       = target->left;
+      tree->n_root->v[2]       = target->rght;
+      tree->n_root->b[1]->rght = target->left;
+      tree->n_root->b[2]->rght = target->rght;
+    }
 
   if(tree->is_mixt_tree == YES) MIXT_Graft_Subtree(target,link,residual,tree);
 
@@ -5132,7 +5258,7 @@ void Reassign_Edge_Nums(t_node *a, t_node *d, int *curr_br, t_tree *tree)
         For(j,2*N_MAX_OTU-3) if(tree->a_edges[j] == a->b[i]) break;
         if(j == 2*N_MAX_OTU-3)
           {
-            PhyML_Printf("\n. Err. in file %s at line %d (function '%s').\n",__FILE__,__LINE__,__FUNCTION__);
+            PhyML_Printf("\n== Err. in file %s at line %d (function '%s').\n",__FILE__,__LINE__,__FUNCTION__);
             Exit("\n");
           }
         tree->a_edges[*curr_br] = a->b[i];
@@ -5154,12 +5280,11 @@ void Reassign_Edge_Nums(t_node *a, t_node *d, int *curr_br, t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Find_Mutual_Direction(t_node *n1, t_node *n2, short int *dir_n1_to_n2, short int *dir_n2_to_n1)
 {
   int scores[3][3];
   int i,j,k,l;
-
+  
   if(n1 == n2) return;
 
 
@@ -5228,7 +5353,6 @@ void Find_Mutual_Direction(t_node *n1, t_node *n2, short int *dir_n1_to_n2, shor
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Update_Dir_To_Tips(t_node *a, t_node *d, t_tree *tree)
 {
   int i,j,k;
@@ -5239,43 +5363,39 @@ void Update_Dir_To_Tips(t_node *a, t_node *d, t_tree *tree)
   dim = 2*tree->n_otu-2;
 
   inout = (short int *)mCalloc(tree->n_otu,sizeof(short int));
-
+  
   For(i,3)
     {
       if(a->v[i] == d)
-    {
-      For(j,tree->n_otu) inout[j] = 1;
-      For(k,a->bip_size[i]) inout[a->bip_node[i][k]->num] = 0;
-      For(j,tree->n_otu) if(inout[tree->a_nodes[j]->num]) tree->t_dir[a->num*dim+tree->a_nodes[j]->num] = i;
-      break;
-    }
+        {
+          For(j,tree->n_otu) inout[j] = 1;
+          For(k,a->bip_size[i]) inout[a->bip_node[i][k]->num] = 0;
+          For(j,tree->n_otu) if(inout[tree->a_nodes[j]->num]) tree->t_dir[a->num*dim+tree->a_nodes[j]->num] = i;
+          break;
+        }
     }
-
-
+  
+  
   if(!d->tax)
-    {
-
+    {      
       d_a = -1;
-
+      
       For(i,3)
-    {
-      if(d->v[i] != a) Update_Dir_To_Tips(d,d->v[i],tree);
-      else if(d->v[i] == a) d_a = i;
-    }
-
+        {
+          if(d->v[i] != a) Update_Dir_To_Tips(d,d->v[i],tree);
+          else if(d->v[i] == a) d_a = i;
+        }
+      
       For(j,tree->n_otu) inout[j] = 1;
       For(k,d->bip_size[d_a]) inout[d->bip_node[d_a][k]->num] = 0;
       For(j,tree->n_otu) if(inout[tree->a_nodes[j]->num]) tree->t_dir[d->num*dim+tree->a_nodes[j]->num] = d_a;
     }
-
-  Free(inout);
-
+  Free(inout);  
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Fill_Dir_Table(t_tree *tree)
 {
   int i,j;
@@ -5288,28 +5408,18 @@ void Fill_Dir_Table(t_tree *tree)
   Get_Bip(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree);
   Update_Dir_To_Tips(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree);
 
-
   for(i=tree->n_otu;i<2*tree->n_otu-2;i++)
     for(j=i;j<2*tree->n_otu-2;j++)
       {
-    Find_Mutual_Direction(tree->a_nodes[i],tree->a_nodes[j],
-                  &(tree->t_dir[i*dim+j]),
-                  &(tree->t_dir[j*dim+i]));
+        Find_Mutual_Direction(tree->a_nodes[i],tree->a_nodes[j],
+                              &(tree->t_dir[i*dim+j]),
+                              &(tree->t_dir[j*dim+i]));
       }
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
 
 int Get_Subtree_Size(t_node *a, t_node *d)
 {
@@ -5331,87 +5441,26 @@ int Get_Subtree_Size(t_node *a, t_node *d)
 
 void Fast_Br_Len(t_edge *b, t_tree *tree, int approx)
 {
-  /* phydbl sum; */
-  /* phydbl *prob, *F; */
-  /* int i, j, k, site; */
-  /* phydbl *v_rght; */
-  /* int dim1,dim2,dim3; */
-  /* int n_iter; */
-  /* phydbl scale_rght; */
-
   if(tree->is_mixt_tree)
     {
       if(approx == NO)
-        MIXT_Br_Len_Brent(0.001,100.,b,tree);
+        MIXT_Br_Len_Brent(0.0001,1.,b,tree);
       else
         {
-          tree->mod->s_opt->brent_it_max = 10;
-          MIXT_Br_Len_Brent(0.0001,1000.,b,tree);
+          tree->mod->s_opt->brent_it_max = 8;
+          MIXT_Br_Len_Brent(0.001,2.,b,tree);
           tree->mod->s_opt->brent_it_max = BRENT_IT_MAX;
         }
       return;
     }
 
-  /* n_iter = 0; */
-  /* dim1   = tree->mod->ns * tree->mod->ras->n_catg; */
-  /* dim2   = tree->mod->ns ; */
-  /* dim3   = tree->mod->ns * tree->mod->ns; */
-
-  /* F    = tree->triplet_struct->F_bc; */
-  /* prob = tree->triplet_struct->F_cd; */
-
-  /* Update_PMat_At_Given_Edge(b,tree); */
-
-  /* For(i,dim1*dim2) F[i] = .0; */
-
-  /* v_rght = (phydbl *)mCalloc(tree->mod->ns,sizeof(phydbl)); */
-
-  /* For(site,tree->n_pattern) */
-  /*   { */
-  /*     /\* Joint probabilities of the states at the two ends of the t_edge *\/ */
-
-  /*     For(k,tree->mod->ras->n_catg) */
-  /*       { */
-  /*         if(b->rght->tax == YES) */
-  /*           For(i,tree->mod->ns) v_rght[i] = (phydbl)(b->p_lk_tip_r[site*dim2+i]); */
-  /*         else */
-  /*           For(i,tree->mod->ns) v_rght[i] = (phydbl)(b->p_lk_rght[site*dim1+k*dim2+i]); */
-
-  /*         scale_rght = (b->rght->tax)?(0.0):(b->sum_scale_rght[k*tree->n_pattern+site]); */
-
-  /*         Joint_Proba_States_Left_Right(b->Pij_rr + k*dim3, */
-  /*       				b->p_lk_left + site*dim1+k*dim2, */
-  /*       				v_rght, */
-  /*       				tree->mod->e_frq->pi, */
-  /*       				b->sum_scale_left[k*tree->n_pattern+site], */
-  /*       				scale_rght, */
-  /*       				prob + dim3*k, */
-  /*       				tree->mod->ns,site,tree); */
-
-  /*         /\* Scaling *\/ */
-  /*         sum = .0; */
-  /*         For(i,tree->mod->ns) For(j,tree->mod->ns) sum += prob[dim3*k+dim2*i+j]; */
-  /*         For(i,tree->mod->ns) For(j,tree->mod->ns) prob[dim3*k+dim2*i+j] /= sum; */
-  /*         For(i,tree->mod->ns) For(j,tree->mod->ns) prob[dim3*k+dim2*i+j] *= tree->mod->ras->gamma_r_proba->v[k]; */
-  /*       } */
-
-  /*     /\* Expected number of each pair of states *\/ */
-  /*     For(i,tree->mod->ns) For(j,tree->mod->ns) For(k,tree->mod->ras->n_catg) */
-  /*       F[dim3*k+dim2*i+j] += tree->data->wght[site] * prob[dim3*k+dim2*i+j]; */
-
-  /* } */
-
-  /* Free(v_rght); */
-
-  /* Opt_Dist_F(&(b->l->v),F,tree->mod); */
-  /* n_iter++; */
 
   if(approx == NO)
-    Br_Len_Brent(0.001,100.,b,tree);
+    Br_Len_Brent(0.001,2.,b,tree);
   else
     {
-      tree->mod->s_opt->brent_it_max = 10;
-      Br_Len_Brent(0.001,1000.,b,tree);
+      tree->mod->s_opt->brent_it_max = 6;
+      Br_Len_Brent(0.001,2.,b,tree);
       tree->mod->s_opt->brent_it_max = BRENT_IT_MAX;
     }
 }
@@ -5478,7 +5527,6 @@ phydbl Triple_Dist(t_node *a, t_tree *tree, int approx)
   if(a->tax) return UNLIKELY;
   else
     {
-
       Update_PMat_At_Given_Edge(a->b[1],tree);
       Update_PMat_At_Given_Edge(a->b[2],tree);
 
@@ -5494,6 +5542,7 @@ phydbl Triple_Dist(t_node *a, t_tree *tree, int approx)
       Update_P_Lk(tree,a->b[1],a);
       Update_P_Lk(tree,a->b[0],a);
     }
+  
 
   return tree->c_lnL;
 
@@ -5619,27 +5668,26 @@ void Get_List_Of_Target_Edges(t_node *a, t_node *d, t_edge **list, int *list_siz
   For(i,3)
     {
       if(a->v[i] && a->v[i] == d)
-    {
-      list[*list_size] = a->b[i];
-      (*list_size)++;
-    }
+        {
+          list[*list_size] = a->b[i];
+          (*list_size)++;
+        }
     }
-
+  
   if(d->tax) return;
   else
     {
       For(i,3)
-    {
-      if(d->v[i] != a)
-        Get_List_Of_Target_Edges(d,d->v[i],list,list_size,tree);
-    }
+        {
+          if(d->v[i] != a)
+            Get_List_Of_Target_Edges(d,d->v[i],list,list_size,tree);
+        }
     }
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Fix_All(t_tree *tree)
 {
   int i;
@@ -5655,7 +5703,6 @@ void Fix_All(t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Record_Br_Len(t_tree *mixt_tree)
 {
   int i;
@@ -5681,6 +5728,101 @@ void Record_Br_Len(t_tree *mixt_tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
+scalar_dbl **Copy_Br_Len(t_tree *mixt_tree)
+{
+  int i;
+  scalar_dbl **bl, *new_l;
+  t_edge *e;
+
+  bl = (scalar_dbl **)mCalloc(2*mixt_tree->n_otu-1,sizeof(scalar_dbl *));
+  
+  For(i,2*mixt_tree->n_otu-1) 
+    {
+      e = mixt_tree->a_edges[i];
+      bl[i] = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl));
+      do
+        {
+          bl[i]->v = e->l->v;
+          e = e->next;
+          if(e) 
+            {
+              new_l = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl));
+              bl[i]->next       = new_l;
+              bl[i]->next->prev = bl[i];
+              bl[i]             = bl[i]->next;
+            }
+        }
+      while(e);
+    }
+
+  return(bl);
+}
+
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+scalar_dbl **Copy_Br_Len_Var(t_tree *mixt_tree)
+{
+  int i;
+  scalar_dbl **bl_var, *new_l_var;
+  t_edge *e;
+
+  bl_var = (scalar_dbl **)mCalloc(2*mixt_tree->n_otu-1,sizeof(scalar_dbl *));
+  
+  For(i,2*mixt_tree->n_otu-1) 
+    {
+      e = mixt_tree->a_edges[i];
+      bl_var[i] = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl));
+      do
+        {
+          bl_var[i]->v = e->l_var->v;
+          e = e->next;
+          if(e) 
+            {
+              new_l_var = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl));
+              bl_var[i]->next       = new_l_var;
+              bl_var[i]->next->prev = bl_var[i];
+              bl_var[i]             = bl_var[i]->next;
+            }
+        }
+      while(e);
+    }
+
+  return(bl_var);
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void Transfer_Br_Len_To_Tree(scalar_dbl **bl, t_tree *tree)
+{
+  int i;
+  scalar_dbl *la, *lb;
+
+  For(i,2*tree->n_otu-1) 
+    {
+      if(tree->a_edges[i]->l != NULL)
+        {
+          la = bl[i];
+          lb = tree->a_edges[i]->l;
+          if(lb != NULL && la != NULL)
+            {
+              do 
+                { 
+                  lb->v = la->v;
+                  if(la) la = la->next;
+                  if(lb) lb = lb->next;
+                }
+              while(la != NULL && lb != NULL);
+              assert(la == NULL && lb == NULL);
+            }
+        }
+    }
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
 
 void Restore_Br_Len(t_tree *mixt_tree)
 {
@@ -5744,7 +5886,6 @@ void Detect_Polytomies(t_edge *b, phydbl l_thresh, t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Get_List_Of_Nodes_In_Polytomy(t_node *a, t_node *d, t_node ***list, int *size_list)
 {
   if(d->tax) return;
@@ -5822,22 +5963,24 @@ void Connect_Two_Nodes(t_node *a, t_node *d)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
-void Get_List_Of_Adjacent_Targets(t_node *a, t_node *d, t_node ***node_list, t_edge ***edge_list, int *list_size)
+void Get_List_Of_Adjacent_Targets(t_node *a, t_node *d, t_node ***node_list, t_edge ***edge_list, int *list_size, int curr_depth, int max_depth)
 {
   int i;
-
+  
+  if(a->tax) return;
+  
   For(i,3)
     if(a->v[i] == d)
       {
-    (*node_list)[*list_size] = a;
-    (*edge_list)[*list_size] = a->b[i];
-    (*list_size)++;
+        if(node_list != NULL) (*node_list)[*list_size] = a;
+        if(edge_list != NULL) (*edge_list)[*list_size] = a->b[i];
+        (*list_size)++;
       }
+  if(curr_depth == max_depth) return;
   if(d->tax) return;
   else
     For(i,3)
-      if(d->v[i] != a) Get_List_Of_Adjacent_Targets(d,d->v[i],node_list,edge_list,list_size);
+      if(d->v[i] != a) Get_List_Of_Adjacent_Targets(d,d->v[i],node_list,edge_list,list_size,curr_depth+1,max_depth);
 }
 
 //////////////////////////////////////////////////////////////
@@ -5885,7 +6028,6 @@ t_node *Common_Nodes_Btw_Two_Edges(t_edge *a, t_edge *b)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 int KH_Test(phydbl *site_lk_M1, phydbl *site_lk_M2, t_tree *tree)
 {
   phydbl *delta,mean,sd,obs_stat,threshold;
@@ -5926,11 +6068,6 @@ int KH_Test(phydbl *site_lk_M1, phydbl *site_lk_M2, t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
 void Random_Tree(t_tree *tree)
 {
   int *is_available,*list_of_nodes;
@@ -5939,8 +6076,7 @@ void Random_Tree(t_tree *tree)
 
   min_edge_len = 1.E-3;
 
-  if(tree->mod->s_opt && tree->mod->s_opt->print == YES)
-    PhyML_Printf("\n\n. Randomising the tree...\n");
+  if(tree->mod->s_opt && tree->mod->s_opt->print == YES) PhyML_Printf("\n\n. Randomising the tree...\n");
 
   is_available  = (int *)mCalloc(2*tree->n_otu-2,sizeof(int));
   list_of_nodes = (int *)mCalloc(tree->n_otu,    sizeof(int));
@@ -5989,9 +6125,6 @@ void Random_Tree(t_tree *tree)
 
   For(i,2*tree->n_otu-3) if(tree->a_edges[i]->l->v < min_edge_len) tree->a_edges[i]->l->v = min_edge_len;
 
-  Fill_Dir_Table(tree);
-  Update_Dirs(tree);
-
   Free(is_available);
   Free(list_of_nodes);
 }
@@ -6001,7 +6134,9 @@ void Random_Tree(t_tree *tree)
 // Make sure internal edges have likelihood vectors on both
 // sides and external edges have one likelihood vector on the
 // lefthand side only
-
+// Note: deprecated since it screws things up when used in the
+// context of mixt_tree (as the same edges are not 'aligned' across
+// trees anymore). 
 void Reorganize_Edges_Given_Lk_Struct(t_tree *tree)
 {
   int j,i;
@@ -6009,38 +6144,247 @@ void Reorganize_Edges_Given_Lk_Struct(t_tree *tree)
   For(i,2*tree->n_otu-3)
     {
       if(tree->a_edges[i]->p_lk_left && tree->a_edges[i]->left->tax == YES)
-    {
-      For(j,2*tree->n_otu-3)
-        {
-          if(!tree->a_edges[j]->p_lk_left && tree->a_edges[j]->left->tax == NO)
         {
-          Swap_Nodes_On_Edges(tree->a_edges[i],tree->a_edges[j],NO,tree);
-          break;
+          For(j,2*tree->n_otu-3)
+            {
+              if(!tree->a_edges[j]->p_lk_left && tree->a_edges[j]->left->tax == NO)
+                {
+                  Swap_Partial_Lk(tree->a_edges[i],tree->a_edges[j],LEFT,LEFT,tree);
+                  break;
+                }
+              if(!tree->a_edges[j]->p_lk_rght && tree->a_edges[j]->rght->tax == NO)
+                {
+                  Swap_Partial_Lk(tree->a_edges[i],tree->a_edges[j],LEFT,RGHT,tree);
+                  break;
+                }
+            }
         }
-          if(!tree->a_edges[j]->p_lk_rght && tree->a_edges[j]->rght->tax == NO)
+      
+      if(tree->a_edges[i]->p_lk_rght && tree->a_edges[i]->rght->tax == YES)
         {
-          Swap_Nodes_On_Edges(tree->a_edges[i],tree->a_edges[j],YES,tree);
-          break;
-        }
+          For(j,2*tree->n_otu-3)
+            {
+              if(!tree->a_edges[j]->p_lk_left && tree->a_edges[j]->left->tax == NO)
+                {
+                  Swap_Partial_Lk(tree->a_edges[i],tree->a_edges[j],RGHT,LEFT,tree);
+                  break;
+                }
+              if(!tree->a_edges[j]->p_lk_rght && tree->a_edges[j]->rght->tax == NO)
+                {
+                  Swap_Partial_Lk(tree->a_edges[i],tree->a_edges[j],RGHT,RGHT,tree);
+                  break;
+                }
+            }
         }
     }
+}
 
-      if(tree->a_edges[i]->p_lk_rght && tree->a_edges[i]->rght->tax == YES)
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void Swap_Partial_Lk(t_edge *a, t_edge *b, int side_a, int side_b, t_tree *tree)
+{
+  phydbl *buff_p_lk;
+  int *buff_scale;
+  int *buff_p_pars, *buff_pars, *buff_p_lk_loc, *buff_patt_id;
+  short int *buff_p_lk_tip;
+  unsigned int *buff_ui;
+  
+  
+  if(side_a == LEFT && side_b == LEFT)
     {
-      For(j,2*tree->n_otu-3)
-        {
-          if(!tree->a_edges[j]->p_lk_left && tree->a_edges[j]->left->tax == NO)
-        {
-          Swap_Nodes_On_Edges(tree->a_edges[i],tree->a_edges[j],YES,tree);
-          break;
-        }
-          if(!tree->a_edges[j]->p_lk_rght && tree->a_edges[j]->rght->tax == NO)
-        {
-          Swap_Nodes_On_Edges(tree->a_edges[i],tree->a_edges[j],NO,tree);
-          break;
-        }
-        }
+      buff_p_lk    = b->p_lk_left;
+      b->p_lk_left = a->p_lk_left;
+      a->p_lk_left = buff_p_lk;
+      
+      buff_p_lk_tip = b->p_lk_tip_l;
+      b->p_lk_tip_l = a->p_lk_tip_l;
+      a->p_lk_tip_l = buff_p_lk_tip;
+      
+      buff_scale            = b->sum_scale_left_cat;
+      b->sum_scale_left_cat = a->sum_scale_left_cat;
+      a->sum_scale_left_cat = buff_scale;
+      
+      buff_scale        = b->sum_scale_left;
+      b->sum_scale_left = a->sum_scale_left;
+      a->sum_scale_left = buff_scale;
+      
+      buff_patt_id    = b->patt_id_left;
+      b->patt_id_left = a->patt_id_left;
+      a->patt_id_left = buff_patt_id;
+      
+      buff_p_lk_loc    = b->p_lk_loc_left;
+      b->p_lk_loc_left = a->p_lk_loc_left;
+      a->p_lk_loc_left = buff_p_lk_loc;
+      
+      buff_pars = b->pars_l;
+      b->pars_l = a->pars_l;
+      a->pars_l = buff_pars;
+      
+      buff_p_pars = b->p_pars_l;
+      b->p_pars_l = a->p_pars_l;
+      a->p_pars_l = buff_p_pars;
+      
+      buff_ui = b->ui_l;
+      b->ui_l = a->ui_l;
+      a->ui_l = buff_ui;    
+      
+#ifdef BEAGLE
+      temp             = b->p_lk_left_idx;
+      b->p_lk_left_idx = a->p_lk_left_idx;
+      a->p_lk_left_idx = temp;
+      
+      temp            = b->p_lk_tip_idx;
+      b->p_lk_tip_idx = a->p_lk_tip_idx;
+      a->p_lk_tip_idx = temp;
+#endif
+    }
+
+  if(side_a == LEFT && side_b == RGHT)
+    {
+      buff_p_lk    = b->p_lk_rght;
+      b->p_lk_rght = a->p_lk_left;
+      a->p_lk_left = buff_p_lk;
+      
+      buff_p_lk_tip = b->p_lk_tip_r;
+      b->p_lk_tip_r = a->p_lk_tip_l;
+      a->p_lk_tip_l = buff_p_lk_tip;
+      
+      buff_scale            = b->sum_scale_rght_cat;
+      b->sum_scale_rght_cat = a->sum_scale_left_cat;
+      a->sum_scale_left_cat = buff_scale;
+      
+      buff_scale        = b->sum_scale_rght;
+      b->sum_scale_rght = a->sum_scale_left;
+      a->sum_scale_left = buff_scale;
+      
+      buff_patt_id    = b->patt_id_rght;
+      b->patt_id_rght = a->patt_id_left;
+      a->patt_id_left = buff_patt_id;
+      
+      buff_p_lk_loc    = b->p_lk_loc_rght;
+      b->p_lk_loc_rght = a->p_lk_loc_left;
+      a->p_lk_loc_left = buff_p_lk_loc;
+      
+      buff_pars = b->pars_r;
+      b->pars_r = a->pars_l;
+      a->pars_l = buff_pars;
+      
+      buff_p_pars = b->p_pars_r;
+      b->p_pars_r = a->p_pars_l;
+      a->p_pars_l = buff_p_pars;
+      
+      buff_ui = b->ui_r;
+      b->ui_r = a->ui_l;
+      a->ui_l = buff_ui;    
+      
+#ifdef BEAGLE
+      temp             = b->p_lk_rght_idx;
+      b->p_lk_rght_idx = a->p_lk_left_idx;
+      a->p_lk_left_idx = temp;
+      
+      temp            = b->p_lk_tip_idx;
+      b->p_lk_tip_idx = a->p_lk_tip_idx;
+      a->p_lk_tip_idx = temp;
+#endif
     }
+
+  if(side_a == RGHT && side_b == LEFT)
+    {
+      buff_p_lk    = b->p_lk_left;
+      b->p_lk_left = a->p_lk_rght;
+      a->p_lk_rght = buff_p_lk;
+      
+      buff_p_lk_tip = b->p_lk_tip_l;
+      b->p_lk_tip_l = a->p_lk_tip_r;
+      a->p_lk_tip_r = buff_p_lk_tip;
+      
+      buff_scale            = b->sum_scale_left_cat;
+      b->sum_scale_left_cat = a->sum_scale_rght_cat;
+      a->sum_scale_rght_cat = buff_scale;
+      
+      buff_scale        = b->sum_scale_left;
+      b->sum_scale_left = a->sum_scale_rght;
+      a->sum_scale_rght = buff_scale;
+      
+      buff_patt_id    = b->patt_id_left;
+      b->patt_id_left = a->patt_id_rght;
+      a->patt_id_rght = buff_patt_id;
+      
+      buff_p_lk_loc    = b->p_lk_loc_left;
+      b->p_lk_loc_left = a->p_lk_loc_rght;
+      a->p_lk_loc_rght = buff_p_lk_loc;
+      
+      buff_pars = b->pars_l;
+      b->pars_l = a->pars_r;
+      a->pars_r = buff_pars;
+      
+      buff_p_pars = b->p_pars_l;
+      b->p_pars_l = a->p_pars_r;
+      a->p_pars_r = buff_p_pars;
+      
+      buff_ui = b->ui_l;
+      b->ui_l = a->ui_r;
+      a->ui_r = buff_ui;    
+      
+#ifdef BEAGLE
+      temp             = b->p_lk_left_idx;
+      b->p_lk_left_idx = a->p_lk_rght_idx;
+      a->p_lk_rght_idx = temp;
+      
+      temp            = b->p_lk_tip_idx;
+      b->p_lk_tip_idx = a->p_lk_tip_idx;
+      a->p_lk_tip_idx = temp;
+#endif
+    }
+
+  if(side_a == RGHT && side_b == RGHT)
+    {
+      buff_p_lk    = b->p_lk_rght;
+      b->p_lk_rght = a->p_lk_rght;
+      a->p_lk_rght = buff_p_lk;
+      
+      buff_p_lk_tip = b->p_lk_tip_r;
+      b->p_lk_tip_r = a->p_lk_tip_r;
+      a->p_lk_tip_r = buff_p_lk_tip;
+      
+      buff_scale            = b->sum_scale_rght_cat;
+      b->sum_scale_rght_cat = a->sum_scale_rght_cat;
+      a->sum_scale_rght_cat = buff_scale;
+      
+      buff_scale        = b->sum_scale_rght;
+      b->sum_scale_rght = a->sum_scale_rght;
+      a->sum_scale_rght = buff_scale;
+      
+      buff_patt_id    = b->patt_id_rght;
+      b->patt_id_rght = a->patt_id_rght;
+      a->patt_id_rght = buff_patt_id;
+      
+      buff_p_lk_loc    = b->p_lk_loc_rght;
+      b->p_lk_loc_rght = a->p_lk_loc_rght;
+      a->p_lk_loc_rght = buff_p_lk_loc;
+      
+      buff_pars = b->pars_r;
+      b->pars_r = a->pars_r;
+      a->pars_r = buff_pars;
+      
+      buff_p_pars = b->p_pars_r;
+      b->p_pars_r = a->p_pars_r;
+      a->p_pars_r = buff_p_pars;
+      
+      buff_ui = b->ui_r;
+      b->ui_r = a->ui_r;
+      a->ui_r = buff_ui;    
+      
+#ifdef BEAGLE
+      temp             = b->p_lk_rght_idx;
+      b->p_lk_rght_idx = a->p_lk_rght_idx;
+      a->p_lk_rght_idx = temp;
+      
+      temp            = b->p_lk_tip_idx;
+      b->p_lk_tip_idx = a->p_lk_tip_idx;
+      a->p_lk_tip_idx = temp;
+#endif
     }
 }
 
@@ -6256,11 +6600,11 @@ void Check_Memory_Amount(t_tree *tree)
     }
   else if(((phydbl)nbytes/(1.E+06)) > 100.)
     {
-      if(!tree->io->quiet) PhyML_Printf("\n\n. WARNING: this analysis will use at least %.0f Mo of memory space...\n",(phydbl)nbytes/(1.E+06));
+      if(!tree->io->quiet) PhyML_Printf("\n\n. WARNING: this analysis will use at least %.0f MB of memory space...\n",(phydbl)nbytes/(1.E+06));
     }
   else if(((phydbl)nbytes/(1.E+06)) > 1.)
     {
-      if(!tree->io->quiet) PhyML_Printf("\n\n. This analysis requires at least %.0f Mo of memory space.\n",(phydbl)nbytes/(1.E+06));
+      if(!tree->io->quiet) PhyML_Printf("\n\n. This analysis requires at least %.0f MB of memory space.\n",(phydbl)nbytes/(1.E+06));
     }
 }
 
@@ -6404,8 +6748,11 @@ void Add_Root(t_edge *target, t_tree *tree)
 {
   t_edge *b1, *b2;
 
+  assert(target);
+  assert(tree);
+
   #ifndef PHYML
-  PhyML_Printf("\n. Adding root on t_edge %d left = %d right = %d\n.",target->num,target->left->num,target->rght->num); fflush(NULL);
+  PhyML_Printf("\n. Adding root on t_edge %d left = %d right = %d.",target->num,target->left->num,target->rght->num); fflush(NULL);
   #endif
 
   tree->e_root = target;
@@ -6487,42 +6834,45 @@ void Add_Root(t_edge *target, t_tree *tree)
   b2->r_v1 = 1;
   b2->r_v2 = 2;
 
-
   /* WARNING: make sure you have freed the memory for p_lk_rght on b1 and b2 */
-
-  b1->p_lk_rght = tree->e_root->p_lk_left;
-  b2->p_lk_rght = tree->e_root->p_lk_rght;
-
-  b1->p_lk_tip_r = tree->e_root->p_lk_tip_l;
-  b2->p_lk_tip_r = tree->e_root->p_lk_tip_r;
-
-  b1->sum_scale_rght = tree->e_root->sum_scale_left;
-  b2->sum_scale_rght = tree->e_root->sum_scale_rght;
-
-  b1->sum_scale_rght_cat = tree->e_root->sum_scale_left_cat;
-  b2->sum_scale_rght_cat = tree->e_root->sum_scale_rght_cat;
-
-  b1->p_lk_loc_rght = tree->e_root->p_lk_loc_left;
-  b2->p_lk_loc_rght = tree->e_root->p_lk_loc_rght;
-
-  b1->pars_r = tree->e_root->pars_l;
-  b2->pars_r = tree->e_root->pars_r;
-
-  b1->ui_r = tree->e_root->ui_l;
-  b2->ui_r = tree->e_root->ui_r;
-
-  b1->p_pars_r = tree->e_root->p_pars_l;
-  b2->p_pars_r = tree->e_root->p_pars_r;
-
-  b1->p_lk_loc_rght = tree->e_root->p_lk_loc_left;
-  b2->p_lk_loc_rght = tree->e_root->p_lk_loc_rght;
-
-  b1->patt_id_rght = tree->e_root->patt_id_left;
-  b2->patt_id_rght = tree->e_root->patt_id_rght;
+  if(tree->is_mixt_tree == NO)
+    {
+      b1->p_lk_rght = tree->e_root->p_lk_left;
+      b2->p_lk_rght = tree->e_root->p_lk_rght;
+      
+      b1->p_lk_tip_r = tree->e_root->p_lk_tip_l;
+      b2->p_lk_tip_r = tree->e_root->p_lk_tip_r;
+      
+      b1->sum_scale_rght = tree->e_root->sum_scale_left;
+      b2->sum_scale_rght = tree->e_root->sum_scale_rght;
+      
+      b1->sum_scale_rght_cat = tree->e_root->sum_scale_left_cat;
+      b2->sum_scale_rght_cat = tree->e_root->sum_scale_rght_cat;
+      
+      b1->p_lk_loc_rght = tree->e_root->p_lk_loc_left;
+      b2->p_lk_loc_rght = tree->e_root->p_lk_loc_rght;
+      
+      b1->pars_r = tree->e_root->pars_l;
+      b2->pars_r = tree->e_root->pars_r;
+      
+      b1->ui_r = tree->e_root->ui_l;
+      b2->ui_r = tree->e_root->ui_r;
+      
+      b1->p_pars_r = tree->e_root->p_pars_l;
+      b2->p_pars_r = tree->e_root->p_pars_r;
+      
+      b1->p_lk_loc_rght = tree->e_root->p_lk_loc_left;
+      b2->p_lk_loc_rght = tree->e_root->p_lk_loc_rght;
+      
+      b1->patt_id_rght = tree->e_root->patt_id_left;
+      b2->patt_id_rght = tree->e_root->patt_id_rght;
+    }
 
   Update_Ancestors(tree->n_root,tree->n_root->v[2],tree);
   Update_Ancestors(tree->n_root,tree->n_root->v[1],tree);
   tree->n_root->anc = NULL;
+
+  if(tree->is_mixt_tree == YES) MIXT_Add_Root(target,tree);
 }
 
 //////////////////////////////////////////////////////////////
@@ -6562,15 +6912,15 @@ t_tree *Generate_Random_Tree_From_Scratch(int n_otu, int rooted)
 
   tree->rates = RATES_Make_Rate_Struct(tree->n_otu);
   RATES_Init_Rate_Struct(tree->rates,tree->io->rates,tree->n_otu);
-
+  
   For(i,2*tree->n_otu-2)
     {
       tree->a_nodes[i]->v[1] = NULL;
       tree->a_nodes[i]->v[2] = NULL;
     }
-
+  
   root = (t_node *)Make_Node_Light(2*tree->n_otu-2);
-
+  
   connected       = (int *)mCalloc(2*tree->n_otu-2,sizeof(int));
   nonconnected    = (int *)mCalloc(2*tree->n_otu-2,sizeof(int));
   available_nodes = (int *)mCalloc(2*tree->n_otu-2,sizeof(int));
@@ -6578,13 +6928,13 @@ t_tree *Generate_Random_Tree_From_Scratch(int n_otu, int rooted)
   external_nodes  = (t_node **)mCalloc(tree->n_otu,  sizeof(t_node *));
   t               = (phydbl *)mCalloc(tree->n_otu-1,sizeof(phydbl ));
   tmp             = (phydbl *)mCalloc(2*tree->n_otu-2,sizeof(phydbl ));
-
+  
   n_nonconnected = 2*n_otu-2;
-
+  
   For(i,2*tree->n_otu-2) nonconnected[i] = i;
-
+  
   available_nodes[0] = 2*n_otu-2;
-
+  
   /* Node times are generated according to a Birth-death process.
      Formulae are as described by Yang and Rannala (1997) */
   phydbl    phi;
@@ -6593,33 +6943,33 @@ t_tree *Generate_Random_Tree_From_Scratch(int n_otu, int rooted)
   phydbl lambda; /* death rate */
   phydbl      u; /* random U[0,1] */
   phydbl expval;
-
+  
   /* rho = 1.0 and mu = 0.0 correspond to the Yule process */
-
+  
   lambda = 6.7;
   mu     = 2.5;
   rho    = 9./150.;
-
+  
   expval = EXP(MIN(1.E+2,mu-lambda));
   phi = (rho*lambda*(expval-1.) + (mu-lambda)*expval)/(expval-1.); /* Equation 16 */
-
+  
   For(i,tree->n_otu-1)
     {
       u = rand();
       u /= RAND_MAX;
-
+      
       if(FABS(lambda - mu) > 1.E-4)
-    t[i] = (LOG(phi-u*rho*lambda) - LOG(phi-u*rho*lambda + u*(lambda-mu)))/(mu-lambda); /* Equation 15 */
+        t[i] = (LOG(phi-u*rho*lambda) - LOG(phi-u*rho*lambda + u*(lambda-mu)))/(mu-lambda); /* Equation 15 */
       else
-    t[i] = u / (1.+lambda*rho*(1-u)); /* Equation 17 */
+        t[i] = u / (1.+lambda*rho*(1-u)); /* Equation 17 */
     }
-
+  
   Qksort(t,NULL,0,tree->n_otu-2); /* Node times ordering in ascending order */
-
+  
   For(i,tree->n_otu-1) tmp[i] =  t[tree->n_otu-2-i];
   For(i,tree->n_otu-1) t[i]   = -tmp[i];
-
-
+  
+  
   /* Rescale t_node times such that the time at the root t_node is -100 */
   for(i=1;i<tree->n_otu-1;i++)
     {
@@ -6627,8 +6977,8 @@ t_tree *Generate_Random_Tree_From_Scratch(int n_otu, int rooted)
       t[i] *= 1.E+02;
     }
   t[0] = -1.E+02;
-
-
+  
+  
   n_available = 1;
   curr_n = root;
   n_connected = 0;
@@ -6637,87 +6987,84 @@ t_tree *Generate_Random_Tree_From_Scratch(int n_otu, int rooted)
       n1 = Rand_Int(0,n_nonconnected-1);
       n1 = nonconnected[n1];
       connected[n1] = 1;
-
+      
       n_nonconnected = 0;
       For(i,2*tree->n_otu-2) if(!connected[i]) {nonconnected[n_nonconnected++] = i;}
-
+      
       n2 = Rand_Int(0,n_nonconnected-1);
       n2 = nonconnected[n2];
       connected[n2] = 1;
-
+      
       n_nonconnected = 0;
       For(i,2*tree->n_otu-2) if(!connected[i]) {nonconnected[n_nonconnected++] = i;}
-
+      
       curr_n->v[1] = tree->a_nodes[n1];
       curr_n->v[2] = tree->a_nodes[n2];
       tree->a_nodes[n1]->v[0] = curr_n;
       tree->a_nodes[n2]->v[0] = curr_n;
-
+      
       tree->rates->nd_t[curr_n->num] = t[n_connected/2];
-
+      
       available_nodes[n_available] = tree->a_nodes[n1]->num;
       For(i,n_available)
-    if(available_nodes[i] == curr_n->num)
-      {
-        available_nodes[i] = tree->a_nodes[n2]->num;
-        break;
-      }
+        if(available_nodes[i] == curr_n->num)
+          {
+            available_nodes[i] = tree->a_nodes[n2]->num;
+            break;
+          }
       n_available++;
-
+      
       new_n = Rand_Int(0,n_available-1);
       curr_n = tree->a_nodes[available_nodes[new_n]];
-
+      
       n_connected+=2;
-
+      
     }while(n_connected < 2*tree->n_otu-2);
-
+  
   For(i,2*tree->n_otu-2) tmp[i] = tree->rates->nd_t[i];
-
+  
   /* Unroot the tree */
   root->v[2]->v[0] = root->v[2];
   root->v[1]->v[0] = root->v[1];
-
+  
   n_internal = n_external = 0;
   For(i,2*tree->n_otu-2)
     {
       if(tree->a_nodes[i]->v[1]) internal_nodes[n_internal++] = tree->a_nodes[i];
-      else                     external_nodes[n_external++] = tree->a_nodes[i];
+      else                       external_nodes[n_external++] = tree->a_nodes[i];
     }
-
-
+  
+  
   n_internal = n_external = 0;
   For(i,2*tree->n_otu-2)
     {
       if(i < tree->n_otu)
-    {
-      tree->a_nodes[i]      = external_nodes[n_external++];
-      tree->a_nodes[i]->tax = 1;
-    }
+        {
+          tree->a_nodes[i]      = external_nodes[n_external++];
+          tree->a_nodes[i]->tax = 1;
+        }
       else
-    {
-      tree->rates->nd_t[i] = tmp[internal_nodes[n_internal]->num];
-      tree->a_nodes[i]        = internal_nodes[n_internal++];
-      tree->a_nodes[i]->tax   = 0;
-    }
-
+        {
+          tree->rates->nd_t[i]  = tmp[internal_nodes[n_internal]->num];
+          tree->a_nodes[i]      = internal_nodes[n_internal++];
+          tree->a_nodes[i]->tax = 0;
+        }
+      
       tree->a_nodes[i]->num = i;
     }
-
+  
   For(i,tree->n_otu) tree->rates->nd_t[i] = 0.0;
-
+  
   For(i,tree->n_otu)
     {
       if(!tree->a_nodes[i]->name) tree->a_nodes[i]->name = (char *)mCalloc(T_MAX_NAME,sizeof(char));
       strcpy(tree->a_nodes[i]->name,"x");
       sprintf(tree->a_nodes[i]->name+1,"%d",i);
     }
-
-
+  
+  
   tree->num_curr_branch_available = 0;
   Connect_Edges_To_Nodes_Recur(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree);
-  Fill_Dir_Table(tree);
-  Update_Dirs(tree);
-
   
   /* Add root */
   if(rooted)
@@ -6731,6 +7078,7 @@ t_tree *Generate_Random_Tree_From_Scratch(int n_otu, int rooted)
               break;
             }
         }
+
     }
   /* Or not... */
   else
@@ -6747,7 +7095,7 @@ t_tree *Generate_Random_Tree_From_Scratch(int n_otu, int rooted)
   Free(internal_nodes);
   Free(t);
   Free(tmp);
-
+  
   return tree;
 }
 #endif
@@ -6846,7 +7194,7 @@ void Evolve(calign *data, t_mod *mod, t_tree *tree)
 
   if(mod->use_m4mod) tree->write_labels = YES;
 
-  Set_Br_Len_Var(tree);
+  Set_Br_Len_Var(NULL,tree);
 
   switch_to_yes = NO;
   if(tree->mod->gamma_mgf_bl == YES) 
@@ -6884,6 +7232,15 @@ void Evolve(calign *data, t_mod *mod, t_tree *tree)
       root_state = Pick_State(mod->ns,mod->e_frq->pi->v);
       data->c_seq[0]->state[site] = Reciproc_Assign_State(root_state,tree->io->datatype);
 
+      /* printf("\n. root_state: %d root_rate_class: %d [%f %f %f %f]", */
+      /*        root_state, */
+      /*        root_rate_class, */
+      /*        mod->e_frq->pi->v[0], */
+      /*        mod->e_frq->pi->v[1], */
+      /*        mod->e_frq->pi->v[2], */
+      /*        mod->e_frq->pi->v[3]); */
+      /* Exit("\n"); */
+
       /* tree->a_nodes[0] is considered as the root t_node */
       Evolve_Recur(tree->a_nodes[0],
                    tree->a_nodes[0]->v[0],
@@ -7288,35 +7645,22 @@ void Best_Of_NNI_And_SPR(t_tree *tree)
     {
       t_tree *ori_tree,*best_tree;
       t_mod *ori_mod,*best_mod;
-      phydbl *ori_bl,*best_bl;
+      scalar_dbl  **ori_bl,**best_bl;
       phydbl best_lnL,ori_lnL,nni_lnL,spr_lnL;
       int i;
 #ifdef BEAGLE
       tree->b_inst = create_beagle_instance(tree, tree->io->quiet, tree->io);
 #endif
-      ori_bl = (phydbl *)mCalloc(2*tree->n_otu-3,sizeof(phydbl));
-      best_bl = (phydbl *)mCalloc(2*tree->n_otu-3,sizeof(phydbl));
 
       ori_mod   = Copy_Model(tree->mod);
       best_mod  = Copy_Model(tree->mod);
 
-      ori_tree = Make_Tree_From_Scratch(tree->n_otu,tree->data);
-
-/*       ori_tree = Make_Tree(tree->n_otu); */
-/*       Init_Tree(ori_tree,ori_tree->n_otu); */
-/*       Make_All_Tree_Nodes(ori_tree); */
-/*       Make_All_Tree_Edges(ori_tree); */
-
+      ori_tree  = Make_Tree_From_Scratch(tree->n_otu,tree->data);
       best_tree = Make_Tree_From_Scratch(tree->n_otu,tree->data);
 
-/*       best_tree = Make_Tree(tree->n_otu); */
-/*       Init_Tree(best_tree,best_tree->n_otu); */
-/*       Make_All_Tree_Nodes(best_tree); */
-/*       Make_All_Tree_Edges(best_tree); */
-
       Copy_Tree(tree,ori_tree);//Save a backup of the original tree in ori_tree
       Record_Br_Len(tree);
-      For(i,2*tree->n_otu-3) ori_bl[i] = tree->a_edges[i]->l->v;
+      ori_bl = Copy_Br_Len(tree);
 
 
       best_lnL = UNLIKELY;
@@ -7331,12 +7675,12 @@ void Best_Of_NNI_And_SPR(t_tree *tree)
       //Mark the NNI tree as the "best" tree
       Copy_Tree(tree,best_tree); /* Record the tree topology and branch lengths */
       Record_Br_Len(tree);
-      For(i,2*tree->n_otu-3) best_bl[i] = tree->a_edges[i]->l->v;
-      For(i,2*tree->n_otu-3) best_tree->a_edges[i]->l->v = best_bl[i];
+      best_bl = Copy_Br_Len(tree);
+      Transfer_Br_Len_To_Tree(best_bl,best_tree);
       Record_Model(tree->mod,best_mod);
 
       Copy_Tree(ori_tree,tree); /* Back to the original tree topology */
-      For(i,2*tree->n_otu-3) tree->a_edges[i]->l->v = ori_bl[i]; /* Back to the original branch lengths */
+      Transfer_Br_Len_To_Tree(ori_bl,tree); /* Back to the original branch lengths */
       Record_Model(ori_mod,tree->mod); /* Back to the original model */
 
       /* Make sure the tree is in its original form */
@@ -7363,18 +7707,18 @@ void Best_Of_NNI_And_SPR(t_tree *tree)
           best_lnL = spr_lnL;
           Copy_Tree(tree,best_tree); /* Record tree topology, branch lengths and model parameters */
           Record_Br_Len(tree);
-          For(i,2*tree->n_otu-3) best_bl[i] = tree->a_edges[i]->l->v;
-          For(i,2*tree->n_otu-3) best_tree->a_edges[i]->l->v = best_bl[i];
+          For(i,2*tree->n_otu-1) Free_Scalar_Dbl(best_bl[i]);
+          Free(best_bl);
+          best_bl = Copy_Br_Len(tree);
+          Transfer_Br_Len_To_Tree(best_bl,best_tree);
           Record_Model(tree->mod,best_mod);
         }
 
       Copy_Tree(best_tree,tree);
-      Fill_Dir_Table(tree);
-      Update_Dirs(tree);
       Init_P_Lk_Tips_Int(tree);
       Init_Ui_Tips(tree);
       Init_P_Pars_Tips(tree);
-      For(i,2*tree->n_otu-3) tree->a_edges[i]->l->v = best_bl[i];
+      Transfer_Br_Len_To_Tree(best_bl,tree);
       Record_Model(best_mod,tree->mod);
 
       /* Make sure the current tree has the best topology, branch lengths and model parameters */
@@ -7392,7 +7736,10 @@ void Best_Of_NNI_And_SPR(t_tree *tree)
           PhyML_Printf("\n. Log likelihood obtained after SPR moves : %f",spr_lnL);
         }
 
+      For(i,2*tree->n_otu-1) Free_Scalar_Dbl(ori_bl[i]);
       Free(ori_bl);
+
+      For(i,2*tree->n_otu-1) Free_Scalar_Dbl(best_bl[i]);
       Free(best_bl);
 
       Free_Tree(ori_tree);
@@ -7489,10 +7836,10 @@ void JF(t_tree *tree)
   For(i,2*tree->n_otu-3)
     {
       if((!tree->a_edges[i]->left->tax) && (!tree->a_edges[i]->rght->tax))
-    {
-      PhyML_Printf("%3d %f %f %f\n",
-         tree->a_edges[i]->bip_score,tree->a_edges[i]->alrt_statistic, tree->a_edges[i]->ratio_test,tree->a_edges[i]->l->v);
-    }
+        {
+          PhyML_Printf("%3d %f %f %f\n",
+                       tree->a_edges[i]->bip_score,tree->a_edges[i]->alrt_statistic, tree->a_edges[i]->ratio_test,tree->a_edges[i]->l->v);
+        }
     }
 
 
@@ -7525,7 +7872,6 @@ void JF(t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 t_tree *Dist_And_BioNJ(calign *cdata, t_mod *mod, option *io)
 {
   t_tree *tree;
@@ -7600,8 +7946,6 @@ char *Bootstrap_From_String(char *s_tree, calign *cdata, t_mod *mod, option *io)
 
   Connect_CSeqs_To_Nodes(cdata,io,tree);
   if(tree->mod->s_opt->random_input_tree) Random_Tree(tree);
-  Fill_Dir_Table(tree);
-  Update_Dirs(tree);
   Make_Tree_4_Pars(tree,cdata,cdata->init_len);
   Make_Tree_4_Lk(tree,cdata,cdata->init_len);
   tree->triplet_struct = Make_Triplet_Struct(mod);
@@ -7662,8 +8006,6 @@ char *aLRT_From_String(char *s_tree, calign *cdata, t_mod *mod, option *io)
 
   Connect_CSeqs_To_Nodes(cdata,io,tree);
   if(tree->mod->s_opt->random_input_tree) Random_Tree(tree);
-  Fill_Dir_Table(tree);
-  Update_Dirs(tree);
   Make_Tree_4_Pars(tree,cdata,cdata->init_len);
   Make_Tree_4_Lk(tree,cdata,cdata->init_len);
   tree->triplet_struct = Make_Triplet_Struct(mod);
@@ -7706,8 +8048,6 @@ char *aLRT_From_String(char *s_tree, calign *cdata, t_mod *mod, option *io)
 void Prepare_Tree_For_Lk(t_tree *tree)
 {
   Connect_CSeqs_To_Nodes(tree->data,tree->io,tree);
-  Fill_Dir_Table(tree);
-  Update_Dirs(tree);
   Make_Tree_4_Pars(tree,tree->data,tree->data->init_len);
   Make_Tree_4_Lk(tree,tree->data,tree->data->init_len);
   tree->triplet_struct = Make_Triplet_Struct(tree->mod);
@@ -7883,14 +8223,14 @@ t_node *Find_Lca_Clade(t_node **node_list, int node_list_size, t_tree *tree)
   if(!tree->n_root)
     {
       PhyML_Printf("\n== The tree must be rooted in this function.");
-      PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__);
+      PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__);
       Warn_And_Exit("");
     }
 
   list = (t_node ***)mCalloc(node_list_size,sizeof(t_node **));
   For(i,node_list_size) list[i] = (t_node **)mCalloc(2*tree->n_otu-1,sizeof(t_node *));
   size = (int *)mCalloc(node_list_size,sizeof(int));
-
+  
   For(i,node_list_size)
     {
       if(!Get_List_Of_Ancestors(node_list[i],list[i],size+i,tree))
@@ -7900,26 +8240,43 @@ t_node *Find_Lca_Clade(t_node **node_list, int node_list_size, t_tree *tree)
         }
     }
 
+  /* For(i,node_list_size) */
+  /*   { */
+  /*     int j; */
+  /*     PhyML_Printf("\n. Listing all ancestors of node number %d [%s]", */
+  /*                  node_list[i]->num, */
+  /*                  node_list[i]->tax ? node_list[i]->name : NULL); */
+  /*     For(j,size[i]) PhyML_Printf("\n.  > %d <",list[i][j]->num); */
+  /*   } */
+
   if(node_list_size > 1)
     {
       do
         {
           For(i,node_list_size-1)
-            if(list[i][size[i]] != list[i+1][size[i+1]])
-              break;
-          
+            {
+              assert(list[i][size[i]-1]);
+              assert(list[i+1][size[i+1]-1]);
+              /* PhyML_Printf("\n. %d %d %d %d",list[i][size[i]-1]->num,size[i],list[i+1][size[i+1]-1]->num,size[i+1]); */
+              if(list[i][size[i]-1] != list[i+1][size[i+1]-1])
+                {
+                  /* PhyML_Printf("\n. Break at %d %d",list[i][size[i]]->num,list[i+1][size[i+1]]->num); */
+                  break;
+                }
+            }
+
           if(i != node_list_size-1) break;
           
           For(i,node_list_size)
             {
               size[i]--;
-              if(size[i] == 1) break; // We have reached the tip corresponding to node_list[i]
+              assert(size[i] > 0);
             }
           
           if(node_list_size == 1) break;
           
         }while(1);
-      lca = list[0][size[0]+1];
+      lca = list[0][size[0]];
     }
   else
     {
@@ -7930,6 +8287,8 @@ t_node *Find_Lca_Clade(t_node **node_list, int node_list_size, t_tree *tree)
   Free(list);
   Free(size);
 
+  /* PhyML_Printf("\n. LCA: %d",lca->num); */
+
   return lca;
 }
 
@@ -8092,7 +8451,6 @@ void Branch_Lengths_To_Rate_Lengths_Pre(t_node *a, t_node *d, t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 int Find_Clade(char **tax_name_list, int list_size, t_tree *tree)
 {
   int *tax_num_list;
@@ -8206,7 +8564,7 @@ void Find_Clade_Pre(t_node *a, t_node *d, int *tax_num_list, int list_size, int
   else
     For(i,3)
       if((d->v[i] != a) && (d->b[i] != tree->e_root))
-    Find_Clade_Pre(d,d->v[i],tax_num_list,list_size,num,tree);
+        Find_Clade_Pre(d,d->v[i],tax_num_list,list_size,num,tree);
 }
 
 //////////////////////////////////////////////////////////////
@@ -8581,6 +8939,7 @@ void Get_Best_Root_Position(t_tree *tree)
 
   if(has_outgrp == YES)
     {
+
       Free_Edge_Lk_Rght(tree->a_edges[2*tree->n_otu-3]);
       Free_Edge_Lk_Rght(tree->a_edges[2*tree->n_otu-2]);
       Free_Edge_Pars_Rght(tree->a_edges[2*tree->n_otu-3]);
@@ -8774,28 +9133,27 @@ int Scale_Subtree_Height(t_node *a, phydbl K, phydbl floor, int *n_nodes, t_tree
   else
     {
       int i;
-
+      
       if(new_height < tree->rates->nd_t[a->anc->num]) return 0;
       else
-    {
-      tree->rates->nd_t[a->num] = new_height;
-      *n_nodes = 1;
-    }
-
+        {
+          tree->rates->nd_t[a->num] = new_height;
+          *n_nodes = 1;
+        }
+      
       For(i,3)
-    if(a->v[i] != a->anc && a->b[i] != tree->e_root)
-      {
-        Scale_Node_Heights_Post(a,a->v[i],K,floor,n_nodes,tree);
-      }
+        if(a->v[i] != a->anc && a->b[i] != tree->e_root)
+          {
+            Scale_Node_Heights_Post(a,a->v[i],K,floor,n_nodes,tree);
+          }
     }
-
+  
   return 1;
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Scale_Node_Heights_Post(t_node *a, t_node *d, phydbl K, phydbl floor, int *n_nodes, t_tree *tree)
 {
   if(d == tree->n_root)
@@ -8832,10 +9190,10 @@ void Scale_Node_Heights_Post(t_node *a, t_node *d, phydbl K, phydbl floor, int *
       
       if(tree->rates->nd_t[d->num] < tree->rates->nd_t[a->num])
         {
-          PhyML_Printf("\n. K = %f floor = %f t_prior_max(a) = %f t_prior_max(d) = %f a->t = %f d->t %f",
+          PhyML_Printf("\n== K = %f floor = %f t_prior_max(a) = %f t_prior_max(d) = %f a->t = %f d->t %f",
                        K,floor,tree->rates->t_prior_max[a->num],tree->rates->t_prior_max[d->num],
                        tree->rates->nd_t[a->num],tree->rates->nd_t[d->num]);
-          PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__);
+          PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__);
           Warn_And_Exit("");
         }
       
@@ -8853,7 +9211,7 @@ int Scale_Subtree_Rates(t_node *a, phydbl mult, int *n_nodes, t_tree *tree)
 {
   int res;
   int i;
-
+  
   *n_nodes = 0;
   res      = 1;
 
@@ -9011,44 +9369,44 @@ void Adjust_Variances(t_tree *tree)
   For(i,2*tree->n_otu-3)
     {
       if(tree->a_edges[i]->l->v < 1.1*tree->mod->l_min)
-    {
-      tree->rates->mean_l[i]                     = -1.00;
-      tree->rates->cov_l[i*(2*tree->n_otu-3)+i]  =  0.1;
-      tree->norm_scale                           = -100;
-
-
-      new_diff = curr_diff = 10.0;
-      do
         {
-          curr_diff = new_diff;
-
-          Generic_Brent_Lk(&(tree->norm_scale),
-                   -1E+6,
-                   0.0,
-                   1.E-10,
-                   10000,
-                   NO,
-                   Wrap_Diff_Lk_Norm_At_Given_Edge,tree->a_edges[i],tree,NULL,NO);
-
-          /* 		      Generic_Brent_Lk(&(tree->rates->mean_l[0]), */
-          /* 				       -100., */
-          /* 				       10*tree->mod->l_min, */
-          /* 				       1.E-3, */
-          /* 				       10000, */
-          /* 				       NO, */
-          /* 				       Wrap_Diff_Lk_Norm_At_Given_Edge,tree->a_edges[0],tree,NULL); */
-
-          Generic_Brent_Lk(&(tree->rates->cov_l[i*(2*tree->n_otu-3)+i]),
-                   0.0,
-                   10.0,
-                   1.E-10,
-                   10000,
-                   NO,
-                   Wrap_Diff_Lk_Norm_At_Given_Edge,tree->a_edges[i],tree,NULL,NO);
-
-          new_diff = Diff_Lk_Norm_At_Given_Edge(tree->a_edges[i],tree);
-        }while(FABS(new_diff-curr_diff) > 1.E-3);
-    }
+          tree->rates->mean_l[i]                     = -1.00;
+          tree->rates->cov_l[i*(2*tree->n_otu-3)+i]  =  0.1;
+          tree->norm_scale                           = -100;
+          
+          
+          new_diff = curr_diff = 10.0;
+          do
+            {
+              curr_diff = new_diff;
+              
+              Generic_Brent_Lk(&(tree->norm_scale),
+                               -1E+6,
+                               0.0,
+                               1.E-10,
+                               10000,
+                               NO,
+                               Wrap_Diff_Lk_Norm_At_Given_Edge,tree->a_edges[i],tree,NULL,NO);
+              
+              /* 		      Generic_Brent_Lk(&(tree->rates->mean_l[0]), */
+              /* 				       -100., */
+              /* 				       10*tree->mod->l_min, */
+              /* 				       1.E-3, */
+              /* 				       10000, */
+              /* 				       NO, */
+              /* 				       Wrap_Diff_Lk_Norm_At_Given_Edge,tree->a_edges[0],tree,NULL); */
+              
+              Generic_Brent_Lk(&(tree->rates->cov_l[i*(2*tree->n_otu-3)+i]),
+                               0.0,
+                               10.0,
+                               1.E-10,
+                               10000,
+                               NO,
+                               Wrap_Diff_Lk_Norm_At_Given_Edge,tree->a_edges[i],tree,NULL,NO);
+              
+              new_diff = Diff_Lk_Norm_At_Given_Edge(tree->a_edges[i],tree);
+            }while(FABS(new_diff-curr_diff) > 1.E-3);
+        }
     }
 }
 
@@ -9696,8 +10054,9 @@ void Set_Both_Sides(int yesno, t_tree *mixt_tree)
 {
   t_tree *tree;
 
-  tree = mixt_tree;
+  assert(!mixt_tree->prev);
 
+  tree = mixt_tree;
   do
     {
       tree->both_sides = yesno;
@@ -9709,6 +10068,8 @@ void Set_Both_Sides(int yesno, t_tree *mixt_tree)
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
 // Returns the matrix of pairwise distances between tips
 phydbl *Dist_Btw_Tips(t_tree *tree)
 {
@@ -9717,9 +10078,6 @@ phydbl *Dist_Btw_Tips(t_tree *tree)
 
   dist = (phydbl *)mCalloc(tree->n_otu*tree->n_otu,sizeof(phydbl));
 
-  Fill_Dir_Table(tree);
-  Update_Dirs(tree);
-
   For(i,tree->n_otu-1)
     {
       for(j=i+1;j<tree->n_otu;j++)
@@ -10005,7 +10363,7 @@ void Set_P_Lk_One_Side(phydbl **Pij, phydbl **p_lk,  int **sum_scale, t_node *d,
 */
 
 void Set_All_P_Lk(t_node **n_v1, t_node **n_v2,
-                  phydbl **p_lk   , int **sum_scale   , int **p_lk_loc,
+                  phydbl **p_lk, int **sum_scale, int **p_lk_loc,
                   phydbl **Pij1, phydbl **p_lk_v1, int **sum_scale_v1,
                   phydbl **Pij2, phydbl **p_lk_v2, int **sum_scale_v2,
                   t_node *d, t_edge *b, t_tree *tree
@@ -10016,8 +10374,9 @@ void Set_All_P_Lk(t_node **n_v1, t_node **n_v2,
 {
   int i;
   
+  assert(tree->is_mixt_tree == NO);
 
-  if(!tree->n_root || tree->ignore_root == YES)
+  if(tree->n_root == NULL || tree->ignore_root == YES)
     {
       if(tree->n_root && (b == tree->n_root->b[1] || b == tree->n_root->b[2])) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
 
@@ -10286,12 +10645,23 @@ void Set_All_P_Lk(t_node **n_v1, t_node **n_v2,
             }
         }
     }
+
+
+  /* assert(*n_v1); */
+  /* assert(*n_v2); */
+  /* assert(*sum_scale); */
+  /* assert(*sum_scale_v1); */
+  /* assert(*sum_scale_v2); */
+  /* assert(*p_lk); */
+  /* assert(*p_lk_v1); */
+  /* assert(*p_lk_v2); */
+
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-void Optimum_Root_Position_IL_Model(t_tree *tree)
+void Best_Root_Position_IL_Model(t_tree *tree)
 {
 
   if(tree->n_root)
@@ -10310,6 +10680,7 @@ void Optimum_Root_Position_IL_Model(t_tree *tree)
       Free_Edge_Pars_Rght(tree->a_edges[2*tree->n_otu-3]);
       Free_Edge_Pars_Rght(tree->a_edges[2*tree->n_otu-2]);
 
+
       best_edge = NULL;
       best_lnL  = UNLIKELY;
       For(i,2*tree->n_otu-3)
@@ -10349,25 +10720,32 @@ void Optimum_Root_Position_IL_Model(t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-void Set_Br_Len_Var(t_tree *tree)
+void Set_Br_Len_Var(t_edge *b, t_tree *tree)
 {
   if(tree->is_mixt_tree)
     {
-      MIXT_Set_Br_Len_Var(tree);
+      MIXT_Set_Br_Len_Var(b,tree);
       return;
     }
 
-  if(!tree->rates)
+  if(tree->rates == NO && tree->mod->gamma_mgf_bl == YES)
     {
-      int i;
-      phydbl len;
 
-      For(i,2*tree->n_otu-1)
+      phydbl len;
+      if(b == NULL)
+        {
+          int i;
+          
+          For(i,2*tree->n_otu-1)
+            {
+              len = MAX(0.0,tree->a_edges[i]->l->v);
+              tree->a_edges[i]->l_var->v = POW(len,2)*tree->mod->l_var_sigma;
+            }
+        }
+      else
         {
-          /* len = MAX(tree->mod->l_min,tree->a_edges[i]->l->v); */
-          /* len = MIN(tree->mod->l_max,len); */
-          len = MAX(0.0,tree->a_edges[i]->l->v);
-          tree->a_edges[i]->l_var->v = POW(len,2)*tree->mod->l_var_sigma;
+          len = MAX(0.0,b->l->v);
+          b->l_var->v = POW(len,2)*tree->mod->l_var_sigma;
         }
     }
 }
@@ -10457,7 +10835,7 @@ void Build_Distrib_Number_Of_Diff_States_Under_Model(t_tree *tree)
         }
 
 
-      Free_Cseq(tree->data);
+      Free_Calign(tree->data);
       Free_Model_Complete(tree->mod);
       Free_Model_Basic(tree->mod);
       
@@ -10993,7 +11371,6 @@ phydbl Fst(int i, int j, calign *data)
   return((Fr-FA)/(1-FA));
 }
 
-
 /*////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////*/
 
@@ -11016,3 +11393,166 @@ phydbl Nucleotide_Diversity(calign *data)
 
   return(pair_div / (phydbl)(n*(n-1.)/2.));
 }
+
+/*////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////*/
+
+void Copy_Scalar_Dbl(scalar_dbl *from, scalar_dbl *to)
+{
+  scalar_dbl *f,*t;
+  f = from;
+  t = to;
+  do
+    {
+      assert(t);
+      assert(f);
+      t->v = f->v;
+      t = t->next;
+      f = f->next;
+    }
+  while(f);
+}
+
+/*////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////*/
+
+scalar_dbl *Duplicate_Scalar_Dbl(scalar_dbl *from)
+{
+  scalar_dbl *to,*t,*f;
+
+  to = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl));
+
+  t = to;
+  f = from;
+  do
+    {
+
+      t->v = f->v;
+      f = f->next;
+      if(f) t->next = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl));
+      t = t->next;
+    }
+  while(f);
+
+  return(to);
+}
+
+/*////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////*/
+
+phydbl Scalar_Elem(int pos, scalar_dbl *scl)
+{
+  scalar_dbl *loc;
+  loc = scl;
+  while(--pos >= 0) loc = loc->next;
+  assert(loc);
+  return(loc->v);
+}
+
+/*////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////*/
+
+void *Linked_List_Elem(int pos, t_ll *ll)
+{
+  t_ll *loc;
+  loc = ll;
+  while(--pos >= 0) loc = loc->next;
+  assert(loc);
+  return(loc->v);
+}
+
+/*////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////*/
+
+int Scalar_Len(scalar_dbl *scl)
+{
+  int len;
+  scalar_dbl *loc;
+
+  if(!scl) return 0;
+
+  loc = scl;
+  len = 0;
+  do 
+    {
+      len++;
+      loc = loc->next;
+    }
+  while(loc != NULL);
+
+  return(len);
+
+}
+
+/*////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////*/
+
+int Linked_List_Len(t_ll *list)
+{
+  int len;
+  t_ll *loc;
+
+  if(!list) return 0;
+
+  loc = list;
+  len = 0;
+  do 
+    {
+      len++;
+      loc = loc->next;
+    }
+  while(loc != NULL);
+
+  return(len);
+
+}
+
+/*////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////*/
+
+void List_Of_Regraft_Nodes(t_node *a, t_node *d, phydbl time_thresh, t_ll *list, t_tree *tree)
+{
+
+  /* printf("\n. d: %d t: %f t_thresh: %f",d->num,tree->rates->nd_t[d->num],time_thresh); */
+  if(d->tax || tree->rates->nd_t[d->num] > time_thresh) return;
+  else
+    {
+      int i;
+
+      Push_Bottom_Linked_List(d,list);
+
+      For(i,3)
+        if(d->v[i] != a) 
+          List_Of_Regraft_Nodes(d,d->v[i],time_thresh,list,tree);
+    }
+}
+
+/*////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////*/
+
+void Push_Bottom_Linked_List(void *what, t_ll *list)
+{
+  if(list->v == NULL) 
+    {
+      // First elem is empty
+      list->v = (void *)what;
+    }
+  else
+    {
+      // Add one elem in list and add 
+      list->tail->next = (t_ll *)mCalloc(1,sizeof(t_ll));
+      list->tail->next->v = (void *)what;
+      list->tail = list->next;
+      list->tail->next = NULL;
+    }
+}
+
+/*////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////*/
+/*////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////*/
+/*////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////*/
+/*////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////*/
+
diff --git a/src/utilities.h b/src/utilities.h
index 7f7cd5f..7f07238 100644
--- a/src/utilities.h
+++ b/src/utilities.h
@@ -48,8 +48,10 @@ extern int n_sec2;
 #define MIN(a,b)                     ((a)<(b)?(a):(b))
 #endif
 
-#define READ  0
-#define WRITE 1
+#define READ      0
+#define WRITE     1
+#define APPEND    2
+#define READWRITE 3
 
 #ifndef isnan
 # define isnan(x)						 \
@@ -108,8 +110,8 @@ static inline int isinf_ld (long double x) { return isnan (x - x); }
 #define T_MAX_NEX_COM   100
 #define N_MAX_NEX_PARM  50
 #define T_MAX_TOKEN     200
-#define T_MAX_ID_COORD  5
-#define T_MAX_ID_DISK   5
+#define T_MAX_ID_COORD  10
+#define T_MAX_ID_DISK   10
 
 #define N_MAX_MIXT_CLASSES 1000
 
@@ -180,7 +182,8 @@ static inline int isinf_ld (long double x) { return isnan (x - x); }
 #define INFINITY HUGE
 #endif
 
-#define  N_MAX_OPTIONS        100
+#define MAX_N_CAL              10
+#define N_MAX_OPTIONS         100
 
 #define NEXT_BLOCK_SIZE        50
 
@@ -270,6 +273,7 @@ static inline int isinf_ld (long double x) { return isnan (x - x); }
 #define THORNE         4
 #define GUINDON        5
 #define STRICTCLOCK    6
+#define BIRTHDEATH     7
 #define NONE          -1
 
 #define ALRTSTAT       1
@@ -364,6 +368,15 @@ typedef	double phydbl;
 #define DUMP_E(...) FOR_EACH(DUMP_EACH_SCI, __VA_ARGS__)
 
 /*!********************************************************/
+// Generic linked list
+typedef struct __Generic_LL {
+  void                    *v;
+  struct __Generic_LL  *next;
+  struct __Generic_LL  *tail;
+  struct __Generic_LL  *head;
+}t_ll;
+
+/*!********************************************************/
 
 typedef struct __Scalar_Int {
   int                      v;
@@ -426,10 +439,7 @@ typedef struct __Node {
   struct __Node                   *prev; /*! See above */
   struct __Node                *next_mixt; /*! Next mixture tree*/
   struct __Node                *prev_mixt; /*! Parent mixture tree */
-
-  struct __Calibration            **calib;
-  short int             *calib_applies_to;
-  int                             n_calib;
+  struct __Calibration              **cal; /*! List of calibration constraints attached to this node */
 
   int                           *bip_size; /*! Size of each of the three lists from bip_node */
   int                                 num; /*! t_node number */
@@ -437,6 +447,7 @@ typedef struct __Node {
   int                        check_branch; /*! check_branch=1 is the corresponding branch is labelled with '*' */
   char                              *name; /*! taxon name (if exists) */
   char                          *ori_name; /*! taxon name (if exists) */
+  int                               n_cal; /*! Number of calibration constraints */
 
   phydbl                           *score; /*! score used in BioNJ to determine the best pair of nodes to agglomerate */
   phydbl                               *l; /*! lengths of the (three or one) branche(s) connected this t_node */
@@ -502,11 +513,12 @@ typedef struct __Edge {
                           bip_score = 1 iif the branch is found in both trees to be compared,
                           bip_score = 0 otherwise. */
 
-  phydbl            *p_lk_left,*p_lk_rght; /*! likelihoods of the subtree on the left and right side (for each site and each relative rate category) */
-  short int      *p_lk_tip_r, *p_lk_tip_l;
+  int                         num_st_left; /*! number of the subtree on the left side */
+  int                         num_st_rght; /*! number of the subtree on the right side */
+
+  phydbl                          *Pij_rr; /*! matrix of change probabilities and its first and secnd derivates (rate*state*state) */
 #ifdef BEAGLE
-  int        p_lk_left_idx, p_lk_rght_idx;
-  int                        p_lk_tip_idx;
+  int                          Pij_rr_idx;
 #endif
 
   short int           *div_post_pred_left; /*! posterior prediction of nucleotide/aa diversity (left-hand subtree) */
@@ -514,24 +526,23 @@ typedef struct __Edge {
   short int                    does_exist;
 
 
+
+  phydbl            *p_lk_left,*p_lk_rght; /*! likelihoods of the subtree on the left and right side (for each site and each relative rate category) */
+  short int      *p_lk_tip_r, *p_lk_tip_l;
+#ifdef BEAGLE
+  int        p_lk_left_idx, p_lk_rght_idx;
+  int                        p_lk_tip_idx;
+#endif
+
   int                       *patt_id_left;
   int                       *patt_id_rght;
   int                      *p_lk_loc_left;
   int                      *p_lk_loc_rght;
 
-
-  phydbl                          *Pij_rr; /*! matrix of change probabilities and its first and secnd derivates (rate*state*state) */
-#ifdef BEAGLE
-  int                          Pij_rr_idx;
-#endif
   int                     *pars_l,*pars_r; /*! parsimony of the subtree on the left and right sides (for each site) */
   unsigned int               *ui_l, *ui_r; /*! union - intersection vectors used in Fitch's parsimony algorithm */
   int                *p_pars_l, *p_pars_r; /*! conditional parsimony vectors */
 
-  int                         num_st_left; /*! number of the subtree on the left side */
-  int                         num_st_rght; /*! number of the subtree on the right side */
-
-
   /*! Below are the likelihood scaling factors (used in functions
      `Get_All_Partial_Lk_Scale' in lk.c. */
   /*
@@ -604,6 +615,7 @@ typedef struct __Tree{
   struct __Phylogeo                      *geo;
   struct __Migrep_Model                 *mmod;
   struct __Disk_Event                   *disk;
+  struct __XML_node                 *xml_root;
 
   int                            is_mixt_tree;
   int                                tree_num; /*! tree number. Used for mixture models */
@@ -633,6 +645,7 @@ typedef struct __Tree{
   int                            write_labels;
   int                           write_br_lens;
   int                                 *mutmap; /*! Mutational map */
+  int                                json_num;
 
   phydbl                             init_lnL;
   phydbl                             best_lnL; /*! highest value of the loglikelihood found so far */
@@ -815,7 +828,7 @@ typedef struct __Calign {
   struct __Option    *io;             /*! input/output */
   phydbl          *b_frq;             /*! observed state frequencies */
   short int       *invar;             /*! < 0 -> polymorphism observed */
-  int              *wght;             /*! # of each site in c_align */
+  phydbl           *wght;             /*! # of each site in c_align */
   short int      *ambigu;             /*! ambigu[i]=1 is one or more of the sequences at site
                                         i display an ambiguous character */
   phydbl      obs_pinvar;
@@ -827,6 +840,7 @@ typedef struct __Calign {
                                         compressed alignment to the positions in the uncompressed
                                         one */
   int             format;             /*! 0 (default): PHYLIP. 1: NEXUS. */
+  scalar_dbl    *io_wght;             /*! weight of each *site* (not pattern) given as input */
 }calign;
 
 /*!********************************************************/
@@ -903,11 +917,17 @@ typedef struct __RAS {
 
 typedef struct __EquFreq {
   /*! Equilibrium frequencies */
-  vect_dbl             *pi; /*! states frequencies */
-  vect_dbl    *pi_unscaled; /*! states frequencies (unscaled) */
+  vect_dbl                   *pi; /*! states frequencies */
+  vect_dbl          *pi_unscaled; /*! states frequencies (unscaled) */
 
-  struct __EquFreq   *next;
-  struct __EquFreq   *prev;
+  phydbl                  *b_frq; /*! vector of empirical state frequencies */
+  
+  short int empirical_state_freq;
+  short int      user_state_freq;
+  vect_dbl          *user_b_freq; /*! user-defined nucleotide frequencies */
+
+  struct __EquFreq         *next;
+  struct __EquFreq         *prev;
 
 }t_efrq;
 
@@ -929,7 +949,6 @@ typedef struct __Model {
   t_string       *aa_rate_mat_file;
   FILE             *fp_aa_rate_mat;
 
-  vect_dbl            *user_b_freq; /*! user-defined nucleotide frequencies */
   t_string              *modelname;
   t_string      *custom_mod_string; /*! string of characters used to define custom models of substitution */
 
@@ -980,8 +999,6 @@ typedef struct __Model {
 
 }t_mod;
 
-
-
 /*!********************************************************/
 
 typedef struct __Eigen{
@@ -1028,6 +1045,9 @@ typedef struct __Option { /*! mostly used in 'help.c' */
   char                *out_tree_file; /*! name of the tree file */
   FILE                  *fp_out_tree;
 
+  char                  *weight_file; /*! name of the file containing site weights */
+  FILE               *fp_weight_file;
+
   char               *out_trees_file; /*! name of the tree file */
   FILE                 *fp_out_trees; /*! pointer to the tree file containing all the trees estimated using random starting trees */
 
@@ -1040,9 +1060,12 @@ typedef struct __Option { /*! mostly used in 'help.c' */
   char               *out_stats_file; /*! name of the statistics file */
   FILE                 *fp_out_stats;
 
-  char               *out_trace_file; /*! name of the file in which the likelihood of the model is written */
+  char               *out_trace_file; /*! name of the file in which the trace is written */
   FILE                 *fp_out_trace;
 
+  char          *out_json_trace_file; /*! name of the file in which json trace is written */
+  FILE           *fp_out_json_trace;
+
   char                  *out_lk_file; /*! name of the file in which the likelihood of the model is written */
   FILE                    *fp_out_lk;
 
@@ -1087,6 +1110,7 @@ typedef struct __Option { /*! mostly used in 'help.c' */
   int                  collapse_boot; /*! 0 -> branch length on bootstrap trees are not collapsed if too small */
   int          random_boot_seq_order; /*! !0 -> sequence order in bootstrapped data set is random */
   int                    print_trace;
+  int               print_json_trace;
   int                 print_site_lnl;
   int                       m4_model;
   int                      rm_ambigu; /*! 0 is the default. 1: columns with ambiguous characters are discarded prior further analysis */
@@ -1120,6 +1144,7 @@ typedef struct __Option { /*! mostly used in 'help.c' */
 #endif
 
   int                       ancestral;
+  int                  has_io_weights;
 }option;
 
 /*!********************************************************/
@@ -1152,7 +1177,6 @@ typedef struct __Optimiz { /*! parameters to be optimised (mostly used in 'optim
   int            n_rand_starts; /*! number of random starting points */
   int             brent_it_max;
   int                steph_spr;
-  int          user_state_freq;
   int          opt_five_branch;
   int              pars_thresh;
   int            hybrid_thresh;
@@ -1192,6 +1216,8 @@ typedef struct __Optimiz { /*! parameters to be optimised (mostly used in 'optim
   int        serial_free_rates;
 
   int      curr_opt_free_rates;
+
+  int          nni_br_len_opt;
 }t_opt;
 
 /*!********************************************************/
@@ -1203,11 +1229,14 @@ typedef struct __NNI{
   struct __Edge            *b;
 
   phydbl                score;
-  phydbl               init_l;
+  scalar_dbl          *init_l;
+  scalar_dbl          *init_v;
   phydbl              init_lk;
-  phydbl               best_l;
+  scalar_dbl          *best_l;
+  scalar_dbl          *best_v;
   phydbl          lk0,lk1,lk2;
-  phydbl             l0,l1,l2;
+  scalar_dbl      *l0,*l1,*l2;
+  scalar_dbl      *v0,*v1,*v2;
 
   struct __Node *swap_node_v1;
   struct __Node *swap_node_v2;
@@ -1218,7 +1247,7 @@ typedef struct __NNI{
                 ((left_1,left_2),right_1,right_2) or
                 ((left_1,right_2),right_1,left_2) or
                 ((left_1,right_1),right_1,left_2)  */
-}nni;
+}t_nni;
 
 /*!********************************************************/
 
@@ -1229,10 +1258,13 @@ typedef struct __SPR{
   struct __Edge       *b_target;
   struct __Edge  *b_init_target;
   struct __Node          **path;
-  phydbl          init_target_l;
-  phydbl          init_target_v;
-  phydbl               l0,l1,l2;
-  phydbl               v0,v1,v2;
+
+  scalar_dbl     *init_target_l;
+  scalar_dbl     *init_target_v;
+
+  scalar_dbl        *l0,*l1,*l2;
+  scalar_dbl        *v0,*v1,*v2;
+
   phydbl                    lnL;
   int                depth_path;
   int                      pars;
@@ -1323,6 +1355,9 @@ typedef struct __T_Rate {
   phydbl birth_rate;
   phydbl birth_rate_min;
   phydbl birth_rate_max;
+  phydbl death_rate;
+  phydbl death_rate_min;
+  phydbl death_rate_max;
   phydbl min_rate;
   phydbl max_rate;
   phydbl c_lnL1;
@@ -1422,10 +1457,8 @@ typedef struct __T_Rate {
 
   int *has_survived;
 
-  struct __Calibration *calib;
-  int tot_num_cal;
-  int *curr_nd_for_cal;
-  phydbl c_lnL_Hastings_ratio;
+  struct __Calibration **a_cal; /* array of calibration data */
+  int                    n_cal; /* number of elements in a_cal */
 
   phydbl     *t_prior_min_ori;
   phydbl     *t_prior_max_ori;
@@ -1464,6 +1497,7 @@ typedef struct __Tmcmc {
   int num_move_tree_height;
   int num_move_subtree_height;
   int num_move_kappa;
+  int num_move_spr;
   int num_move_tree_rates;
   int num_move_subtree_rates;
   int num_move_updown_nu_cr;
@@ -1473,6 +1507,7 @@ typedef struct __Tmcmc {
   int num_move_cov_rates;
   int num_move_cov_switch;
   int num_move_birth_rate;
+  int num_move_death_rate;
   int num_move_jump_calibration;
   int num_move_geo_lambda;
   int num_move_geo_sigma;
@@ -1627,15 +1662,17 @@ typedef struct __XML_attr {
 /*!********************************************************/
 
 typedef struct __Calibration {
-  phydbl *proba; // Probability of this calibration (set by the user and fixed throughout)
+  struct __Node *target_nd; // The node this calibration applies to
+  struct __Calibration *next; // Next calibration
+  struct __Calibration *prev; // Previous calibration
+
   phydbl lower; // lower bound
   phydbl upper; // upper bound
-  int cur_applies_to;
-  phydbl calib_proba;
-  struct __Node **all_applies_to;
-  int n_all_applies_to;
-  struct __Calibration *next;
-  struct __Calibration *prev;
+
+  short int is_primary; // Is is a primary or secondary calibration interval?
+  
+  char **target_tax;
+  int  n_target_tax;
 }t_cal;
 
 /*!********************************************************/
@@ -1716,7 +1753,7 @@ typedef struct __Migrep_Model{
 
   struct __Geo_Coord            *lim; // max longitude and lattitude (the min are both set to zero)                       
 
-  phydbl                  sampl_area;
+  struct __SampArea       *samp_area;
 }t_phyrex_mod;
 
 /*!********************************************************/
@@ -1765,22 +1802,46 @@ typedef struct __Polygon{
 }t_poly;
 
 /*!********************************************************/
+
+typedef struct __SampArea {
+  int n_poly;      /* Number of polygons making the sampling area */
+  t_poly **a_poly; /* Polygons making the sampling area */
+}t_sarea;
+
+
 /*!********************************************************/
-/*!********************************************************/
-/*!********************************************************/
-/*!********************************************************/
+
+typedef struct __JSON_StringVal {
+  char *string;
+  char *value;
+  struct __JSON_Object *object;
+  struct __JSON_Array *array;
+  struct __JSON_StringVal *next;
+}json_sv;
+
 /*!********************************************************/
 
+typedef struct __JSON_Object {
+  struct __JSON_StringVal *sv;
+  struct __JSON_Object *next;
+}json_o;
 
+/*!********************************************************/
 
+typedef struct __JSON_Array {
+  struct __JSON_Object *object;
+}json_a;
 
+/*!********************************************************/
+/*!********************************************************/
+/*!********************************************************/
+/*!********************************************************/
 
 void Unroot_Tree(char **subtrees);
 void Init_Tree(t_tree *tree,int n_otu);
 void Init_Edge_Light(t_edge *b,int num);
 void Init_Node_Light(t_node *n,int num);
 void Set_Edge_Dirs(t_edge *b,t_node *a,t_node *d,t_tree *tree);
-void Init_NNI(nni *a_nni);
 void Init_Nexus_Format(nexcom **com);
 void Restrict_To_Coding_Position(align **data,option *io);
 void Uppercase(char *ch);
@@ -1891,7 +1952,7 @@ void Detect_Polytomies(t_edge *b,phydbl l_thresh,t_tree *tree);
 void Get_List_Of_Nodes_In_Polytomy(t_node *a,t_node *d,t_node ***list,int *size_list);
 void Check_Path(t_node *a,t_node *d,t_node *target,t_tree *tree);
 void Connect_Two_Nodes(t_node *a,t_node *d);
-void Get_List_Of_Adjacent_Targets(t_node *a,t_node *d,t_node ***node_list,t_edge ***edge_list,int *list_size);
+void Get_List_Of_Adjacent_Targets(t_node *a, t_node *d, t_node ***node_list, t_edge ***edge_list, int *list_size, int curr_depth, int max_depth);
 void Sort_List_Of_Adjacent_Targets(t_edge ***list,int list_size);
 t_node *Common_Nodes_Btw_Two_Edges(t_edge *a,t_edge *b);
 int KH_Test(phydbl *site_lk_M1,phydbl *site_lk_M2,t_tree *tree);
@@ -2028,8 +2089,8 @@ void Set_All_P_Lk(t_node **n_v1, t_node **n_v2,
 #endif
                   );
 
-void Optimum_Root_Position_IL_Model(t_tree *tree);
-void Set_Br_Len_Var(t_tree *tree);
+void Best_Root_Position_IL_Model(t_tree *tree);
+void Set_Br_Len_Var(t_edge *b, t_tree *tree);
 void Check_Br_Lens(t_tree *tree);
 void Calculate_Number_Of_Diff_States_Post(t_node *a, t_node *d, t_edge *b, t_tree *tree);
 void Calculate_Number_Of_Diff_States_Pre(t_node *a, t_node *d, t_edge *b, t_tree *tree);
@@ -2046,7 +2107,19 @@ phydbl Mean_Identity(calign *data);
 phydbl Pairwise_Identity(int i, int j, calign *data);
 phydbl Fst(int i, int j, calign *data);
 phydbl Nucleotide_Diversity(calign *data);
-
+void Swap_Partial_Lk(t_edge *a, t_edge *b, int side_a, int side_b, t_tree *tree);
+scalar_dbl **Copy_Br_Len_Var(t_tree *mixt_tree);
+scalar_dbl **Copy_Br_Len(t_tree *mixt_tree);
+void Transfer_Br_Len_To_Tree(scalar_dbl **bl, t_tree *tree);
+void Copy_Scalar_Dbl(scalar_dbl *from, scalar_dbl *to);
+scalar_dbl *Duplicate_Scalar_Dbl(scalar_dbl *from);
+scalar_dbl *Read_Weights(option *io);
+phydbl Scalar_Elem(int pos, scalar_dbl *scl);
+int Scalar_Len(scalar_dbl *scl);
+void List_Of_Regraft_Nodes(t_node *a, t_node *d, phydbl time_thresh, t_ll *list, t_tree *tree);
+void Push_Bottom_Linked_List(void *what, t_ll *list);
+int Linked_List_Len(t_ll *list);
+void *Linked_List_Elem(int pos, t_ll *ll);
 
 #include "xml.h"
 #include "free.h"
diff --git a/src/xml.c b/src/xml.c
index 6ae9712..e2377c2 100644
--- a/src/xml.c
+++ b/src/xml.c
@@ -3,6 +3,1093 @@
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
+t_tree *XML_Process_Base(char *xml_filename)
+{
+  FILE *fp;
+  xml_node *root,*p_elem,*m_elem,*parent,*instance;
+  option *io;
+  void *buff;
+  t_mod *mod,*iomod;
+  t_tree *tree,*mixt_tree,*root_tree;
+  int select;
+  char *component;
+  int i,j,n_components;
+  int first_m_elem;
+  int class_number;
+  scalar_dbl **lens,**lens_var,**ori_lens,**lens_old,**lens_var_old,**ori_lens_old,**ori_lens_var,**ori_lens_var_old;
+  t_ds *ds;
+  char *outputfile;
+  char *alignment;
+  char *s;
+  int lens_size;
+  int first;
+  int *class_num;
+
+
+  fp = fopen(xml_filename,"r");
+  if(!fp)
+    {
+      PhyML_Printf("\n== Could not find the XML file '%s'.\n",xml_filename);
+      Exit("\n");
+    }
+
+  root = XML_Load_File(fp);
+
+  if(!root)
+    {
+      PhyML_Printf("\n== Encountered an issue while loading the XML file.\n");
+      Exit("\n");
+    }
+
+  class_num = (int *)mCalloc(N_MAX_MIXT_CLASSES,sizeof(int));
+  For(i,N_MAX_MIXT_CLASSES) class_num[i] = i;
+
+  component = (char *)mCalloc(T_MAX_NAME,sizeof(char));
+
+  m_elem           = NULL;
+  p_elem           = root;
+  io               = NULL;
+  mixt_tree        = NULL;
+  root_tree        = NULL;
+  mod              = NULL;
+  tree             = NULL;
+  lens             = NULL;
+  lens_var         = NULL;
+  lens_old         = NULL;
+  lens_var_old     = NULL;
+  select           = -1;
+  class_number     = -1;
+  ds               = NULL;
+  lens_size        = 0;
+  ori_lens         = NULL;
+  ori_lens_old     = NULL;
+  ori_lens_var     = NULL;
+  ori_lens_var_old = NULL;
+  first            = YES;
+
+  // Make sure there are no duplicates in node's IDs
+  XML_Check_Duplicate_ID(root);
+
+  int count = 0;
+  XML_Count_Number_Of_Node_With_Name("topology",&count,root);
+
+  if(count > 1)
+    {
+      PhyML_Printf("\n== There should not more than one 'topology' node.");
+      PhyML_Printf("\n== Found %d. Please fix your XML file",count);
+      Exit("\n");
+    }
+  else if(count < 1)
+    {
+      PhyML_Printf("\n== There should be at least one 'topology' node.");
+      PhyML_Printf("\n== Found none. Please fix your XML file");
+      Exit("\n");
+    }
+
+  p_elem = XML_Search_Node_Name("phyml",NO,p_elem);
+
+  /*! Input file
+   */
+  outputfile = XML_Get_Attribute_Value(p_elem,"output.file");
+
+  if(!outputfile)
+    {
+      PhyML_Printf("\n== The 'outputfile' attribute in 'phyml' tag is mandatory.");
+      PhyML_Printf("\n== Please amend your XML file accordingly.");
+      Exit("\n");
+    }
+
+  io = (option *)Make_Input();
+  Set_Defaults_Input(io);
+
+  s = XML_Get_Attribute_Value(p_elem,"run.id");
+  if(s)
+    {
+      io->append_run_ID = YES;
+      strcpy(io->run_id_string,s);
+    }
+
+  strcpy(io->out_file,outputfile);
+  strcpy(io->out_tree_file,outputfile);
+  if(io->append_run_ID) { strcat(io->out_tree_file,"_"); strcat(io->out_tree_file,io->run_id_string); }
+
+# if defined(DATE)
+  strcat(io->out_tree_file,"_date_tree");
+# else
+  strcat(io->out_tree_file,"_phyml_tree");
+#endif
+
+  strcpy(io->out_stats_file,outputfile);
+  if(io->append_run_ID) { strcat(io->out_stats_file,"_"); strcat(io->out_stats_file,io->run_id_string); }
+
+
+# if defined(DATE)
+  strcat(io->out_stats_file,"_date_stats");
+# else
+  strcat(io->out_stats_file,"_phyml_stats");
+#endif
+
+
+  io->fp_out_tree  = Openfile(io->out_tree_file,1);
+  io->fp_out_stats = Openfile(io->out_stats_file,1);
+
+  s = XML_Get_Attribute_Value(p_elem,"print.trace");
+
+  if(s)
+    {
+      select = XML_Validate_Attr_Int(s,6,
+                                     "true","yes","y",
+                                     "false","no","n");
+      
+      if(select < 3)
+        {
+          io->print_trace = YES;
+          strcpy(io->out_trace_file,outputfile);
+          if(io->append_run_ID) { strcat(io->out_trace_file,"_"); strcat(io->out_trace_file,io->run_id_string); }
+          strcat(io->out_trace_file,"_phyml_trace");
+          io->fp_out_trace = Openfile(io->out_trace_file,1);
+        }
+    }
+
+
+  s = XML_Get_Attribute_Value(p_elem,"print.json.trace");
+
+  if(s)
+    {
+      select = XML_Validate_Attr_Int(s,6,
+                                     "true","yes","y",
+                                     "false","no","n");
+      
+      if(select < 3)
+        {
+          io->print_json_trace = YES;
+          strcpy(io->out_json_trace_file,outputfile);
+          if(io->append_run_ID) { strcat(io->out_json_trace_file,"_"); strcat(io->out_json_trace_file,io->run_id_string); }
+          strcat(io->out_json_trace_file,"_phyml_trace.json");
+          io->fp_out_json_trace = Openfile(io->out_json_trace_file,READWRITE);
+        }
+    }
+  
+  s = XML_Get_Attribute_Value(p_elem,"branch.test");
+  if(s)
+    {
+      if(!strcmp(s,"aLRT"))
+        {
+          io->ratio_test = ALRTSTAT;
+        }
+      else if(!strcmp(s,"aBayes"))
+        {
+          io->ratio_test = ABAYES;
+        }
+      else if(!strcmp(s,"SH"))
+        {
+          io->ratio_test = SH;
+        }
+      else if(!strcmp(s,"no") || !strcmp(s,"none"))
+        {
+          io->ratio_test = 0;
+        }
+      else
+        {
+          PhyML_Printf("\n== '%s' is not a valid option for 'branch.test'.",s);
+          PhyML_Printf("\n== Please use 'aLRT' or 'aBayes' or 'SH'.");
+          Exit("\n");
+        }
+    }
+  
+  s = XML_Get_Attribute_Value(p_elem,"quiet");
+  if(s)
+    {
+      select = XML_Validate_Attr_Int(s,6,
+                                     "true","yes","y",
+                                     "false","no","n");
+      if(select < 3) io->quiet = YES;
+    }
+
+  s = XML_Get_Attribute_Value(p_elem,"memory.check");
+  if(s)
+    {
+      select = XML_Validate_Attr_Int(s,6,
+                                     "true","yes","y",
+                                     "false","no","n");
+      if(select >= 3) io->mem_question = NO;
+    }
+
+  /*! Read all partitionelem nodes and mixturelem nodes in each of them
+   */
+  do
+    {
+      p_elem = XML_Search_Node_Name("partitionelem",YES,p_elem);
+      
+      if(p_elem == NULL) break;
+      
+      buff = (option *)Make_Input();
+      Set_Defaults_Input(buff);
+      io->next = buff;
+      io->next->prev = io;
+      
+      io = io->next;
+      if(first == YES)
+        {
+          io = io->prev;
+          io->next = NULL;
+          Free_Input(buff);
+          first = NO;
+        }
+      
+      
+      /*! Set the datatype (required when compressing data)
+       */
+      char *dt = NULL;
+      dt = XML_Get_Attribute_Value(p_elem,"data.type");
+      if(!dt)
+        {
+          PhyML_Printf("\n== Please specify the type of data ('aa' or 'nt') for partition element '%s'",
+                       XML_Get_Attribute_Value(p_elem,"id"));
+          PhyML_Printf("\n== Syntax: 'data.type=\"aa\"' or 'data.type=\"nt\"'");
+          Exit("\n");
+        }
+      
+      select = XML_Validate_Attr_Int(dt,2,"aa","nt");
+      switch(select)
+        {
+        case 0:
+          {
+            io->datatype = AA;
+            break;
+          }
+        case 1:
+          {
+            io->datatype = NT;
+            break;
+          }
+        default:
+          {
+            PhyML_Printf("\n== Unknown data type. Must be either 'aa' or 'nt'.");
+            Exit("\n");
+          }
+        }
+      
+
+      char *format = NULL;
+      format = XML_Get_Attribute_Value(p_elem,"format");
+      if(format)
+        {
+          if(!strcmp(format,"interleave") ||
+             !strcmp(format,"interleaved"))
+            {
+              io->interleaved = YES;
+            }
+          else if(!strcmp(format,"sequential"))
+            {
+              io->interleaved = NO;
+            }
+        }
+      
+      
+      /*! Attach a model to this io struct
+       */
+      io->mod = (t_mod *)Make_Model_Basic();
+      Set_Defaults_Model(io->mod);
+      io->mod->ras->n_catg = 1;
+      io->mod->io = io;
+      iomod = io->mod;
+
+      if(io->datatype == AA)      io->mod->ns = 20;
+      else if(io->datatype == NT) io->mod->ns = 4;
+      else assert(FALSE);
+
+      
+      /*! Attach an optimization structure to this model
+       */
+      iomod->s_opt = (t_opt *)Make_Optimiz();
+      Set_Defaults_Optimiz(iomod->s_opt);
+      
+      iomod->s_opt->opt_kappa   = NO;
+      iomod->s_opt->opt_lambda  = NO;
+      iomod->s_opt->opt_rr      = NO;
+      
+      /*! Input file
+       */
+      alignment = XML_Get_Attribute_Value(p_elem,"file.name");
+      
+      if(!alignment)
+        {
+          PhyML_Printf("\n== 'file.name' tag is mandatory. Please amend your");
+          PhyML_Printf("\n== XML file accordingly.");
+          Exit("\n");
+        }
+      
+      strcpy(io->in_align_file,alignment);
+      
+      /*! Open pointer to alignment
+       */
+      io->fp_in_align = Openfile(io->in_align_file,0);
+      
+
+      s = XML_Get_Attribute_Value(p_elem,"print.site.lk");
+      if(s)
+        {
+          select = XML_Validate_Attr_Int(s,6,
+                                         "true","yes","y",
+                                         "false","no","n");
+          if(select < 3) io->print_site_lnl = YES;
+
+          strcpy(io->out_lk_file,io->in_align_file);
+          strcat(io->out_lk_file, "_phyml_lk");
+          io->fp_out_lk = Openfile(io->out_lk_file,1);
+        }
+
+
+      /*! Load sequence file
+       */
+      io->data = Get_Seq(io);
+      
+      /*! Close pointer to alignment
+       */
+      fclose(io->fp_in_align);
+      
+      /*! Compress alignment
+       */
+      io->cdata = Compact_Data(io->data,io);
+      
+      /*! Free uncompressed alignment
+       */
+      Free_Seq(io->data,io->n_otu);
+      
+      /*! Create new mixture tree
+       */
+      buff = (t_tree *)Make_Tree_From_Scratch(io->cdata->n_otu,io->cdata);
+      
+      if(mixt_tree)
+        {
+          mixt_tree->next_mixt            = buff;
+          mixt_tree->next_mixt->prev_mixt = mixt_tree;
+          mixt_tree                       = mixt_tree->next_mixt;
+          mixt_tree->dp                   = mixt_tree->prev_mixt->dp+1;
+        }
+      else mixt_tree = buff;
+      
+      /*! Connect mixt_tree to xml struct
+       */
+      mixt_tree->xml_root = root;
+
+      /*! Connect mixt_tree to io struct
+       */
+      mixt_tree->io = io;
+      
+      /*! Connect mixt_tree to model struct
+       */
+      mixt_tree->mod = iomod;
+      
+      /*! mixt_tree is a mixture tree
+       */
+      mixt_tree->is_mixt_tree = YES;
+      
+      /*! mixt_tree is a mixture tree
+       */
+      mixt_tree->mod->is_mixt_mod = YES;
+      
+      /*! Connect mixt_tree to compressed data
+       */
+      mixt_tree->data = io->cdata;
+      
+      /*! Set total number of patterns
+       */
+      mixt_tree->n_pattern = io->cdata->crunch_len;
+      
+      /*! Remove branch lengths from mixt_tree */
+      For(i,2*mixt_tree->n_otu-1)
+        {
+          Free_Scalar_Dbl(mixt_tree->a_edges[i]->l);
+          Free_Scalar_Dbl(mixt_tree->a_edges[i]->l_old);
+          Free_Scalar_Dbl(mixt_tree->a_edges[i]->l_var);
+          Free_Scalar_Dbl(mixt_tree->a_edges[i]->l_var_old);
+        }
+      
+      /*! Connect last tree of the mixture for the
+        previous partition element to the next mixture tree
+      */
+      if(tree)
+        {
+          tree->next = mixt_tree;
+          mixt_tree->prev = tree;
+        }
+      
+      /*! Do the same for the model
+       */
+      if(mod)
+        {
+          mod->next = iomod;
+          iomod->prev = mod;
+        }
+      
+      if(!root_tree) root_tree = mixt_tree;
+      
+      /*! Tree size scaling factor */
+      char *scale_tree = NULL;
+      scale_tree = XML_Get_Attribute_Value(p_elem,"optimise.tree.scale");
+
+      if(scale_tree)
+        {
+          int select;
+          
+          select = XML_Validate_Attr_Int(scale_tree,6,
+                                         "true","yes","y",
+                                         "false","no","n");
+          
+          if(select < 3) mixt_tree->mod->s_opt->opt_br_len_mult = YES;
+        }
+      
+      scale_tree = NULL;
+      scale_tree = XML_Get_Attribute_Value(p_elem,"tree.scale");
+      
+      if(scale_tree)
+        {
+          char *scale_val;
+
+          scale_val = XML_Get_Attribute_Value(p_elem,"tree.scale");
+          if(scale_val)
+            {
+              mixt_tree->mod->br_len_mult->v          = String_To_Dbl(scale_val);
+              mixt_tree->mod->br_len_mult_unscaled->v = String_To_Dbl(scale_val);
+              Free(scale_val);
+            }
+        }
+
+      /*! Process all the mixtureelem tags in this partition element
+       */
+      n_components  = 0;
+      m_elem        = p_elem;
+      first_m_elem  = 0;
+      mod           = NULL;
+      tree          = NULL;
+      class_number  = 0;
+      do
+        {
+          m_elem = XML_Search_Node_Name("mixtureelem",YES,m_elem);
+          if(m_elem == NULL) break;
+          
+
+          if(!strcmp(m_elem->name,"mixtureelem"))
+            {
+              first_m_elem++;
+              
+              /*! Rewind tree and model when processing a new mixtureelem node
+               */
+              if(first_m_elem > 1)
+                {
+                  while(tree->prev && tree->prev->is_mixt_tree == NO) { tree = tree->prev; } 
+                  while(mod->prev  && mod->prev->is_mixt_mod == NO)   { mod  = mod->prev;  }
+                }
+              
+              /*! Read and process model components
+               */
+              char *list;
+              list = XML_Get_Attribute_Value(m_elem,"list");
+              
+              j = 0;
+              For(i,(int)strlen(list)) if(list[i] == ',') j++;
+              
+              if(j != n_components && first_m_elem > 1)
+                {
+                  PhyML_Printf("\n== Discrepancy in the number of elements in nodes 'mixtureelem' partitionelem id '%s'",p_elem->id);
+                  PhyML_Printf("\n== Check 'mixturelem' node with list '%s'",list);
+                  Exit("\n");
+                }
+              n_components = j;
+              
+              i = j = 0;
+              component[0] = '\0';
+              while(1)
+                {
+                  if(list[j] == ',' || j == (int)strlen(list))
+                    {
+                      /*! Reading a new component
+                       */
+                      
+                      if(first_m_elem == YES) /* Only true when processing the first mixtureelem node */
+                        {
+                          t_tree *this_tree;
+                          t_mod *this_mod;
+                          
+                          /*! Create new tree
+                           */
+                          this_tree = (t_tree *)Make_Tree_From_Scratch(io->cdata->n_otu,io->cdata);
+                          
+                          /*! Update the number of mixtures */
+                          iomod->n_mixt_classes++;
+                          
+                          if(tree)
+                            {
+                              tree->next = this_tree;
+                              tree->next->prev = tree;
+                            }
+                          else
+                            {
+                              mixt_tree->next = this_tree;
+                              mixt_tree->next->prev = mixt_tree;
+                            }
+                          
+                          tree = this_tree;
+                          tree->mixt_tree = mixt_tree;
+                          
+                          
+                          /*! Create a new model
+                           */
+                          this_mod = (t_mod *)Make_Model_Basic();
+                          Set_Defaults_Model(this_mod);
+                          this_mod->ras->n_catg = 1;
+                          this_mod->ns = iomod->ns;
+
+                          /*! All br_len_multiplier point to the corresponding */
+                          /*! parameter in the relevant mixt_tree */
+                          Free_Scalar_Dbl(this_mod->br_len_mult);
+                          this_mod->br_len_mult = iomod->br_len_mult;                          
+
+                          Free_Scalar_Dbl(this_mod->br_len_mult_unscaled);
+                          this_mod->br_len_mult_unscaled = iomod->br_len_mult_unscaled;                          
+                          
+                          if(mod)
+                            {
+                              mod->next = this_mod;
+                              mod->next->prev = mod;
+                            }
+                          else
+                            {
+                              this_mod->prev = iomod;
+                            }
+                          
+                          mod = this_mod;
+                          if(!iomod->next) iomod->next = mod;
+                          mod->io = io;
+                          
+                          mod->s_opt = (t_opt *)Make_Optimiz();
+                          Set_Defaults_Optimiz(mod->s_opt);
+                          
+                          mod->s_opt->opt_alpha  = NO;
+                          mod->s_opt->opt_pinvar = NO;
+                          
+                          tree->data      = io->cdata;
+                          tree->n_pattern = io->cdata->crunch_len;
+                          tree->io        = io;
+                          tree->mod       = mod;
+                          
+                          if(tree->n_pattern != tree->prev->n_pattern) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
+                        }
+                      
+                      /*! Read a component
+                       */
+                      component[i] = '\0';
+                      if(j != (int)strlen(list)-1) i = 0;
+                                            
+                      /*! Find which node this ID corresponds to
+                       */
+                      instance = XML_Search_Node_ID(component,YES,root);
+                      
+                      if(!instance)
+                        {
+                          PhyML_Printf("\n== Could not find a node with id:'%s'.",component);
+                          PhyML_Printf("\n== Problem with 'mixtureelem' node, list '%s'.",list);
+                          Exit("\n");
+                        }
+                      
+                      if(!instance->parent)
+                        {
+                          PhyML_Printf("\n== Node '%s' with id:'%s' has no parent.",instance->name,component);
+                          Exit("\n");
+                        }
+                      
+                      parent = instance->parent;
+                      
+                      ////////////////////////////////////////
+                      //        SUBSTITUTION MODEL          //
+                      ////////////////////////////////////////
+                      
+                      if(!strcmp(parent->name,"ratematrices"))
+                        {
+                          /* ! First time we process this 'instance' node which has this 'ratematrices' parent */
+                          if(instance->ds->obj == NULL)
+                            {
+                              Make_Ratematrice_From_XML_Node(instance,io,mod);
+                              
+                              ds = instance->ds;
+                              
+                              /*! Connect the data structure n->ds to mod->r_mat */
+                              ds->obj = (t_rmat *)(mod->r_mat);
+                              
+                              /*! Create and connect the data structure n->ds->next to mod->kappa */
+                              ds->next      = (t_ds *)mCalloc(1,sizeof(t_ds));
+                              ds = ds->next;
+                              ds->obj = (scalar_dbl *)(mod->kappa);
+                              
+                              /*! Create and connect the data structure n->ds->next to mod->s_opt->opt_kappa */
+                              ds->next      = (t_ds *)mCalloc(1,sizeof(t_ds));
+                              ds = ds->next;
+                              ds->obj = (int *)(&mod->s_opt->opt_kappa);
+                              
+                              /*! Create and connect the data structure n->ds->next to mod->s_opt->opt_rr */
+                              ds->next      = (t_ds *)mCalloc(1,sizeof(t_ds));
+                              ds = ds->next;
+                              ds->obj = (int *)(&mod->s_opt->opt_rr);
+                              
+                              /*! Create and connect the data structure n->ds->next to mod->whichmodel */
+                              ds->next      = (t_ds *)mCalloc(1,sizeof(t_ds));
+                              ds = ds->next;
+                              ds->obj = (int *)(&mod->whichmodel);
+                              
+                              /*! Create and connect the data structure n->ds->next to mod->modelname */
+                              ds->next      = (t_ds *)mCalloc(1,sizeof(t_ds));
+                              ds = ds->next;
+                              ds->obj = (t_string *)(mod->modelname);
+                              
+                              /*! Create and connect the data structure n->ds->next to mod->ns */
+                              ds->next      = (t_ds *)mCalloc(1,sizeof(t_ds));
+                              ds = ds->next;
+                              ds->obj = (int *)(&mod->ns);
+                              
+                              /*! Create and connect the data structure n->ds->next to mod->modelname */
+                              ds->next      = (t_ds *)mCalloc(1,sizeof(t_ds));
+                              ds = ds->next;
+                              ds->obj = (t_string *)(mod->custom_mod_string);
+
+
+                              /*! Create and connect the data structure n->ds->next to mod->fp_aa_rate_mat */
+                              ds->next      = (t_ds *)mCalloc(1,sizeof(t_ds));
+                              ds = ds->next;
+                              ds->obj = (FILE *)(mod->fp_aa_rate_mat);
+
+                              /*! Create and connect the data structure n->ds->next to mod->aa_rate_mat_file */
+                              ds->next      = (t_ds *)mCalloc(1,sizeof(t_ds));
+                              ds = ds->next;
+                              ds->obj = (t_string *)mod->aa_rate_mat_file;                              
+                            }
+                          else
+                            {
+                              /*! Connect to already extisting r_mat & kappa structs. */
+                              t_ds *ds;
+                              
+                              
+                              ds = instance->ds;
+                              Free(mod->r_mat);
+                              mod->r_mat             = (t_rmat *)ds->obj;
+                              
+                              ds = ds->next;
+                              Free_Scalar_Dbl(mod->kappa);
+                              mod->kappa             = (scalar_dbl *)ds->obj;
+                              
+                              ds = ds->next;
+                              mod->s_opt->opt_kappa  = *((int *)ds->obj);
+                              
+                              ds = ds->next;
+                              mod->s_opt->opt_rr     = *((int *)ds->obj);
+                              
+                              ds = ds->next;
+                              mod->whichmodel        = *((int *)ds->obj);
+                              
+                              ds = ds->next;
+                              Free_String(mod->modelname);
+                              mod->modelname         = (t_string *)ds->obj;
+                              
+                              ds = ds->next;
+                              mod->ns                = *((int *)ds->obj);
+                              
+                              ds = ds->next;
+                              Free_String(mod->custom_mod_string);
+                              mod->custom_mod_string = (t_string *)ds->obj;
+
+                              ds = ds->next;
+                              mod->fp_aa_rate_mat = (FILE *)ds->obj;
+
+                              ds = ds->next;
+                              Free_String(mod->aa_rate_mat_file);
+                              mod->aa_rate_mat_file = (t_string *)ds->obj;
+
+                            }
+                        }
+                      
+                      ////////////////////////////////////////
+                      //           STATE FREQS              //
+                      ////////////////////////////////////////
+                      
+                      else if(!strcmp(parent->name,"equfreqs"))
+                        {
+                          /* If n->ds == NULL, the corrresponding node data structure, n->ds, has not */
+                          /* been initialized. If not, do nothing. */
+                          if(instance->ds->obj == NULL)
+                            {
+                              Make_Efrq_From_XML_Node(instance,io,mod);
+                              
+                              t_ds *ds;
+                              
+                              ds = instance->ds;
+                              ds->obj = (t_efrq *)mod->e_frq;
+                              
+                              ds->next = (t_ds *)mCalloc(1,sizeof(t_ds));
+                              ds = ds->next;
+                              ds->obj = (int *)(&mod->s_opt->opt_state_freq);
+                              
+                              ds->next = (t_ds *)mCalloc(1,sizeof(t_ds));
+                              ds = ds->next;
+                              ds->obj = (int *)(&mod->e_frq->user_state_freq);
+                              
+                              ds->next = (t_ds *)mCalloc(1,sizeof(t_ds));
+                              ds = ds->next;
+                              ds->obj = (vect_dbl *)(mod->e_frq->user_b_freq);                              
+                            }
+                          else
+                            {
+                              /* Connect the data structure n->ds to mod->e_frq */
+                              
+                              ds = instance->ds;
+                              mod->e_frq = (t_efrq *)ds->obj;
+                              
+                              ds = ds->next;
+                              mod->s_opt->opt_state_freq = *((int *)ds->obj);
+                              
+                              ds = ds->next;
+                              mod->e_frq->user_state_freq = *((int *)ds->obj);
+                              
+                              ds = ds->next;
+                              mod->e_frq->user_b_freq = (vect_dbl *)ds->obj;
+                            }
+                        }
+                      
+                      //////////////////////////////////////////
+                      //             TOPOLOGY                 //
+                      //////////////////////////////////////////
+                      
+                      else if(!strcmp(parent->name,"topology"))
+                        {
+                          if(parent->ds->obj == NULL) Make_Topology_From_XML_Node(instance,io,iomod);
+                          
+                          ds = parent->ds;
+                          
+                          int buff;
+                          ds->obj = (int *)(& buff);
+                        }
+                      
+                      //////////////////////////////////////////
+                      //                RAS                   //
+                      //////////////////////////////////////////
+                      
+                      else if(!strcmp(parent->name,"siterates"))
+                        {
+                          char *rate_value = NULL;
+                          /* scalar_dbl *r; */
+                          phydbl val;
+                          
+
+                          /*! First time we process this 'siterates' node, check that its format is valid.
+                            and process it afterwards.
+                          */
+                          if(parent->ds->obj == NULL)
+                            {
+                              class_number = 0;
+                              
+                              Make_RAS_From_XML_Node(parent,iomod);
+                              
+                              ds = parent->ds;
+                              
+                              ds->obj = (t_ras *)iomod->ras;
+                              
+                              ds->next      = (t_ds *)mCalloc(1,sizeof(t_ds));
+                              ds = ds->next;
+                              ds->obj = (int *)(&iomod->s_opt->opt_alpha);
+                              
+                              ds->next      = (t_ds *)mCalloc(1,sizeof(t_ds));
+                              ds = ds->next;
+                              ds->obj = (int *)(&iomod->s_opt->opt_free_mixt_rates);
+                            }
+                          else /*! Connect ras struct to an already defined one. Same for opt_alpha & opt_free_mixt_rates */
+                            {
+                              if(iomod->ras != (t_ras *)parent->ds->obj) Free_RAS(iomod->ras);
+                              iomod->ras = (t_ras *)parent->ds->obj;
+                              iomod->s_opt->opt_alpha = *((int *)parent->ds->next->obj);
+                              iomod->s_opt->opt_free_mixt_rates = *((int *)parent->ds->next->next->obj);
+                            }
+                          
+                          rate_value = XML_Get_Attribute_Value(instance,"init.value");
+                          
+                          val = 1.;
+                          if(rate_value) val = String_To_Dbl(rate_value);
+                          
+                          if(instance->ds->obj == NULL)
+                            {
+                              instance->ds->obj = (phydbl *)(&val);
+                              instance->ds->next = (t_ds *)mCalloc(1,sizeof(t_ds));
+                              instance->ds->next->obj = (int *)(class_num + class_number);
+                              
+                              iomod->ras->gamma_rr->v[class_number] = val;
+                              iomod->ras->gamma_rr_unscaled->v[class_number] = val;
+                              
+                              iomod->ras->init_rr = NO;
+                              
+                              if(Are_Equal(val,0.0,1E-20) == NO) class_number++;
+                            }
+                          
+                          
+                          /*! Note: ras is already connected to the relevant t_ds stucture. No need
+                            to connect ras->gamma_rr or ras->p_invar */
+                          
+                          /*! Invariant */
+                          if(Are_Equal(val,0.0,1E-20))
+                            {
+                              mod->ras->invar = YES;
+                            }
+                          else
+                            {
+                              mod->ras->parent_class_number = *((int *)instance->ds->next->obj);
+                            }
+                          
+                          xml_node *orig_w = NULL;
+                          orig_w = XML_Search_Node_Attribute_Value("appliesto",instance->id,YES,instance->parent);
+                          
+                          if(orig_w)
+                            {
+                              char *weight;
+                              weight = XML_Get_Attribute_Value(orig_w,"value");
+                              if(mod->ras->invar == YES)
+                                {
+                                  iomod->ras->pinvar->v = String_To_Dbl(weight);
+                                }
+                              else
+                                {
+                                  int class;
+                                  class = *((int *)instance->ds->next->obj);
+                                  iomod->ras->gamma_r_proba->v[class] = String_To_Dbl(weight);
+                                  iomod->ras->init_r_proba = NO;
+                                }
+                            }
+                        }
+                      
+                      //////////////////////////////////////////////
+                      //           BRANCH LENGTHS                 //
+                      //////////////////////////////////////////////
+                      
+                      else if(!strcmp(parent->name,"branchlengths"))
+                        {
+                          int i;
+                          int n_otu;
+                          
+                          n_otu = tree->n_otu;
+                          
+                          if(instance->ds->obj == NULL)
+                            {
+                              if(!lens)
+                                {
+                                  ori_lens         = (scalar_dbl **)mCalloc(2*tree->n_otu-1,sizeof(scalar_dbl *));
+                                  ori_lens_old     = (scalar_dbl **)mCalloc(2*tree->n_otu-1,sizeof(scalar_dbl *));
+                                  
+                                  ori_lens_var     = (scalar_dbl **)mCalloc(2*tree->n_otu-1,sizeof(scalar_dbl *));
+                                  ori_lens_var_old = (scalar_dbl **)mCalloc(2*tree->n_otu-1,sizeof(scalar_dbl *));
+                                  
+                                  lens     = ori_lens;
+                                  lens_old = ori_lens_old;
+                                  
+                                  lens_var     = ori_lens_var;
+                                  lens_var_old = ori_lens_var_old;
+                                  
+                                  lens_size = 2*tree->n_otu-1;
+                                }
+                              else
+                                {
+                                  ori_lens         = (scalar_dbl **)mRealloc(ori_lens,2*tree->n_otu-1+lens_size,sizeof(scalar_dbl *));
+                                  ori_lens_old     = (scalar_dbl **)mRealloc(ori_lens_old,2*tree->n_otu-1+lens_size,sizeof(scalar_dbl *));
+                                  
+                                  ori_lens_var     = (scalar_dbl **)mRealloc(ori_lens_var,2*tree->n_otu-1+lens_size,sizeof(scalar_dbl *));
+                                  ori_lens_var_old = (scalar_dbl **)mRealloc(ori_lens_var_old,2*tree->n_otu-1+lens_size,sizeof(scalar_dbl *));
+                                  
+                                  lens     = ori_lens     + lens_size;;
+                                  lens_old = ori_lens_old + lens_size;;
+                                  
+                                  lens_var     = ori_lens_var     + lens_size;;
+                                  lens_var_old = ori_lens_var_old + lens_size;;
+                                  
+                                  lens_size += 2*tree->n_otu-1;
+                                }
+                              
+                              For(i,2*tree->n_otu-1)
+                                {
+                                  lens[i] = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl));
+                                  Init_Scalar_Dbl(lens[i]);
+                                  
+                                  lens_old[i] = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl));
+                                  Init_Scalar_Dbl(lens_old[i]);
+                                  
+                                  lens_var[i] = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl));
+                                  Init_Scalar_Dbl(lens_var[i]);
+                                  
+                                  lens_var_old[i] = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl));
+                                  Init_Scalar_Dbl(lens_var_old[i]);
+                                  
+                                  Free_Scalar_Dbl(tree->a_edges[i]->l);
+                                  Free_Scalar_Dbl(tree->a_edges[i]->l_old);
+                                  
+                                  Free_Scalar_Dbl(tree->a_edges[i]->l_var);
+                                  Free_Scalar_Dbl(tree->a_edges[i]->l_var_old);
+                                  
+                                  if(tree->prev &&
+                                     tree->prev->a_edges[i]->l == mixt_tree->a_edges[i]->l &&
+                                     tree->prev->is_mixt_tree == NO)
+                                    {
+                                      PhyML_Printf("\n== %p %p",tree->a_edges[i]->l,mixt_tree->a_edges[i]->l);
+                                      PhyML_Printf("\n== Only one set of edge lengths is allowed ");
+                                      PhyML_Printf("\n== in a 'partitionelem'. Please fix your XML file.");
+                                      Exit("\n");
+                                    }
+                                }
+                              
+                              char *opt_bl = NULL;
+                              opt_bl = XML_Get_Attribute_Value(instance,"optimise.lens");
+                              
+                              if(opt_bl)
+                                {
+                                  if(!strcmp(opt_bl,"yes") || !strcmp(opt_bl,"true"))
+                                    {
+                                      iomod->s_opt->opt_bl = YES;
+                                    }
+                                  else
+                                    {
+                                      iomod->s_opt->opt_bl = NO;
+                                    }
+                                }
+                              
+                              ds = instance->ds;
+                              
+                              ds->obj       = (scalar_dbl **)lens;
+                              
+                              ds->next      = (t_ds *)mCalloc(1,sizeof(t_ds));
+                              ds            = ds->next;
+                              ds->obj       = (scalar_dbl **)lens_old;
+                              
+                              ds->next      = (t_ds *)mCalloc(1,sizeof(t_ds));
+                              ds            = ds->next;
+                              ds->obj       = (scalar_dbl **)lens_var;
+                              
+                              ds->next      = (t_ds *)mCalloc(1,sizeof(t_ds));
+                              ds            = ds->next;
+                              ds->obj       = (scalar_dbl **)lens_var_old;
+                              
+                              ds->next      = (t_ds *)mCalloc(1,sizeof(t_ds));
+                              ds            = ds->next;
+                              ds->obj       = (int *)(&iomod->s_opt->opt_bl);
+                            }
+                          else
+                            {
+                              For(i,2*tree->n_otu-1)
+                                {
+                                  Free_Scalar_Dbl(tree->a_edges[i]->l);
+                                  Free_Scalar_Dbl(tree->a_edges[i]->l_old);
+                                  Free_Scalar_Dbl(tree->a_edges[i]->l_var);
+                                  Free_Scalar_Dbl(tree->a_edges[i]->l_var_old);
+                                }
+                              
+                              ds = instance->ds;
+                              
+                              lens     = (scalar_dbl **)ds->obj;
+                              
+                              ds = ds->next;
+                              lens_old = (scalar_dbl **)ds->obj;
+                              
+                              ds = ds->next;
+                              lens_var = (scalar_dbl **)ds->obj;
+                              
+                              ds = ds->next;
+                              lens_var_old = (scalar_dbl **)ds->obj;
+                              
+                              ds = ds->next;
+                              iomod->s_opt->opt_bl = *((int *)ds->obj);
+                            }
+                          
+                          if(n_otu != tree->n_otu)
+                            {
+                              PhyML_Printf("\n== All the data sets should display the same number of sequences.");
+                              PhyML_Printf("\n== Found at least one data set with %d sequences and one with %d sequences.",n_otu,tree->n_otu);
+                              Exit("\n");
+                            }
+                          
+                          For(i,2*tree->n_otu-1)
+                            {
+                              tree->a_edges[i]->l          = lens[i];
+                              mixt_tree->a_edges[i]->l     = lens[i];
+                              tree->a_edges[i]->l_old      = lens_old[i];
+                              mixt_tree->a_edges[i]->l_old = lens_old[i];
+                              
+                              tree->a_edges[i]->l_var          = lens_var[i];
+                              mixt_tree->a_edges[i]->l_var     = lens_var[i];
+                              tree->a_edges[i]->l_var_old      = lens_var_old[i];
+                              mixt_tree->a_edges[i]->l_var_old = lens_var_old[i];
+                            }
+                        }
+                      
+                      ///////////////////////////////////////////////
+                      ///////////////////////////////////////////////
+                      ///////////////////////////////////////////////
+                      
+                      if(first_m_elem > 1) // Done with this component, move to the next tree and model
+                        {
+                          if(tree->next) tree = tree->next;
+                          if(mod->next)   mod  = mod->next;
+                        }
+                      
+                    }
+                  else if(list[j] != ' ')
+                    {
+                      component[i] = list[j];
+                      i++;
+                    }
+                  j++;
+                  if(j == (int)strlen(list)+1) break;
+                  
+                } // end of mixtureelem processing
+            } // end of partitionelem processing
+        }
+      while(1);
+    }
+  while(1);
+  
+  
+  if(ori_lens)         Free(ori_lens);
+  if(ori_lens_old)     Free(ori_lens_old);
+  if(ori_lens_var)     Free(ori_lens_var);
+  if(ori_lens_var_old) Free(ori_lens_var_old);
+
+  while(io->prev != NULL) io = io->prev;
+  while(mixt_tree->prev != NULL) mixt_tree = mixt_tree->prev;
+
+  /*! Finish making the models */
+  mod = mixt_tree->mod;
+  do
+    {
+      Make_Model_Complete(mod);
+      mod = mod->next;
+    }
+  while(mod);
+
+  Check_Taxa_Sets(mixt_tree);
+
+  Check_Mandatory_XML_Node(root,"phyml");
+  Check_Mandatory_XML_Node(root,"topology");
+  Check_Mandatory_XML_Node(root,"branchlengths");
+  Check_Mandatory_XML_Node(root,"ratematrices");
+  Check_Mandatory_XML_Node(root,"equfreqs");
+  Check_Mandatory_XML_Node(root,"siterates");
+  Check_Mandatory_XML_Node(root,"partitionelem");
+  Check_Mandatory_XML_Node(root,"mixtureelem");
+
+  if(!io->mod->s_opt->random_input_tree) io->mod->s_opt->n_rand_starts = 1;
+
+  Free(component);
+  Free(class_num);
+
+  fclose(fp);
+  return mixt_tree;
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
 xml_node *XML_Load_File(FILE *fp)
 {
   int c;
@@ -517,7 +1604,6 @@ xml_node *XML_Search_Node_Generic(char *nd_name, char *attr_name, char *attr_val
 
 xml_node *XML_Search_Node_Name(char *name, int skip, xml_node *node)
 {
-
   xml_node *match;
   
   /* printf("\n. name:%s child:%s next:%s ", */
@@ -525,6 +1611,7 @@ xml_node *XML_Search_Node_Name(char *name, int skip, xml_node *node)
   /*     node->child?node->child->name:"xx", */
   /*     node->next?node->next->name:"xx"); fflush(NULL); */
 
+  assert(node);
 
   match = NULL;
   if(skip == NO && !strcmp(node->name,name)) match = node;
@@ -562,7 +1649,7 @@ xml_node *XML_Search_Node_ID(char *id, int skip, xml_node *node)
   
   if(!node)
     {
-      PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__);
+      PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__);
       Exit("\n");         
     }
       
@@ -1024,6 +2111,7 @@ void XML_Write_XML_Node(FILE *fp, int *indent, xml_node *root)
 }
 
 //////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
 
 void Check_Mandatory_XML_Node(xml_node *root, char *name)
 {
@@ -1035,11 +2123,63 @@ void Check_Mandatory_XML_Node(xml_node *root, char *name)
     }
 }
 
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
 
-
+int XML_Number_Of_Taxa_In_Clade(xml_node *n_clade)
+{
+  int clade_size = 0;
+  if(n_clade)
+    {
+      do
+        {
+          clade_size++; 
+          if(n_clade->next) n_clade = n_clade -> next;
+          else break;
+        }
+      while(n_clade);
+    }
+  else
+    {
+      PhyML_Printf("\n== Clade is empty.");
+      PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__);
+      Exit("\n");
+    }
+  return(clade_size);
+}
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
+
+char **XML_Read_Clade(xml_node *xnd_clade, t_tree *tree)
+{
+  int i;
+  char **clade;
+
+  clade = (char **)mCalloc(tree->n_otu, sizeof(char *));
+
+  if(xnd_clade)
+    {
+      i = 0;
+      do
+        {
+          clade[i] = xnd_clade->attr->value; 
+          i++;
+          if(xnd_clade->next) xnd_clade = xnd_clade->next;
+          else break;
+        }
+      while(xnd_clade);
+    }
+  else
+    {
+      PhyML_Printf("== Clade is empty. \n");
+      PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__);
+      Exit("\n");
+    }
+
+  return(clade);                          
+}
+
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
diff --git a/src/xml.h b/src/xml.h
index 28aa6b8..8b46f96 100644
--- a/src/xml.h
+++ b/src/xml.h
@@ -36,6 +36,9 @@ xml_node *XML_Copy_XML_Graph(xml_node *root);
 void XML_Copy_XML_Node(xml_node *cpy_root, xml_node *root);
 void Check_Mandatory_XML_Node(xml_node *root, char *name);
 xml_node *XML_Search_Node_Generic(char *nd_name, char *attr_name, char *attr_val, int skip, xml_node *node);
+t_tree *XML_Process_Base(char *xml_filename);
+int XML_Number_Of_Taxa_In_Clade(xml_node *n_clade);
+char **XML_Read_Clade(xml_node *n_clade, t_tree *tree);
 
 
 #endif

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



More information about the debian-med-commit mailing list