[med-svn] [phyml] 03/05: New upstream version 3.3.20170530+dfsg

Andreas Tille tille at debian.org
Sat Jun 24 09:44:18 UTC 2017


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

tille pushed a commit to branch master
in repository phyml.

commit 19154598e4067377d8317d256598280f3e7ebf5a
Author: Andreas Tille <tille at debian.org>
Date:   Sat Jun 24 11:17:04 2017 +0200

    New upstream version 3.3.20170530+dfsg
---
 ChangeLog                                 |  347 --
 NEWS                                      |    0
 README                                    |   31 +-
 autogen.sh                                |    0
 config.h.in                               |   10 +-
 configure.ac                              |   74 +-
 doc/fig/phyrexlog.pdf                     |  Bin 0 -> 463638 bytes
 doc/phyml-manual.pdf                      |  Bin 407931 -> 870332 bytes
 doc/phyml-manual.tex                      |  567 ++--
 doc/ref.bib                               |  190 +-
 examples/phyrex_input_files/h1n1.nxs      |  613 ++++
 examples/phyrex_input_files/usa_coord.txt |   53 +
 src/Makefile.am                           |  171 +-
 src/alrt.c                                |  401 +--
 src/avx.c                                 |  424 +++
 src/avx.h                                 |   39 +
 src/beagle_utils.c                        |    8 +-
 src/bionj.c                               |   26 +-
 src/cl.c                                  |  171 +-
 src/cl.h                                  |    1 +
 src/date.c                                | 1249 +++++++
 src/date.h                                |   44 +
 src/draw.c                                |   14 +-
 src/eigen.c                               |   70 +-
 src/free.c                                |  382 ++-
 src/free.h                                |   14 +-
 src/geo.c                                 |  139 +-
 src/help.c                                |    2 +-
 src/init.c                                |  526 +--
 src/init.h                                |   11 +-
 src/interface.c                           |   92 +-
 src/invitee.c                             |  191 +-
 src/invitee.h                             |    2 +-
 src/io.c                                  | 2708 ++++++---------
 src/io.h                                  |   12 +-
 src/lk.c                                  | 3630 ++++++++++----------
 src/lk.h                                  |   75 +-
 src/m4.c                                  |  230 +-
 src/m4.h                                  |    4 +-
 src/main.c                                |  104 +-
 src/make.c                                |  325 +-
 src/make.h                                |   13 +-
 src/mcmc.c                                | 4294 +++++++++++++++++-------
 src/mcmc.h                                |   15 +-
 src/mg.c                                  | 2820 ----------------
 src/mg.h                                  |   51 -
 src/mixt.c                                | 1986 ++++++++---
 src/mixt.h                                |   39 +-
 src/models.c                              |  569 ++--
 src/models.h                              |    5 +-
 src/mpi_boot.c                            |  138 +-
 src/nexus.c                               |   12 +-
 src/optimiz.c                             | 1735 +++++-----
 src/optimiz.h                             |   10 +-
 src/pars.c                                |  497 ++-
 src/pars.h                                |    7 +-
 src/phyrex.c                              | 1598 ++++++---
 src/phyrex.h                              |    5 +-
 src/rates.c                               |  635 ++--
 src/rates.h                               |    2 +
 src/rwrapper.c                            |    6 +-
 src/simu.c                                | 1118 ++++---
 src/simu.h                                |    1 +
 src/spr.c                                 | 5201 ++++++++---------------------
 src/spr.h                                 |   19 +-
 src/sse.c                                 |  406 +++
 src/sse.h                                 |   36 +
 src/stats.c                               |  606 ++--
 src/stats.h                               |    2 +-
 src/times.c                               | 1001 ++++--
 src/times.h                               |    8 +-
 src/tiporder.c                            |  122 +-
 src/utilities.c                           | 4849 +++++++++++++++------------
 src/utilities.h                           |  429 ++-
 src/xml.c                                 | 1169 ++++++-
 src/xml.h                                 |    3 +
 76 files changed, 22970 insertions(+), 19387 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 9b292c5..e69de29 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,347 +0,0 @@
-
-Version  date		what has been changed
-
-5.0       26.08.2000    - changes to manual, Makefile.in
-                        - cpREV hidden by -DCPREV flag
-                        - chi2test, quartio included into source code files
-                        - generic scr/Makefile.generic
-                        - src/makefile.com for VAX
-			- AUTHORS, README, ChangeLog updated
-			- INSTALL checked
-          27.08.2000	- test code excluded
-			- '-randseed#' added for debugging purposes
-			- ./align added to autoconf/automake
-			- warning output if cmdline parameter unknown
-          11.10.2000	- fixed output of rate categories of sites before 
-			  computing them
-			- check whether rate categories were computed by
-			  1st user tree or NJ tree fixed in the output
-          12.10.2000	- invariant site model normalization fixed
-
-
-CODE FREEZE
-===========
-
-5.0.a33   15.08.2000    - changes for autoconf/automake
-
-5.0.a32   01.08.2000	- a FPE error fixed (badq == 0)
-			- small error in -bestq fixed
-			- fflush's added at several places
-
-5.0.a31   01.08.2000	- comments added to tree structure sorting puzzle2.c
-			- changes in configure.in, Makefile.in
-
-5.0.a30   23.07.2000	- some debugging in checkquart
-			- changed to autoconf
-
-5.0.a29   13.07.2000	- some debugging in checkquart
-
-5.0.a28   13.07.2000	- use best quartet topology option (-bestq) implemented
-
-5.0.a27   13.07.2000	- further developement to checkquart 
-			- ascii/binary quartet values (-wqla/-wqlb)
-			- typo correction
-
-5.0.a26   11.07.2000	- fflush at all checktimer 
-			- further developement at checkquart
-			- possibility to write quartet values to file (-wqlh)
-
-5.0.a25   06.07.2000	- fflush at checktimer 
-
-5.0.a24   02.07.2000	- further debugging of checkquart 
-
-5.0.a23   02.07.2000	- further developement to checkquart 
-
-5.0.a22   29.06.2000	- checkquart added to makefile
-			- bad quartet stats added after reading in *.allquarts
-
-5.0.a21   27.06.2000	- site pattern statistics implemented and added to 
-			  SEQUENCE ALIGNMENT section in puzzle report
-
-5.0.a20   26.06.2000	- cpREV45 implemented
-
-5.0.a19   26.06.2000	- for debugging purposes: typo "MPE" changed to "FPE"
-			- fflush(stdout) added in chi2test
-
-5.0.a18   20.06.2000	- checkquart implemented
-
-5.0.a17   19.06.2000	- FPRINTF(STDOUTFILE and STDOUT definition changed 
-			  and moved; fputid/fputid10 writes to STDOUT instead
-			  of stdout
-			- ppuzzle checks slaves enough slave-processes
-			- numquarts, num2quart, quart2num moved from ppuzzle.c
-			  to puzzle1.c
-			- read/writeallquart implemented (undocumented feature)
-			  to be used by -wqf/-rqf at comandline
-			  -wqf = write quartet file (infilename.allquart) after
-			         quartet evaluation
-			  -rqf = read quartet file (infilename.allquart), no
-			         quartet evaluation, unless -wqf is used as
-			         well, then quartets are written and read in 
-			- '-h' option at comandline -> printusage
-
-5.0.a16   31.05.2000	- chi2test bug fixed
-			- WAG matrix added, model choice adopted
-	  13.06.2000	- date set to June 2000
-			- author order changed to Schmidt, Strimmer, Vingron,
-			  v.Haeseler
-			- CPU time output stopped, due to overflow errors
-	  16.06.2000	- sequence composition chi2test moved before
-			  parameter output.
-			- output of chi2test and bad quartet statistics split,
-			  to do the chi2test output earlier.
-
-5.0.a15   02.05.2000	- Names changed back from TREE-PUZZLE to PUZZLE
-          09.05.2000	- and to TREE-PUZZLE again ;-)
-
-5.0.a14   13.03.2000	- Changes to the manual.
-			- Executable names changed to (p)treepuzzle. 
-			  (changes in the makefiles)
-          15.03.2000	- Output of parameters after estimation added.
-
-5.0.a13   18.02.2000	- ALPHA version number removed from the code 
-
-5.0.a12   18.02.2000	- CPU time measurement problems fixed for case where
-			  clock_t is an unsigned type.
-
-5.0.a11   17.02.2000	- time measure problems (CPU/wallclock) fixed
-			  not all features in addtimes are used at the moment.
-			- unnecessary and unused routines removed fron source 
-			  code.
-
-5.0.a10   20.01.2000	- Name changes from PUZZLE to TREE-PUZZLE
-			- Chi2-fit model guessing for VT model added
-			- little model printing bug fixed
-
-5.0.a9    22.12.1999	- VT Model incorporated (Mueller, Vingron (2000) 
-			  JCB, to appear).
-			- TODO: Chi2-fit model guessing for VT model
-
-5.0.a8    21.12.1999	- 'sys/times.h' and 'sys/types.h' removed from
-			  puzzle.h. They were neither ANSI conform nor
-			  necessary, but occured in the SUN man pages.
-			- Definition and call of writetimesstat eliminated
-			  from the sequention version by compiler switched,
-			  and not just the function body as before.
-			- '-O4' canged to '-O' to be more generic.
-
-5.0.a7    21.12.1999	- Macro constants introduced for data_optn
-			  (NUCLEOTIDE, AMINOACID, BINARY)
-			- round robbing of datatype and AA model option changed 
-			  in menu to make adjustment of the model possible by a
-			  determined sequence of letters:
-			  'd':  Auto -> Nucleotides 
-			             -> Amino acids
-			             -> Binary states 
-			             -> Auto
-			  ('m' && data_optn == AMINOACID):  
-			        Auto -> Dayhoff
-			             -> JTT 
-			             -> mtREV24 
-			             -> BLOSUM62 
-			             -> Auto 
-			- manual.html adjusted
-
-5.0.a6    20.12.1999	- new manual.html added
-
-5.0.a5    07.12.1999	- output bug fixed (bestrates were written before they
-			  were computed)
-
-5.0.a4    02.12.1999	- header file inclusion ajusted:
-			  added:  #include<string.h>
-			  changed from:  #include "ppuzzle.h"
-			          to:    #ifdef PARALLEL
-			                 #  include "ppuzzle.h"
-			                 #endif
-
-5.0.a3    27.11.1999	- '-h' comandline option removed, because of problems
-			  with MPICH under LINUX
-			- new memory leaks of 5.0.a2 closed in PP_Finalize
-
-5.0.a2    27.11.1999	- Cleanup of the source code
-			- Measurement of CPU time added
-			- Parallel load statistics added (quartets, trees, time)
-			  to puzzle report.
-			- Cleanup debug messages
-			- Comments "[...]" are removed from usertrees now.
-			- single quotes will only be printed arount species 
-			  names if -DUSEQUOTES is set at compiletime.
-			- tree likelihood is printed infront of a tree as a
-			  comment, [ lh=-xx.xxxxx ](...);
-
-5.0.a1    26.11.1999	- Cleanup of the directories
-			- Copyright changes
-			- Version changes
-
-
-VERSION CHANGE
-==============
-
-4.1.a26   25.11.1999	- Makefile made universal for pauzzle and ppuzzle
-			- lines not needed removed from puzzle.h
-
-4.1.a25   19.11.1999	- Output file prefixes for distances, trees, and 
-			  puzzlereport changed in user trees analysis case 
-			  to user tree file name
-			- Temporary output of likelihood to treefile added
-
-4.1.a24   11.11.1999	- Output of puzzling step trees changed
-			  ptorder: [ orderno # % ID #UniqTopos #Steps ]PHYLIP
-			  pstep:   chunk #InChunk sum ID #UniqTopos #Steps
-			- preliminary leap frog RNG implemented, i.e. uses
-			  the rand4 in the usual way in the sequential case.
-			  If run in parallel all rand4 are initialized with
-			  the same seed and started with PP_Myid-th random
-			  number. after that each process uses the every
-			  PP_NumProcs-th random number to make sure that these
-			  unique.
-
-4.1.a23   08.11.1999	- output of sequential and parallel version to *.pstep
-			  made identical
-
-4.1.a22   05.11.1999	- two different puzzle step tree outputs intruduced
-			  and added to the menu ("[ 1. 35 ](...);":
-			  - ordered unique tree list -> *.ptorder 
-			    Format: "[ 1. 35 ]"  (Ordernumber, Amount)
-			  - chronological tree list  -> *.pstep
-			    Format: "[ 1. 35 ]"  (Chunknumber, Amount in chunk)
-			  (the last is a problem in parallel, because the come
-			  in chunks, as scheduled)
-			- debugged the output
-4.1.a21   04.11.1999	- Makefile adjustments for other Plattforms
-			- pstep tree output changed. unique treestructures
-			  printed to *.pstep file with a leading comment
-			  containing an order number and the ammount padded
-			  with blanks (e.g. "[ 1. 356 ]('mouse'...").
-			  output is done right before writing the puzzle file.
-			- controlled MPI finish to the Quit menu option added
-
-4.1.a20   03.11.1999	- some garbage collection (free) added
-			- makefile adjusted, OFLAGS for optimization added
-			  (ppuzzle/MPICH has problems with -O, so the
-			  ppuzzle is created without optimization)
-			  Some minor changes in the makefiles
-			- still to do: garbage collection from 'internalnode'
-			  in master process
-
-4.1.a19   13.10.1999	- adding the output of standardized (i.e. sorted) 
-			  puzzling step trees. Those are printed to the 
-			  standard output at the moment. (Routines to sort 
-			  and print the trees implemented)
-	  14.10.1999	- routines for printing the sorted trees to a string.
-			  needed to send them between Master and Worker, and
-			  to have a unique key to sort and count the trees.
-          21.10.1999	- counting of sorted trees implemented by doubly linked
-			  list, sort routine, print to stdout
-          25.10.1999	- change place of writing distances to file right after 
-			  distances have been computed.
-			- output of puzzling step trees now with true name, 
-			  not numbers
-          02.11.1999	- parallel counting and sending of puzzling step trees
-			- some parallel sending bugs fixed
-
-4.1.a18   14.09.1999	- adding possibility to specify input file at 
-			  command line, this specifies also the output
-			  filenames (puzzle output: *.puzzle; treefile:
-			  *.tree; distances: *.dist; Triangel EPS: *.eps;
-			  unresolved: *.qlist; puzzling step trees: *.pstep)
-			  If an unexisting name is given, one has to reenter
-			  the right name, but the wrong one is used as prefix.
-          15.09.1999	- sending back of bad quartets from slaves added
-			- bug in quart2num fixed (not used before; was shifted 
-			  by 1)
-			- first version of a README added ;-)
-
-4.1.a17   03.08.1999	- Recv-Error in receiving DoPuzzleBlock fixed
-			- double freeing of same MPI_Datatype fixed
-			- changing of scheduling algorithm to smaller chunks 
-			  in gss -> sgss
-          13.09.1999	- bug fixed in optimization routine in ml2.c:
-			  boundary check added
-
-4.1.a16   12.07.1999	- slight changes in verbosity levels
-			- changed all printf to FPRINTF(STDOUTFILE to
-			  change easily from stdout to a file.
-
-4.1.a15   08.07.1999	- scheduler for both parallel parts
-			- several small changes
-
-4.1.a14   25.06.1999	- computation of tree parallel, scheduler dependent,
-			  sending all biparts in one message instead of one
-			  by one 
-			- several small changes since a13 in sched.c, et al.
-
-4.1.a13   10.06.1999	- computation of tree parallel (chunk = #trees/#slaves)
-			- scheduling schemes implemented for minimum chunk sizes
-
-4.1.a12   07.06.1999	- computation of quartets properly parallel
-			- scheduling implemented
-			- counting of quartets by slave ajusted
-			- TODO: sending of bad quartets (array + list)
-			- distinction between '1st user tree' and 'NJ tree'
-			  in result output removed again
-
-4.1.a11   28.05.1999	- PP_SendDoQuartBlock, PP_RecvDoQuartBlock,
-			  PP_SendQuartBlock, PP_RecvQuartBlock
-			- mallocquartets() changed from global to local
-			  variables to be more flexible
-			- Quartet computation moved to slave (badquartet
-			  handling missing: output, badquartet vector);
-			- distinction between '1st user tree' and 'NJ tree'
-			  added in result output (puzzle1.c around l.1756)
-
-4.1.a10   20.05.1999	- num2quart, numquarts, quart2num introduced
-			- parallel init/finalize, quartets computed on
-			  master and slave, compared -> equal -> all necessary
-			  parameter exported
-
-4.1.a9    19.05.1999	- 'dvector forg' removed from onepamratematrix
-			  cmdline, because it's not used in the function.
-
-4.1.a8    18.05.1999	- add _GAMMA_ (not necessary) to gamma.h and _PUZZLE_
-			  to puzzle.h to avoid dublicate includes, possible
-			  due to ppuzzle.h
-			- ppuzzle added to makefile and to check
-			- 1st parallel version but no slave computations
-			  only sending parameters and done signals.
-
-4.1.a7    18.05.1999	- export reevaluation of tree and evaluation of
-			  usertrees to evaluatetree.
-
-4.1.a6    17.05.1999	- -DNEWFORLOOP added to fixed.src, because the changed
-			  for loop structure changes the sequence of randomized 
-			  quartets during likelihood mapping
-			- change 'int main()' to 'int main(argc, argv)'
-			- export more functionalities from main:
-			  memcleanup(), inputandinit(&argc, &argv)
-			- grouping if's (excluding eachother) together in 
-			  switch() 
-			- split treereavaluation and 1st usertree, 
-			  evaluate all usertrees together (TODO: both,
-			  treereavaluation and usertrees in one loop)
-			- MAKE CHECK added to ./makefile
-
-4.1.a5    16.05.1999	- adding �dvector Brnlength� to lslength cmdline to 
-			  reduce globality of Brnlength. (Later better to *Tree)
-
-4.1.a4    11.05.1999	- structure of for loops changed in computeallquartets
-			  and recon_tree, so that the quarted addresses are in 
-			  one contigous sequence (for a<b<c<d). This reduces 
-			  swapping on low memory machines and is easier to 
-			  parallelize.
-
-4.1.a3    07.05.1999	- export likelihood mapping from main to map_lklhd()
-			- export tree reconstuction from main to recon_tree()
-
-4.1.a2    06.05.1999	- moving all quartet_(a)lklhd calls to a general 
-			  purpose routine compute_quartlklhds()
-
-4.1.a1   06.05.1999	- Macro constants for typ_optn and puzzlemode
-			  for better readability.
-			- Ring counter for typ_optn and puzzlemode in
-			  the menu realized with mod (%) instead of IF.
-			- Possibility added to switch to a fixed random 
-			  seed (-1) or/and fixed 'random' integers (0)
-			  by using -DFIXEDRANDSEED and -DFIXEDINTRAND options.
-
-
diff --git a/NEWS b/NEWS
deleted file mode 100644
index e69de29..0000000
diff --git a/README b/README
index ee27cf1..3499a93 100644
--- a/README
+++ b/README
@@ -3,30 +3,39 @@
 // 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 compile a Windows executable, install MinGW and run:
+./configure --enable-win --enable-XXXX;
 make;
 
-
-To install PhyTime, type the following commands:
-./configure --enable-phytime;
+To install the MPI version of PhyML, type the following commands:
+./configure --enable-mpi --enable-phyml;
 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.
 
-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;
 
 
 //////////////////////////////////////////////////////////////////////////
 //                    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 or running a Unix-like operating system, you will need 
+to install the packages autoconf automake and pkg-config. On a Mac, the following command 
+should set you up (provided Homebrew is installed on your Mac...): brew install pkg-config
+autoconf automake;
+
+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..14ab5d1 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
 
@@ -15,9 +18,6 @@
 /* GEO tag on */
 #undef GEO
 
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#undef HAVE_DLFCN_H
-
 /* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
 #undef HAVE_DOPRNT
 
@@ -86,10 +86,6 @@
 /* INVITEE tag on */
 #undef INVITEE
 
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
-   */
-#undef LT_OBJDIR
-
 /* m4 tag on */
 #undef M4
 
diff --git a/configure.ac b/configure.ac
index b5d1d7d..c44cb77 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.3." | 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])
@@ -46,61 +47,61 @@ AC_FUNC_SETVBUF_REVERSED
 AC_FUNC_VPRINTF
 AC_CHECK_FUNCS([floor pow rint sqrt strchr strstr])
 
-# Thanks for Charles Plessy from Debian
-case "${host}" in
-*i386*|*amd64*|*x86_64*)
-MSSE=-msse
-AC_MSG_NOTICE("On arch ${host} use MSSE = ${MSSE}")
-;;
-*)
-MSSE=
-AC_MSG_NOTICE("Do not use MSSE = ${MSSE} because not available on arch ${host}")
-;;
-esac
-
-dnl CFLAGS="-O3 -fomit-frame-pointer -funroll-loops -Wall ${ARCH_flag}"
-dnl CFLAGS="-O3 -Wfloat-equal -fomit-frame-pointer -funroll-loops"
-dnl CFLAGS="-O3 -Wfloat-equal"
-dnl CFLAGS="-g"
+VECTOR_FLAG=-march=native
+dnl VECTOR_FLAG=-msse3
+dnl VECTOR_FLAG=-mavx
+dnl VECTOR_FLAG=
 
 LDFLAGS="${ARGC_flag}" 
 
-LT_INIT
-AC_PROG_LIBTOOL
-dnl Add option for compiling with debugging informations
+dnl Uncomment two rows below when compiling rwarp (need to have libtool installed)
+dnl LT_INIT
+dnl AC_PROG_LIBTOOL
+
+dnl DEFAULT_C_FLAG="-O2 -fomit-frame-pointer -funroll-loops -Wall -Winline --param large-stack-frame=1024 --param max-inline-insns-single=1000 --param inline-unit-growth=1001 ${VECTOR_FLAG}"
+DEFAULT_C_FLAG="-std=c99 -O2 -fomit-frame-pointer -funroll-loops -Wall -Winline ${VECTOR_FLAG}"
+dnl DEFAULT_C_FLAG="-O2 -Wall -Winline ${VECTOR_FLAG}"
+dnl DEFAULT_C_FLAG="-O3 -Wall ${VECTOR_FLAG}"
 
 AC_ARG_ENABLE([debug],
               [AS_HELP_STRING([--enable-debug],
                               [Remove optimization options and add debug informations.])])
 AS_IF([test "x$enable_debug" = "xyes"],
-      [CFLAGS="-ansi -pedantic -Wall -std=c99 -O0 -g -Wuninitialized"],
-      [CFLAGS="-Wall -O2 ${MSSE} -fomit-frame-pointer -funroll-loops -Wempty-body -Wuninitialized ${ARCH_flag}"])
+      [CFLAGS="-ansi ${VECTOR_FLAG} -pedantic -Wall -std=c99 -O0 -g -Wuninitialized"],
+      [CFLAGS="${DEFAULT_C_FLAG}"])
+
+AC_ARG_ENABLE([safemode],
+        AS_HELP_STRING([--enable-safemode],[Enable safe mode.]))
+AS_IF([test "x$enable_safemode" = "xyes"],
+      [CFLAGS="-Wall -DSAFEMODE -O3 ${VECTOR_FLAG}"],
+      [AS_IF([test "x$enable_debug" = "xno"],[CFLAGS="${DEFAULT_C_FLAG}"])])
 
 AC_ARG_ENABLE([gprof],
               [AS_HELP_STRING([--enable-gprof],
                               [Remove optimization options and add profiling informations.])])
 AS_IF([test "x$enable_gprof" = "xyes"],
-      [CFLAGS="-ansi -pedantic -Wall -std=c99 -O0 -g -pg"],
-      [AS_IF([test "x$enable_debug" = "xno"],[CFLAGS="-Wall -O2 -msse -fomit-frame-pointer -funroll-loops ${ARCH_flag}"])])
+      [CFLAGS="-g -pg -fno-inline ${VECTOR_FLAG}"],
+      [AS_IF([test "x$enable_debug" = "xno"],[CFLAGS="${DEFAULT_C_FLAG}"])])
 
 AC_ARG_ENABLE([mpi],
               [AS_HELP_STRING([--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])
 AS_IF([test "x$enable_beagle" = "xyes"],[PKG_CHECK_MODULES(BEAGLE, hmsbeagle-1)])
 AS_IF([test "x$enable_beagle" = "xyes"],
-      [CFLAGS="${CFLAGS} ${BEAGLE_CFLAGS} ${BEAGLE_LIBS} -lstdc++ ${ARCH_flag}"],
+      [CFLAGS="${CFLAGS} ${BEAGLE_CFLAGS} ${BEAGLE_LIBS} -lstdc++"],
       [CFLAGS=${CFLAGS}])
 AS_IF([test "x$enable_beagle" = "xyes"], AC_DEFINE([BEAGLE],[1],[BEAGLE tag on]))
 AM_CONDITIONAL([WANT_BEAGLE], [test "$enable_beagle" = yes])
@@ -112,6 +113,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,13 +192,23 @@ 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}"])
+dnl AS_IF([test "x$enable_phyrex" = "xyes"],[CFLAGS="${CFLAGS} `pkg-config --cflags --libs gtk+-3.0`"])
 
 
 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..7da815b 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..f994d1e 100644
--- a/doc/phyml-manual.tex
+++ b/doc/phyml-manual.tex
@@ -26,10 +26,11 @@
   \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}
-\hypersetup{colorlinks=true,linkcolor=blue,urlcolor=red}
+\hypersetup{colorlinks=true,linkcolor=blue,urlcolor=orange}
 \renewcommand{\baselinestretch}{1.}
 \makeindex
 \begin{document}
@@ -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
@@ -1469,7 +1489,9 @@ region usually have similar  GC contents). As a consequence, some components  of
 to be  estimated separately for each  partition element while  others should be shared  by different
 partition elements.
 
-Below is a simple example with a partitionned data set made of two elements:
+Below is a simple example with a partitionned data set made of two elements, corresponding to the
+sequence alignment files \x{nucleic1.txt} and \x{nucleic2.txt}. Importantly, the number and names of
+sequences in these two alignments have to match exactly. 
 
 \vspace{0.2cm}
 \begin{Verbatim}[frame=single, label=Two sets of branch lengths (one per partition element),
@@ -1590,8 +1612,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 +1638,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 +1804,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
@@ -1985,7 +2013,8 @@ and use it as a template to fit this model to another data set.
 
 The example below gives  the complete XML file to specify the analysis  of three partition elements,
 corresponding to the nucleotide  sequence files \x{small\_p1\_pos1.seq}, \x{small\_p1\_pos2.seq} and
-\x{small\_p1\_pos3.seq} in  interleaved PHYLIP  format. \x{small\_p1\_pos1.seq}  is fitted  with the
+\x{small\_p1\_pos3.seq} in  interleaved PHYLIP  format. Importantly, the number and names of
+sequences in these three alignments match exactly. \x{small\_p1\_pos1.seq}  is fitted  with the
 HKY85 model of substitution (with the  transition/transversion ratio being estimated from the data),
 combined to a $\Gamma4$  model of rate variation across sites (with the  gamma shape parameter being
 estimated from the data).  \x{small\_p1\_pos2.seq} is fitted to a custom substitution model with the
@@ -2132,12 +2161,7 @@ likelihood  phylogenies.  Installing these  tools  and  processing data  sets  i
 following sections.
 
 \subsection{PhyTime}\index{PhyTime} PhyTime is  a program that estimates node  ages and substitution
-rates using a Bayesian  approach.  The performance and main features of  this software are described
-in two article (see Section \ref{sec:citephytime}).
-
-It  relies on  a  Gibbs  sampler which  outperforms  the
-``standard'' Metropolis-Hastings algorithm  implemented in a number of  phylogenetic softwares.  The
-details  and performance  of  this  approach are  described  in the  following  article:
+rates using a Bayesian  approach. This software served as a basis to perform the research in the following three articles: \cite{guindon10,guindon13,guindon17},
 
 \subsubsection{Installing PhyTime}
 
@@ -2153,251 +2177,219 @@ make;
   in the `src/' directory.
 
 \subsubsection{Running  PhyTime} Passing  options and  running  PhyTime on  your data  set is  quite
-similar to running  PhyML in commmand-line mode.  The main differences between the  two programs are
+similar to running  PhyML using an XML parameter input file.  The main differences between the  two programs are
 explained below:
 \begin{itemize}
-\item PhyTime takes as mandatory input a {\em rooted} phylogenetic tree.  Hence, the `\x{-u}' option
-must be used. Also, unlike PhyML, PhyTime does not modify the tree topology. Hence, the options that
-go with the `\x{-s}' command do not alter the input tree topology.
-\item  PhyTime  needs  an input  file  giving  information  about  calibration nodes.   The  command
-`\x{--calibration=}' followed by the name of  the file containing the calibration node information is
-mandatory. The content of that file should look as follows:
+\item Unlike PhyML, PhyTime requires calibration (and sequence) data as input. The format for
+  defining the relevant time intervals is described below.
+\item  PhyTime does not allow partitionned (i.e., multigene) analysis. Future releases might 
+implement this feature (depending on users' requests).
+\end{itemize}
 
-\begin{figure}[h]
-\begin{small}
-\begin{Verbatim}[frame=single, label=Calibration node file, samepage=true, baselinestretch=0.5, fontsize=\tiny]
-Dugong_dugon Procavia_capensis Elephantidae | -65 -54
-Equus_sp. Ceratomorpha | -58 -54
-Cercopithecus_solatus Macaca_mulatta Hylobates_lar Homo_sapiens | -35 -25
-Lepus_crawshayi Oryctolagus_cuniculus Ochotona_princeps | -90 -37
-Marmota_monax Aplodontia_rufa | -120 -37
-Dryomys_nitedula Glis_glis | -120 -28.5
- at root@ | -100 -120
-\end{Verbatim}
-\end{small}
-\end{figure}
+\subsubsection{PhyTime input}
+As stated above, PhyTime takes as input an XML file very similar to those compatible with PhyML. An
+example is given thereafter. The first part of the input file (up to the \x{partitionelem} block) corresponds to a standard XML input
+file for PhyML. The second part is PhyTime-specific. Two new elements can be found here: \x{clade}
+and \x{calibration}\index{PhyTime!calibration}. The \x{clade}\index{PhyTime!clade} element is used to define a subset of taxa. Each of these taxa is
+given in a \x{taxon} element. The  value that each taxon takes is a string corresponding to the
+name of one of the sequences in the alignment file. In the example that follows, \x{Gymno\_Cycas}, \x{Gymno\_Ginko} and
+\x{Gymno\_Juniperus} are three taxa that define a clade called \x{CLADE1}. Note that  this clade may
+not be monophyletic. In fact it is not considered as such during the inference. The second important element is \x{calibration}. It
+helps defining time intervals corresponding to the time of diversification (i.e., the time of the most
+recent common ancestor) of the set of taxa the calibration points to. Each interval is defined using 
+\x{upper} and \x{lower} bounds.
 
-Every row in  this file lists a  set of taxa that belong  to the same subtree (i.e.,  a clade). This
-list of taxa  is followed by the character  `\x{|}' and two real numbers corresponding  to the lower
-and upper bounds of the  calibration interval for the node at the root of  the clade. In the example
-given  here,  the  clade  grouping  the three  taxa  ``Dugong\_dugon'',  ``Procavia\_capensis''  and
-``Elephantida'' has  -65 as lower  bound and -54  as upper bound.  Node  ages (or node  heights) are
-relative to the most recent tip node in the phylogeny, which age is set to 0. It is also possible to
-define a  clade using  only two taxon  names. PhyTime will  then search  for the most  recent common
-ancestor  of these  two  taxa  in the  user-defined  phylogeny and  assign  time  boundaries to  the
-corresponding node. For serially-sampled data, the calibration nodes correspond to tips in the tree.
-A calibration file will then look as follows:
-\begin{figure}[h]
-\begin{small}
-\begin{Verbatim}[frame=single, label=Calibration node file (serially-sampled sequences), samepage=true, baselinestretch=0.5]
-taxaA | -65 -65
-taxaB | -65 -65
-taxaC | -20 -20
-taxaD | -30 -30
-taxaE | -30 -30
-taxaF | -60 -60
-taxaG | -61 -51
- at root@ | -100 -120
-\end{Verbatim}
-\end{small}
-\end{figure}
+\vspace{0.2cm}
+\begin{Verbatim}[frame=single, label=Example of PhyTime XML file, samepage=true, baselinestretch=0.5,
+  fontsize=\small, numbers=left]
 
+<phyml run.id="abc" output.file="def">
 
-% The maximum  value the average substitution rate  along a branch of  a phylogeny can take  is set to
-% $10^{-2}$ substitution per site per time unit. It  is therefore important that the time unit used to
-% specify the calibration intervals  are realistic with respect to this upper  bound. For instance, it
-% one time unit corresponds to one month,  one assumes that the maximum (average) substitution rate is
-% $10^{-3}$/site/month, which  is very high  (substitution rate in  introns is close  to 3/site/$10^9$
-% years).  Consider that in the example give above, one time unit is $10^6$ years.  Hence, the maximum
-% value the substitution  rate can take is $10^{-2}$/site/$10^6$  years, i.e., $10$/site/$10^9$ years.
-% Multiplying the calibration values by 10 amounts  to considering that the time unit is $10^5$ years,
-% implying a maximum  substitution rate equal to $10^{-2}$/site/$10^5$  years, i.e., $100$/site/$10^9$
-% years.
-
-Note   that  the  node corresponding  to  the  root of  the  whole tree  has  a specific  label:
-`\x{@root@}'.  {\color{red}{It is important  to specify upper and lower bounds for  the root node in
-order to ensure convergence  of the Gibbs sampler. If the prior interval for  the root height is not
-specified, the  upper bound will be set  to the upper bound  of the oldest calibration  node and the
-lower bound  will be set to twice  this age.}}  As a  consequence, leaving the prior  on root height
-interval unspecified may produce inaccurate estimates of node ages, especially if there are only few
-otherwise calibration nodes available.
-
-A notable exception to this rule comes from the analysis of serial sample \index{serial sample}
-data, i.e., alignments in which sequences were not sampled at the same time point.  For such data,
-the estimated number of substitutions accumulated between successive time points is used to estimate
-the substitution rate averaged over lineages. Because the time of collection of the sequences is
-generally known without ambiguity, this extra piece of data is translated into very informative
-calibration intervals for the tip nodes (i.e., calibration interval of zero width), which in turn
-results in substitution rate estimates with descreased variances.  Posterior distribution of
-substitution rates with small variances then allows one to get good estimates of the root age.
+  <!-- Tree topology: use "bionj" here. Does not matter as the -->
+  <!-- tree is randomized at the start of the analysis anyway -->
+  <topology> 
+    <instance id="T1" init.tree="bionj" optimise.tree="yes"/>
+  </topology>
+  
+  <!-- Substitution model -->
+  <ratematrices id="RM1">
+    <instance id="M1" model="HKY85" optimise.tstv="no" tstv="4.0"/>
+  </ratematrices>
 
-\end{itemize}
+  
+  <!-- Freerate model of variation of rates across sites -->
+  <siterates id="SR1">
+    <instance id="R3" init.value="0.5"/>
+    <instance id="R2" init.value="1.0"/>
+    <instance id="R1" init.value="2.0"/>
+    <weights  id="D1" family="freerates" optimise.freerates="no">
+      <instance appliesto="R3" value="0.33"/>
+      <instance appliesto="R2" value="0.33"/>
+      <instance appliesto="R1" value="0.33"/>
+    </weights>
+  </siterates>
+
+  <!-- Nucleotide frequencies at equilibrium -->
+  <equfreqs id="EF1">
+    <instance id="F1" optimise.freqs="no"/>
+  </equfreqs>
 
-A typical PhyTime command-line should look like the following\index{command-line options!\x{--calibration}}:
 
-\begin{Verbatim}[fontsize=\small]
-./phytime -i seqname -u treename --calibration=calibration_file -m GTR -c 8
+  <!-- One vector of branch lengths -->
+  <branchlengths id="BL1" >
+    <instance id="L1" optimise.lens="no"/>
+  </branchlengths>
+
+
+  <partitionelem id="partition1" file.name="/path/to/sequences" \
+  data.type="nt" interleaved="no">
+    <mixtureelem list="T1, T1, T1"/>
+    <mixtureelem list="M1, M1, M1"/>
+    <mixtureelem list="F1, F1, F1"/>
+    <mixtureelem list="R1, R2, R3"/>
+    <mixtureelem list="L1, L1, L1"/>
+  </partitionelem>
 \end{Verbatim}
 
-Assuming the file `\x{seqname}' contains DNA  sequences in PHYLIP or NEXUS format, `\x{treename}' is
-the rooted  input tree in Newick  format and `\x{calibration\_file}'  is a set of  calibration nodes,
-PhyTime will  estimate the  posterior distribution of  node times  and substitution rates  under the
-assumption that the  substitution process follows a GTR  model with 8 classes of rates  in the Gamma
-distribution of  rates across sites. The  model parameter values  are estimated by a  Gibbs sampling
-technique. This algorithm tries diferent values of the model parameters and record the most probable
-ones. By default,  $10^6$ values for each  parameter are collected. These values  are recorded every
-$10^3$  sample. These  settings can  be  modified using  the appropriate  command-line options  (see
-below).
-
-
-\subsubsection{Upper bounds of model parameters}
-
-The  maximum expected  number  of substitutions  per  along a  given  branch is  set  to 1.0.  Since
-calibration times provide prior  information about the time scale considered, it  is possible to use
-that information to  define an upper bound for  the substitution rate. This upper bound  is equal to
-the ratio of  the maximum value for  a branch length (1.0) by  the amount of time  elapsed since the
-oldest  calibration point  (i.e., the  minimum  of the  lower bounds  taken  over the  whole set  of
-calibration points)\footnote{The actual  formula involves an extra parameter which  does not need to
-be  introduced  here}. It  is  important  to keep  in  mind  that the  upper  bound  of the  average
-substitution rate depends  on the time unit used  in the calibration priors. The value  of the upper
-bound is printed on screen at the start of the execution.
-
-PhyTime  implements  two  models  that  authorize  rates  to  be  autocorrelated.  The  strength  of
-autocorrelation is governed  by a parameter which value  is estimated from the data.  However, it is
-necessary to  set an appropriate  upper bound  for this parameter  prior running the  analysis.  The
-maximum value is set such that the correlation between the rate at the beginning and at the end of a
-branch of length 1.0 calendar time unit is not  different from 0. Here again the upper bound for the
-model parameter depends  on the time unit. It is  important to choose this unit so  that a branch of
-length 1.0 calendar unit can be considered as short. For this reason, {\color{red}{we recommend to select a time
-unit so that the calibration times take values between -10 and -1000}}\index{time scale}.
-
-\subsubsection{PhyTime specific options}
-
-Beside the \x{--calibration} option, there are other command line options that are specific to PhyTime:
-\begin{itemize}
-\item \x{--chain\_len=num}\index{command-line options!\x{--chain\_len}} \\
-\x{num} is the number of iterations required to estimate the joint posterior density of all the model
-parameters, i.e., the length of the MCMC chain. Its default is set to 1E+6.
-% \item \x{--burnin=num} \\
-% \x{num} is the number of iterations for the ``burnin'' period, i.e., the number of iterations
-% required before actually starting to get valid samples from the joint posterior density of all the
-% model parameters. Its default is set to 1E+5, i.e., 0.1 times the default value of the \x{chain\_len}
-% parameter (see above).
-\item \x{--sample\_freq=num}\index{command-line options!\x{--sample\_freq}}  \\  \x{num} is the number of  generations between successive collection
-of   the   model   parameter   values   throughout   the   MCMC   algorithm.   For   instance,   the
-\x{--sample\_freq=1E+2} option will make PhyTime sample the model parameter every 100th iteration of
-the MCMC algorithm. Its default is set to 1E+3.
-\item \x{--fastlk=yes (no)}\index{command-line options!\x{--fastlk}} [Default: no]\\
-The option is used to turn on (off) the approximation of the likelihood function using a
-multivariate normal density. By default, the exact likelihood is used. Using the normal
-approximation considerably speeds up the calculation. However, it is necessary to ensure that this
-approximation is appropriate by looking at the correlation between the exact and approximated
-likelihood values that are sampled. Please read Section \ref{sec:recomphytime} for a description of
-the appropriate steps to take.
-\item \x{--no\_sequences}\index{command-line options!\x{--no\_sequences}}\\
-Use this option to run the sampler without sequence data. This option can be useful when one wants
-to compare the marginal posterior density of model parameters to those derived when ignoring the
-information conveyed by the sequences. Such comparison should be conducted on a systematic basis  so as to determine whether the
-parameters estimates are mostly determined by the prior of driven by the sequence data.
-\item \x{--rate\_model=gbs/gbd/gamma/clock}\index{command-line options!\x{--rate\_model}}\\
-This option is to select the model of evolution of the rate of evolution. \x{gbs} (default) stands
-for Geometric Brownian + Stochastic. This model considers that rates evolve along the tree
-according to a geometric Brownian process \cite{kishino01} and the average rate of substitution
-along a branch is a gamma distributed random variable. This model is described in \cite{guindon13}.
-The \x{gbd} model (Geometric Browninan with Deterministic calculation of edge lengths) assumes the
-same Geometric Brownian model of rates. However, as opposed to \x{gbs}, this model uses a
-deterministic approximation to calculate the average rates of evolution along edges. This model
-corresponds to the one described in \cite{kishino01} and implemented in the program Multidivtime\index{Multidivtime}.
-\x{gamma} is a less sophisticated model that assumes that average rates along edges are distributed a
-priori according to a gamma distribution. It is analogous to the uncorrelated clock model
-implemented in BEAST\index{BEAST} with a gamma distribution replacing the exponential one. The \x{clock} option
-corresponds to the strict clock model where all the lineages in the tree evolve at the same pace.
-\end{itemize}
+\begin{Verbatim}[frame=single, label=Example of PhyTime XML file (ctnd), samepage=true, baselinestretch=0.5,
+  fontsize=\small, numbers=left]
+ 
+  <clade id="CLADE1">
+    <taxon value="Gymno_Cycas"/>
+    <taxon value="Gymno_Ginkgo"/>
+    <taxon value="Gymno_Juniperus"/>
+  </clade>
+  <calibration id="CAL1">
+    <lower>-452</lower>
+    <upper>-290</upper>
+    <appliesto clade.id="CLADE1">
+    </appliesto>
+  </calibration>
+
+  <clade id="CLADE2">
+    <taxon value="Fagales_Juglans"/>
+    <taxon value="Ophioglossum"/>
+  </clade>
+  <calibration id="CAL2">
+    <lower>-10000</lower>
+    <upper>-0</upper>
+    <appliesto clade.id="CLADE2">
+    </appliesto>
+  </calibration>
+
+</phyml>
+\end{Verbatim}
+
+
+
 
 \subsubsection{PhyTime output}
 
-The     program     PhyTime     generates     two     output     files.      The     file     called
-`\x{your\_seqfile\_phytime\_XXXX\_stats}', where  XXXX is  a randomly  generated integer,  lists the
-node times  and branch  relative rates  sampled during the  estimation process.   It also  gives the
-sampled values for other parameters, such as  the autocorrelation of rates (parameter `Nu'), and the
-rate of evolution (parameter `EvolRate') amongst others.   This output file can be analysed with the
+The     program     PhyTime     generates     two     output     files.      Using the XML file given
+above, one of the output files is called  `\x{abc\_def\_phytime\_stats}'. It lists the
+node times  and (relative) substitution rates on edges  sampled during the  estimation process.   It also  gives the
+sampled values for other parameters, such as  the autocorrelation of rates (parameter `nu'), and the
+rate of evolution (parameter `clock') amongst others.   This output file can be analysed with the
 program        Tracer\index{Tracer}        from         the        BEAST\index{BEAST}        package
-(\url{http://beast.bio.ed.ac.uk/Main_Page}).        The       second      file       is       called
-`\x{your\_seqfile\_phytime\_XXXX\_trees}'.  It is  the list of trees that were  collected during the
+(\url{http://beast.bio.ed.ac.uk/Main_Page}) or Icylog (\url{http://tgvaughan.github.io/icylog/}\index{Icylog}).        The       second      file       is       called
+`\x{abc\_def\_phytime\_trees}'.  It is  the list of rooted trees that were  collected during the
 estimation process, i.e., phylogenies sampled from the posterior density of trees.  This file can be
 processed   using   the   software   TreeAnnotator,   also  part   of   the   BEAST   package   (see
 \url{http://beast.bio.ed.ac.uk/Main_Page}) in  order to generate  confidence sets for the  node time
 estimates.
 
-Important  information is also  displayed on  the standard  output of  PhyTime (the  standard output
-generally corresponds to the terminal window from  which PhyTime was launched).  The first column of
-this output gives the current  generation, or run, of the chain. It starts at  1 and goes up to 1E+6
-by default (use \x{--chain\_len} to change this value, see above).  The second column gives the time
-elapsed  in seconds since  the sampling  began. The  third column  gives the  log likelihood  of the
-phylogenetic model (i.e., `Felsenstein's likelihood'). The  fourth column gives the logarithm of the
-joint prior  probability of substitution  rates along  the tree and  node heights. The  fifth column
-gives the  current sampled value  of the EvolRate  parameter along with the  corresponding Effective
-Sample Size (ESS) (see  Section \ref{sec:ess}) for this parameter.  The sixth  column gives the tree
-height  and the  corresponding  ESS.  The seventh  column  gives the  value  of the  autocorrelation
-parameter followed by the  corresponding ESS. The eightth column gives the  values of the birth rate
-parameter that  governs the birth-rate model  of species divergence  dates.  The last column  of the
-standard  output gives  the minimum  of the  ESS  values taken  over the  whole set  of node  height
-estimates.  It provides useful information when one has  to decide whether or not the sample size is
-large enough to draw  valid conclusion, i.e., decide whether the chain was  run for long enough (see
-Section \ref{sec:recomphytime} for more detail about adequate chain length).
-
-\subsubsection{ClockRate vs. EvolRate}
-
-The average rate of evolution along a branch  is broken into two components. One is called ClockRate
-and is  the same throughout  the tree. The  other is called EvolRate  and corresponds to  a weighted
-average of  branch-specific rates.  The  model of rate  evolution implemented in PhyTime  forces the
-branch-specific rate values to  be greater than one. As a consequence,  ClockRate is usually smaller
-EvolRate.
-
-In more mathematical terms, let $\mu$ be the value of ClockRate, $r_i$ be the value of the relative
-rate along branch $i$ and $\Delta_i$ the time elapsed along branch $i$. The value of EvolRate is
-then given by:
-\begin{eqnarray*}
-\mathrm{EvolRate} = \mu \frac{\sum_{i}^{2n-3} r_i \Delta_i}{\sum_{i}^{2n-3} \Delta_i}.
-\end{eqnarray*}  It is  clear from  this equation  that  multiplying each  $r_i$ by  a constant  and
-dividing $\mu$ by the same constant does not  change the value of EvolRate. The $r_i$s and $\mu$
-are then confounded,  or non-identifiable, and only  the value of EvolRate can  be estimated from
-the data.   {\color{red}{Please make sure  that you use  the value of  EvolRate rather than  that of
-ClockRate when referring to the estimate of the substitution rate}}.
-
-\subsubsection{Effective sample size}\label{sec:ess}
-
-The MCMC technique  generates samples from a  target distribution (in our case,  the joint posterior
-density  of  parameters).  Due  to  the  Markovian  nature of  the  method,  these samples  are  not
-independent.  The  ESS is the estimated  number of independent  measurements obtained from a  set of
-(usually dependent) measurements. It is calculated using the following formula:
-\begin{eqnarray*}
-\mathrm{ESS} = N\left(\frac{1-r}{1+r}\right),
-\end{eqnarray*}
-where  $N$  is the  length  of  the  chain  (i.e., the  `raw'  or `correlated' sample  size)  and $r$  is  the
-autocorrelation value, which is obtained using the following formula:
-\begin{eqnarray*}
-r = \frac{1}{(N-k)\sigma_x^2} \sum_{i=1}^{N-k} (X_i - \mu_x)(X_{i+k}-\mu_x),
-\end{eqnarray*} where $\mu_x$ and $\sigma_x$ are the mean and standard deviation of the $X_i$ values
-respectively and $k$ is the lag. The value of $r$ that is used in PhyTime corresponds to the case where $k=1$,
-which therefore gives a first order  approximation of the `average' autocorrelation value (i.e., the
-autocorrelation averaged over the set of possible values of the lag).
 
-
-\subsubsection{Prior distributions of model parameters}\label{sec:prior}
-
-Any Bayesian analysis requires  specifying a prior distribution of model  parameters. The outcome of
-the data analysis, i.e., the posterior distribution,  is influenced by the priors.  It is especially
-true if the signal conveyed  by the data is weak.  While some have  argued that the specification of
-priors relies more  on arbitrary decisions than sound scientific  reasoning, choosing relevant prior
-distributions  is in  fact fully  integrated in  the process  of building  model that  generates the
-observed data.  In particular, the problem of  estimating divergence times naturally lends itself to
-hierarchical Bayesian modelling.  Based on the hypothesis  that rates of evolution are conserved (to
-some extant)  throughout the  course of  evolution, the hierarchical  Bayesian approach  provides an
-adequate framework for inferring substitution rates  and divergence dates separately. Hence, in this
-situation, it makes good  sense to use what is known about a  relatively well-defined feature of the
-evolution of genetic sequences (the ``molecular  clock'' hypothesis combined to stochastic variations of
-rates across lineages) to build a prior distribution on rates along edges.
+\subsubsection{MCMC settings}
+
+PhyTime estimates the joint posterior distribution  of the phylogenetic model parameters  using an
+MCMC algorithm. This algorithm relies on sampling values of these parameters iteratively. The number
+of iterations is fixed to 1E+07 and values of parameters are recorded every 200 generations. The
+vast majority of analyses will not warrant 1E+07 iterations  to converge to the
+target distribution (i.e., converge to the solution). I thus recommend  monitoring each analysis by
+loading on a regular basis the statistics output file produced by PhyTime in Tracer or Icylog  and
+interrupt the analysis once the effective sample sizes of all parameters have reached 200. 
+
+The MCMC
+algorithm implemented in PhyTime relies on multiple operators that update different parameters, or the
+same parameter in different ways. The weights of these operators, i.e., the frequency with which
+they are applied, were adjusted for the analysis of the plant data set described in
+\cite{guindon17}. If you think these default values are not suitable for your own analysis, please
+feel free to have a look at the function \x{MCMC\_Complete\_MCMC} in the file \x{mcmc.c} to make 
+the appropriate changes to the values of \x{mcmc->move\_weight[XXX]}, where \x{XXX} is the name of
+the operator. Alternatively, you might want to send me an email (\url{guindon at lirmm.fr}) if you are
+unsure about all this. 
+
+
+
+% Important  information is also  displayed on  the standard  output of  PhyTime (the  standard output
+% generally corresponds to the terminal window from  which PhyTime was launched).  The first column of
+% this output gives the current  generation, or run, of the chain. It starts at  1 and goes up to 1E+7
+% by default.  The second column gives the time elapsed  in seconds since  the sampling  began. The
+% third column  gives the  log likelihood  of the phylogenetic model (i.e., `Felsenstein's
+% likelihood'). The  fourth column gives the logarithm of the joint prior  probability of substitution
+% rates along  the tree and  node heights. The  fifth column gives the  current sampled value  of the
+% EvolRate  parameter along with the  corresponding Effective Sample Size (ESS)  for this parameter.
+% The sixth  column gives the tree height  and the  corresponding  ESS.  The seventh  column  gives
+% the  value  of the  autocorrelation parameter followed by the  corresponding ESS. The eightth column
+% gives the  values of the birth rate parameter that  governs the birth-rate model  of species
+% divergence  dates.  The last column  of the standard  output gives  the minimum  of the  ESS  values
+% taken  over the  whole set  of node  height estimates.  It provides useful information when one has
+% to decide whether or not the sample size is large enough to draw  valid conclusion, i.e., decide
+% whether the chain was  run for long enough (see Section \ref{sec:recomphytime} for more detail about
+% adequate chain length).
+
+% \subsubsection{ClockRate vs. EvolRate}
+
+% The average rate of evolution along a branch  is broken into two components. One is called ClockRate
+% and is  the same throughout  the tree. The  other is called EvolRate  and corresponds to  a weighted
+% average of  branch-specific rates.  The  model of rate  evolution implemented in PhyTime  forces the
+% branch-specific rate values to  be greater than one. As a consequence,  ClockRate is usually smaller
+% EvolRate.
+
+% In more mathematical terms, let $\mu$ be the value of ClockRate, $r_i$ be the value of the relative
+% rate along branch $i$ and $\Delta_i$ the time elapsed along branch $i$. The value of EvolRate is
+% then given by:
+% \begin{eqnarray*}
+% \mathrm{EvolRate} = \mu \frac{\sum_{i}^{2n-3} r_i \Delta_i}{\sum_{i}^{2n-3} \Delta_i}.
+% \end{eqnarray*}  It is  clear from  this equation  that  multiplying each  $r_i$ by  a constant  and
+% dividing $\mu$ by the same constant does not  change the value of EvolRate. The $r_i$s and $\mu$
+% are then confounded,  or non-identifiable, and only  the value of EvolRate can  be estimated from
+% the data.   {\color{red}{Please make sure  that you use  the value of  EvolRate rather than  that of
+% ClockRate when referring to the estimate of the substitution rate}}.
+
+% \subsubsection{Effective sample size}\label{sec:ess}
+
+% The MCMC technique  generates samples from a  target distribution (in our case,  the joint posterior
+% density  of  parameters).  Due  to  the  Markovian  nature of  the  method,  these samples  are  not
+% independent.  The  ESS is the estimated  number of independent  measurements obtained from a  set of
+% (usually dependent) measurements. It is calculated using the following formula:
+% \begin{eqnarray*}
+% \mathrm{ESS} = N\left(\frac{1-r}{1+r}\right),
+% \end{eqnarray*}
+% where  $N$  is the  length  of  the  chain  (i.e., the  `raw'  or `correlated' sample  size)  and $r$  is  the
+% autocorrelation value, which is obtained using the following formula:
+% \begin{eqnarray*}
+% r = \frac{1}{(N-k)\sigma_x^2} \sum_{i=1}^{N-k} (X_i - \mu_x)(X_{i+k}-\mu_x),
+% \end{eqnarray*} where $\mu_x$ and $\sigma_x$ are the mean and standard deviation of the $X_i$ values
+% respectively and $k$ is the lag. The value of $r$ that is used in PhyTime corresponds to the case where $k=1$,
+% which therefore gives a first order  approximation of the `average' autocorrelation value (i.e., the
+% autocorrelation averaged over the set of possible values of the lag).
+
+
+% \subsubsection{Prior distributions of model parameters}\label{sec:prior}
+
+% Any Bayesian analysis requires  specifying a prior distribution of model  parameters. The outcome of
+% the data analysis, i.e., the posterior distribution,  is influenced by the priors.  It is especially
+% true if the signal conveyed  by the data is weak.  While some have  argued that the specification of
+% priors relies more  on arbitrary decisions than sound scientific  reasoning, choosing relevant prior
+% distributions  is in  fact fully  integrated in  the process  of building  model that  generates the
+% observed data.  In particular, the problem of  estimating divergence times naturally lends itself to
+% hierarchical Bayesian modelling.  Based on the hypothesis  that rates of evolution are conserved (to
+% some extant)  throughout the  course of  evolution, the hierarchical  Bayesian approach  provides an
+% adequate framework for inferring substitution rates  and divergence dates separately. Hence, in this
+% situation, it makes good  sense to use what is known about a  relatively well-defined feature of the
+% evolution of genetic sequences (the ``molecular  clock'' hypothesis combined to stochastic variations of
+% rates across lineages) to build a prior distribution on rates along edges.
 
 
 
@@ -2448,7 +2440,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 +2495,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 +2749,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..8382215 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},
@@ -24,7 +65,7 @@
 @article{ayres12,
   title={BEAGLE: an application programming interface and high-performance computing library for statistical phylogenetics},
   author={Ayres, Daniel L and Darling, Aaron and Zwickl, Derrick J and Beerli, Peter and Holder, Mark T and Lewis, Paul O and Huelsenbeck, John P and Ronquist, Fredrik and Swofford, David L and Cummings, Michael P and others},
-  journal={Systematic biology},
+  journal={Systematic Biology},
   volume={61},
   number={1},
   pages={170--173},
@@ -35,7 +76,7 @@
 @article{ho11,
   title={Time-dependent rates of molecular evolution},
   author={Ho, Simon YW and Lanfear, Robert and Bromham, Lindell and Phillips, Matthew J and Soubrier, Julien and Rodrigo, Allen G and Cooper, Alan},
-  journal={Molecular ecology},
+  journal={Molecular Ecology},
   volume={20},
   number={15},
   pages={3087--3101},
@@ -67,7 +108,7 @@
   publisher={Elsevier}
 }
 @article{best,
-  title={BEST: Bayesian estimation of species trees under the coalescent model},
+  title={{BEST}: Bayesian estimation of species trees under the coalescent model},
   author={Liu, L.},
   journal={Bioinformatics},
   volume={24},
@@ -88,7 +129,7 @@
   publisher={SMBE}
 }
 @article{stem,
-  title={STEM: species tree estimation using maximum likelihood for gene trees under coalescence},
+  title={{STEM}: species tree estimation using maximum likelihood for gene trees under coalescence},
   author={Kubatko, L.S. and Carstens, B.C. and Knowles, L.L.},
   journal={Bioinformatics},
   volume={25},
@@ -109,6 +150,27 @@
   publisher={SMBE}
 }
 
+ at article{guindon10,
+  title={Bayesian estimation of divergence times from large sequence alignments},
+  author={Guindon, St{\'e}phane},
+  journal={Molecular Biology and Evolution},
+  volume={27},
+  number={8},
+  pages={1768--1781},
+  year={2010},
+  publisher={SMBE}
+}
+
+ at article{guindon17,
+  title={Bayesian molecular dating as a ``doubly intractable'' problem},
+  author={Guindon, St{\'e}phane},
+  journal={BioRxiv},
+  volume={},
+  number={},
+  pages={http://biorxiv.org/content/early/2017/02/06/106310},
+  year={2017},
+}
+
 
 %% Created for guindon at 2009-04-21 13:11:50 +1200 
 
@@ -124,7 +186,7 @@
 @article{matsen07,
   title={Phylogenetic mixtures on a single tree can mimic a tree of another topology},
   author={Matsen, F.A. and Steel, M.},
-  journal={Systematic biology},
+  journal={Systematic Biology},
   volume={56},
   number={5},
   pages={767--775},
@@ -138,10 +200,21 @@ 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.},
-  journal={Trends in ecology \& evolution},
+  journal={Trends in Ecology \& Evolution},
   year={2011},
   vol=27,
   pages={47,56}
@@ -320,7 +393,7 @@ Pages = {249,265}
 
 @article{anisimova06,
 	Author = {M. Anisimova and O. Gascuel},
-	Journal = {Syst. Biol.},
+	Journal = {Systematic Biology},
 	Pages = {539-552},
 	Title = {Approximate likelihood-ratio test for branches: a fast, accurate, and powerful alternative},
 	Volume = 55,
@@ -340,7 +413,7 @@ Pages = {249,265}
 @article{anisimova11,
   title={Survey of branch support methods demonstrates accuracy, power, and robustness of fast likelihood-based approximation schemes},
   author={Anisimova, M. and Gil, M. and Dufayard, J.F. and Dessimoz, C. and Gascuel, O.},
-  journal={Systematic biology},
+  journal={Systematic Biology},
   volume={60},
   number={5},
   pages={685--699},
@@ -364,7 +437,7 @@ Pages = {249,265}
 	Author = {T. H. Cormen and C. E. Leiserson and R. L. Rivest},
 	Chapter = { 17 greedy algorithms},
 	Pages = {329-356},
-	Publisher = {The massachuset Institute of Technology Press},
+	Publisher = {The Massachuset Institute of Technology Press},
 	Title = {Introduction to algorithms},
 	Year = 1992}
 
@@ -400,7 +473,7 @@ Pages = {249,265}
 
 @article{kumar02,
 	Author = {S. Kumar and S. Subramanian},
-	Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)},
+	Journal = {PNAS},
 	Pages = {803-808},
 	Title = {Mutation rates in mammalian genomes},
 	Volume = {99},
@@ -414,7 +487,7 @@ Pages = {249,265}
 
 @article{nei97,
 	Author = {Masatoshi Nei, Sudhir Kumar, and Kei Takahashi},
-	Journal = {special series of inaugural articles by members of the national academy of science},
+	Journal = {Special series of inaugural articles by members of the national academy of science},
 	Pages = {584-593},
 	Title = {The optimization principle in phylogenetic analysis tends to give incorrect topologies when the number of nucleotides or amino acids is small},
 	Volume = 13,
@@ -422,7 +495,7 @@ Pages = {249,265}
 
 @article{nei98,
 	Author = {M. Nei and S. Kumar and K. Takahashi},
-	Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)},
+	Journal = {PNAS},
 	Pages = {12390-12397},
 	Title = {The optimization principle in phylogenetic analysis tends to give incorrect topologies when the number of nucleotides or amino acids used is small},
 	Volume = 95,
@@ -436,7 +509,7 @@ Pages = {249,265}
 
 @article{adell94,
 	Author = {J. Adell and J. Dopazo},
-	Journal = {J. Mol. Evol},
+	Journal = {Journal of Molecular Evolution},
 	Pages = {305-309},
 	Title = {{M}onte {C}arlo Simulation in phylogenies : An     application to Test the Constancy of Evolutionary Rates},
 	Volume = 38,
@@ -462,7 +535,7 @@ Pages = {249,265}
 
 @article{almagor83,
 	Author = {Hagai Almagor},
-	Journal = {Journal of theorical biology},
+	Journal = {Journal of Theorical Biology},
 	Note = {{I}nfluence du {V}oisinage sur l'{E}volution d'une     {S{\'e}}quence d'{ADN}},
 	Pages = {633-645},
 	Title = { A Markov analysis of {DNA} sequences},
@@ -525,7 +598,7 @@ Pages = {249,265}
 
 @article{bailly03,
 	Author = { X. Bailly and R. Leroy and S. Carney and O. Collin and F. Zal and A. Toulmond and D. Jollivet},
-	Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)},
+	Journal = {PNAS},
 	Pages = {5885-5890},
 	Title = {The loss of the hemoglobin \hbox{H$_2$S}-binding function in annelids from sulfide-free habitats reveals molecular adaptation driven by {D}arwinian positive selection},
 	Volume = 1000,
@@ -548,7 +621,7 @@ Pages = {249,265}
 
 @article{bandelt92,
 	Author = {H.-J. Bandelt and A. Dress},
-	Journal = {Advances Math},
+	Journal = {Advances Math.},
 	Pages = {47-105},
 	Title = {A canonical decomposition theory for metrics on a finite set},
 	Volume = 92,
@@ -579,6 +652,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},
@@ -655,7 +740,7 @@ Pages = {249,265}
 
 @article{benzer61,
 	Author = {S. Benzer},
-	Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)},
+	Journal = {PNAS},
 	Pages = {403-415},
 	Title = {On the topography of genetic fine structure},
 	Volume = 47,
@@ -684,7 +769,8 @@ Pages = {249,265}
 	Author = {D. Bertrand and O. Gascuel},
 	Journal = {{IEEE} Transactions on computational biology and bioinformatics},
 	Title = {Topological rearrangements and local search method for tandem duplication trees},
-	Volume = {In press},
+	Volume = {2},
+        Issue = {1},
 	Year = 2005}
 
 @article{bg96_boot,
@@ -1373,7 +1459,7 @@ pages={1792-1797}
 
 @article{efron96,
 	Author = {B. Efron and E. Halloran and S. Holmes},
-	Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)},
+	Journal = {PNAS},
 	Pages = {7085-7090},
 	Title = {Bootstrap confidence levels for phylogenetic trees},
 	Volume = 93,
@@ -1390,7 +1476,7 @@ pages={1792-1797}
 
 @article{eigen88,
 	Author = {M. Eigen and R. Winkler-Oswatitsch and     A. Dress},
-	Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)},
+	Journal = {PNAS},
 	Pages = {5913-5917},
 	Title = {Statistical Geometry in Sequence Space : A Method     of Quantitative Comparative Sequence Analysis },
 	Volume = 85,
@@ -1615,7 +1701,7 @@ pages={1792-1797}
 
 @article{gaucher01,
 	Author = {E. Gaucher and M. Miyamoto and S. Benner},
-	Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)},
+	Journal = {PNAS},
 	Pages = {548-552},
 	Title = {Function-structure analysis of proteins using covarion-based evolutionary approaches: {E}longation factors},
 	Volume = 98,
@@ -1643,7 +1729,7 @@ pages = {221-4}
 
 @article{henikoff92,
 	Author = {S. Henikoff and J. Henikoff},
-	Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)},
+	Journal = {PNAS},
 	Pages = {10915-10919},
 	Title = {Amino acid substitution matrices from protein blocks.},
 	Volume = 89,
@@ -1801,7 +1887,7 @@ pages = {221-4}
 
 @article{galtier95,
 	Author = {N. Galtier and M. Gouy},
-	Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)},
+	Journal = {PNAS},
 	Pages = {11317-11321},
 	Title = {Inferring phylogenies from {DNA} sequences of unequal base compositions},
 	Volume = 92,
@@ -1907,7 +1993,7 @@ pages = {221-4}
 @Article{gaut92,
    Author="Gaut, B. S.  and Muse, S. V.  and Clark, W. D.  and Clegg, M. T. ",
    Title="{{R}elative rates of nucleotide substitution at the rbc{L} locus of monocotyledonous plants}",
-   Journal="J. Mol. Evol.",
+   Journal="Journal of Molecular Evolution",
    Year="1992",
    Volume="35",
    Pages="292--303",
@@ -2067,7 +2153,7 @@ pages = {221-4}
 
 @article{gu98,
 	Author = {X. Gu and W.H. Li},
-	Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)},
+	Journal = {PNAS},
 	Pages = {5899-5905},
 	Title = {Estimation of evolutionary distances under stationary and nonstationary models of nucleotide substitution},
 	Volume = 95,
@@ -2140,7 +2226,7 @@ pages={479-483}
 
 @article{guindon04,
 	Author = {S. Guindon and A. Rodrigo and K. Dyer and J. Huelsenbeck},
-	Journal = {Proceedings of the National Academy of Sciences},
+	Journal = {PNAS},
 	Pages = {12957-12962},
 	Title = {Modeling the site-specific variation of selection patterns along lineages},
 	Volume = {101},
@@ -2293,7 +2379,7 @@ pages={479-483}
 
 @article{hendy94,
 	Author = {M. Hendy and D. Penny and M. A. Steel},
-	Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)},
+	Journal = {PNAS},
 	Pages = {3339-3343},
 	Title = {A discrete {F}ourier analysis for evolutionary trees},
 	Volume = 91,
@@ -2515,7 +2601,7 @@ pages={479-483}
 
 @article{huelsenbeck06,
 	Author = {J. Huelsenbeck and S. Jain and S. Frost and S. Pond},
-	Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)},
+	Journal = {PNAS},
 	Pages = {6263-6268},
 	Title = {A Dirichlet process model for detecting positive selection in protein-coding {DNA} sequences},
 	Volume = 103,
@@ -2679,7 +2765,7 @@ pages={479-483}
 
 @article{karlin93,
 	Author = {Samuel Karlin and Stephen F. Altschul},
-	Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)},
+	Journal = {PNAS},
 	Pages = {5873-5877},
 	Title = {Applications and Statistics for multiple     hight-scoring segments in molecular Sequences},
 	Utilisateur = {Guillaume Andrieu},
@@ -2739,7 +2825,7 @@ pages={479-483}
 
 @article{kimura81,
 	Author = {M. Kimura},
-	Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)},
+	Journal = {PNAS},
 	Pages = {454-458},
 	Title = {Estimation of evolutionary distances between homologous nucleotide sequences},
 	Volume = 78,
@@ -2800,7 +2886,7 @@ pages={479-483}
 @Article{kishino01,
    Author="Kishino, H.  and Thorne, J.  and Bruno, W.",
    Title="{{P}erformance of a divergence time estimation method under a probabilistic model of rate evolution}",
-   Journal="Mol. Biol. Evol.",
+   Journal="Molecular Biology and Evolution",
    Year="2001",
    Volume="18",
    Pages="352--361",
@@ -2819,7 +2905,7 @@ pages={479-483}
 
 @article{klotz79,
 	Author = {Lynn C. Klotz and Ned Komar and Roger L. Blanken and Ralph M. Mitchell},
-	Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)},
+	Journal = {PNAS},
 	Pages = {4516-4520},
 	Title = {Calculation of evolutionary trees from sequence data},
 	Utilisateur = {Gilles Caraux},
@@ -2854,7 +2940,7 @@ pages={479-483}
 
 @article{kondrashov02,
 	Author = {A.S. Kondrashov and S. Sunyaev and F.A.  Kondrashov},
-	Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)},
+	Journal = {PNAS},
 	Pages = {14878-14883},
 	Title = {Dobzhansky-{M}uller incompatibilities in protein evolution},
 	Volume = 99,
@@ -2981,7 +3067,7 @@ pages={479-483}
 
 @article{lawrence98,
 	Author = {J. Lawrence and H. Ochman},
-	Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)},
+	Journal = {PNAS},
 	Pages = {9413-9417},
 	Title = {Molecular archaeology of the {\it \hbox{E}scherichia coli} genome},
 	Volume = 95,
@@ -2989,7 +3075,7 @@ pages={479-483}
 
 @article{le08,
 	Author = {SQ. Le and O. Gascuel},
-	Journal = {Mol. Biol. Evol.},
+	Journal = {Molecular Biology and Evolution},
 	Title = {An Improved General Amino-Acid Replacement Matrix},
 Volume = {25},
 Pages = {1307-1320},
@@ -3040,7 +3126,7 @@ Pages = {1307-1320},
 
 @article{lemmon02,
 	Author = {A. Lemmon and M. Milinkovitch},
-	Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)},
+	Journal = {PNAS},
 	Pages = {10516-10521},
 	Title = {The metapopulation genetic algorithm: an efficient solution for the problem of large phylogeny estimation},
 	Volume = 99,
@@ -3048,7 +3134,7 @@ Pages = {1307-1320},
 
 @article{metapiga,
 	Author = {A.R. Lemmon and Milinkovitch M.C.},
-	Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)},
+	Journal = {PNAS},
 	Pages = {10516-10521},
 	Title = {The metapopulation genetic algorithm: An efficient solution for the problem of large phylogeny estimation},
 	Volume = 99,
@@ -3567,7 +3653,7 @@ Pages = {1307-1320},
 
 @article{nei79,
 	Author = {Masatoshi Nei and Wen Hsiung Li},
-	Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)},
+	Journal = {PNAS},
 	Number = 10,
 	Pages = {5269-5273},
 	Title = {Mathematical model for studying genetic variation in terms of restriction endonucleases},
@@ -3699,6 +3785,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},
@@ -4054,7 +4150,7 @@ Pages = {1307-1320},
 @Article{robinson98,
    Author="Robinson, M.  and Gouy, M.  and Gautier, C.  and Mouchiroud, D. ",
    Title="{{S}ensitivity of the relative-rate test to taxonomic sampling}",
-   Journal="Mol. Biol. Evol.",
+   Journal="Molecular Biology and Evolution",
    Year="1998",
    Volume="15",
    Pages="1091--1098",
@@ -4105,7 +4201,7 @@ Pages = {1307-1320},
 
 @article{rodriguez03,
 	Author = {F. Rodriguez-Trelles and R. Tarrio and F. Ayala},
-	Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)},
+	Journal = {PNAS},
 	Pages = {13413-13417},
 	Title = {Convergent neofunctionalization by positive Darwinian selection after ancient recurrent duplications of the xanthine dehydrogenase gene},
 	Volume = {100},
@@ -4362,7 +4458,7 @@ Year = {1994}
 
 @article{sanger77,
 	Author = {F. Sanger and S. Nicklen and A.R. Coulson},
-	Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)},
+	Journal = {PNAS},
 	Pages = {5463-5467},
 	Title = {DNA sequencing with chain-terminating inhibitors},
 	Volume = 74,
@@ -4777,7 +4873,7 @@ Year = 2010}
 
 @article{suzuki02,
 	Author = {Y. Suzuki and G. V. Glazko and M. Nei},
-	Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)},
+	Journal = {PNAS},
 	Pages = {16138-16143},
 	Title = {Overcredibility of molecular phylogenies obtained by Bayesian phylogenetics},
 	Volume = 99,
@@ -4793,7 +4889,7 @@ Year = 2010}
 
 @article{swanson01,
 	Author = {W. Swanson and Z. Yang and M. Wolfner and C. Aquadro},
-	Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)},
+	Journal = {PNAS},
 	Pages = {2509-2514},
 	Title = {Positive Darwinian selection drives the evolution of several female reproductive proteins in mammals},
 	Volume = 98,
@@ -4902,7 +4998,7 @@ Year = 2010}
 @Article{takezaki95,
    Author="Takezaki, N.  and Rzhetsky, A.  and Nei, M. ",
    Title="{{P}hylogenetic test of the molecular clock and linearized trees}",
-   Journal="Mol. Biol. Evol.",
+   Journal="Molecular Biology and Evolution",
    Year="1995",
    Volume="12",
    Pages="823--833",
@@ -5165,7 +5261,7 @@ Year = {2006},
 @article{nozawa09,
   title={Reliabilities of identifying positive selection by the branch-site and the site-prediction methods},
   author={Nozawa, Masafumi and Suzuki, Yoshiyuki and Nei, Masatoshi},
-  journal={Proceedings of the National Academy of Sciences},
+  journal={PNAS},
   volume={106},
   number={16},
   pages={6700--6705},
@@ -5351,7 +5447,7 @@ Year = {2006},
 @Article{yang06,
    Author="Yang, Z.  and Rannala, B. ",
    Title="{{B}ayesian estimation of species divergence times under a molecular clock using multiple fossil calibrations with soft bounds}",
-   Journal="Mol. Biol. Evol.",
+   Journal="Molecular Biology and Evolution",
    Year="2006",
    Volume="23",
    Pages="212--226",
@@ -5529,7 +5625,7 @@ Year = {2006},
 @Article{wu85,
    Author="Wu, C. I.  and Li, W. H. ",
    Title="{{E}vidence for higher rates of nucleotide substitution in rodents than in man}",
-   Journal="Proc. Natl. Acad. Sci. U.S.A.",
+   Journal="PNAS",
    Year="1985",
    Volume="82",
    Pages="1741--1745",
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..af8a664 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,10 @@ 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\
+sse.c sse.h\
+avx.c avx.h\
+xml.c xml.h
 phytime_LDADD = -lm
 else 
 if WANT_PHYCONT
@@ -140,42 +157,42 @@ tiporder.c tiporder.h
 # continuous.c continuous.h
 phycont_LDADD = -lm
 else 
-if WANT_RWRAP
-lib_LTLIBRARIES = librwrap.la
-librwrap_la_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\
-rwrapper.c rwrapper.h
-librwrap_la_LIBADD = -lm
-librwrap_la_LDFLAGS = -I/usr/share/R/include -shared -module -flat_namespace
-librwrap_la_CFLAGS=-std=gnu99 -fPIC -Wl,-z,defs
-else 
+# if WANT_RWRAP
+# lib_LTLIBRARIES = librwrap.la
+# librwrap_la_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\
+# rwrapper.c rwrapper.h
+# librwrap_la_LIBADD = -lm
+# librwrap_la_LDFLAGS = -I/usr/share/R/include -shared -module -flat_namespace
+# librwrap_la_CFLAGS=-std=gnu99 -fPIC -Wl,-z,defs
+# else 
 if WANT_PART
 part_SOURCES = main.c \
 utilities.c utilities.h\
@@ -307,9 +324,45 @@ nexus.c nexus.h\
 init.c init.h\
 xml.c xml.h\
 mixt.c mixt.h\
+date.c date.h\
+sse.c sse.h\
+avx.c avx.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 +556,9 @@ nexus.c nexus.h\
 init.c init.h\
 xml.c xml.h\
 mixt.c mixt.h\
+date.c date.h\
+sse.c sse.h\
+avx.c avx.h\
 phyrex.c phyrex.h
 else
 if WANT_BEAGLE
@@ -538,7 +594,8 @@ mixt.c mixt.h\
 beagle_utils.c beagle_utils.h
 phyml_beagle_LDADD = -lm -lhmsbeagle
 else
-phyml_SOURCES = main.c \
+if WANT_DATE
+date_SOURCES = main.c \
 utilities.c  utilities.h\
 optimiz.c  optimiz.h\
 lk.c  lk.h\
@@ -566,6 +623,40 @@ 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\
+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\
+m4.c m4.h\
+io.c io.h\
+make.c make.h\
+nexus.c nexus.h\
+init.c init.h\
+xml.c xml.h\
+date.c date.h\
+sse.c sse.h\
+avx.c avx.h\
 mixt.c mixt.h
 phyml_LDADD = -lm
 endif
@@ -583,6 +674,8 @@ endif
 endif
 endif
 endif
+endif
+# endif
 
 
 all-am:	intro $(bin_PROGRAMS)
diff --git a/src/alrt.c b/src/alrt.c
index e8ed543..2e72b5c 100644
--- a/src/alrt.c
+++ b/src/alrt.c
@@ -23,7 +23,6 @@ Authors : Jean-Francois Dufayard & Stephane Guindon.
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 /*
 * Check every testable branch of the tree,
 * check for NNIs, optimizing 5 branches,
@@ -41,15 +40,15 @@ 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);
-      
+            
       //Interface output
-      if((tree->mod->s_opt->print) && (!tree->io->quiet)) PhyML_Printf("\n\n. Checking for NNIs, optimizing five branches...\n");
+      if(tree->verbose > VL0 && tree->io->quiet == NO) PhyML_Printf("\n\n. Checking for NNIs, optimizing five branches...\n");
       
       better_found  =  0;
       result        = -1;
@@ -62,6 +61,7 @@ int Check_NNI_Five_Branches(t_tree *tree)
       init_lnL = Lk(NULL,tree);
       MIXT_Set_Alias_Subpatt(NO,tree);
       
+      
       //For every branch
       For(i,2*tree->n_otu-3)
         {
@@ -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;
@@ -129,6 +129,7 @@ int Check_NNI_Five_Branches(t_tree *tree)
             }
         }
       
+      
       if((tree->c_lnL < init_lnL - tree->mod->s_opt->min_diff_lk_local) || (tree->c_lnL > init_lnL + tree->mod->s_opt->min_diff_lk_local))
         {
           PhyML_Printf("\n\n== tree->c_lnL = %f init_lnL = %f.",tree->c_lnL,init_lnL);
@@ -137,7 +138,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.
@@ -156,7 +157,7 @@ int Check_NNI_Five_Branches(t_tree *tree)
               Exit("\n");
             }
 
-          if((tree->mod->s_opt->print) && (!tree->io->quiet)) Print_Lk(tree,"[Topology           ]");
+          if(tree->verbose > VL0 && tree->io->quiet == NO) Print_Lk(tree,"[Topology           ]");
 
           if(FABS(tree->c_lnL - init_lnL) < tree->mod->s_opt->min_diff_lk_move) return 0;
           return 1;
@@ -205,6 +206,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))
@@ -293,9 +295,9 @@ int Compute_Likelihood_Ratio_Test(t_edge *tested_edge, t_tree *tree)
               
               logK = 1. - MAX(MAX(tested_edge->nni->lk0,tested_edge->nni->lk1),tested_edge->nni->lk2);
               
-              Kp0 = EXP(tested_edge->nni->lk0+logK);
-              Kp1 = EXP(tested_edge->nni->lk1+logK);
-              Kp2 = EXP(tested_edge->nni->lk2+logK);
+              Kp0 = exp(tested_edge->nni->lk0+logK);
+              Kp1 = exp(tested_edge->nni->lk1+logK);
+              Kp2 = exp(tested_edge->nni->lk2+logK);
               tested_edge->ratio_test = Kp0/(Kp0+Kp1+Kp2);              
             }
         }
@@ -347,19 +349,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;
-  phydbl l_infa, l_infb;
+  scalar_dbl *l_init,*v_init;
   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 +381,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 +395,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.
@@ -402,30 +411,23 @@ int NNI_Neigh_BL(t_edge *b_fcus, t_tree *tree)
     {
       lk0 = lk_temp;
 
-      For(i,3) //a branch has three nodes
-        if(b_fcus->left->v[i] != b_fcus->rght)//Only consider left_1 and left_2
+      for(i=0;i<3;i++) //a branch has three nodes
+        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);
-            lk_temp = Br_Len_Brent(l_infb,l_infa,b_fcus->left->b[i],tree);
+            Update_Partial_Lk(tree,b_fcus->left->b[i],b_fcus->left);
+            lk_temp = Br_Len_Brent(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);
-      lk_temp = Br_Len_Brent(l_infb,l_infa,b_fcus,tree);
+      Update_Partial_Lk(tree,b_fcus,b_fcus->left);
+      lk_temp = Br_Len_Brent(b_fcus,tree);
 
-      For(i,3)
-        if(b_fcus->rght->v[i] != b_fcus->left)//Only consider right_1 and right_2
+      for(i=0;i<3;i++)
+        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);
-            lk_temp = Br_Len_Brent(l_infb,l_infa,b_fcus->rght->b[i],tree);
+            Update_Partial_Lk(tree,b_fcus->rght->b[i],b_fcus->rght);
+            lk_temp = Br_Len_Brent(b_fcus->rght->b[i],tree);
           }
-      Update_P_Lk(tree,b_fcus,b_fcus->rght);
+      Update_Partial_Lk(tree,b_fcus,b_fcus->rght);
 
       if(lk_temp < lk0 - tree->mod->s_opt->min_diff_lk_local)
         {
@@ -438,42 +440,39 @@ 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=0;site<tree->n_pattern;site++) 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);
   Update_PMat_At_Given_Edge(e4,tree);
   Update_PMat_At_Given_Edge(b_fcus,tree);
 
-
   /* Sanity check */
   MIXT_Set_Alias_Subpatt(YES,tree);
-  Update_P_Lk(tree,b_fcus,b_fcus->rght);
-  Update_P_Lk(tree,b_fcus,b_fcus->left);
+  Update_Partial_Lk(tree,b_fcus,b_fcus->rght);
+  Update_Partial_Lk(tree,b_fcus,b_fcus->left);
   lk_temp = Lk(b_fcus,tree);
   MIXT_Set_Alias_Subpatt(NO,tree);
   if((lk_temp > lk_init + tree->mod->s_opt->min_diff_lk_local) || (lk_temp < lk_init - tree->mod->s_opt->min_diff_lk_local))
@@ -488,18 +487,18 @@ int NNI_Neigh_BL(t_edge *b_fcus, t_tree *tree)
   Swap(v2,b_fcus->left,b_fcus->rght,v3,tree);
   MIXT_Set_Alias_Subpatt(YES,tree);
   Set_Both_Sides(YES,tree);
-  Update_P_Lk(tree,b_fcus,b_fcus->left);
-  Update_P_Lk(tree,b_fcus,b_fcus->rght);
+  Update_Partial_Lk(tree,b_fcus,b_fcus->left);
+  Update_Partial_Lk(tree,b_fcus,b_fcus->rght);
   lk1 = Lk(b_fcus,tree);
   MIXT_Set_Alias_Subpatt(NO,tree);
 
-  For(i,3)
+  for(i=0;i<3;i++)
     if(b_fcus->left->v[i] != b_fcus->rght)
-      Update_P_Lk(tree,b_fcus->left->b[i],b_fcus->left);
+      Update_Partial_Lk(tree,b_fcus->left->b[i],b_fcus->left);
   
-  For(i,3)
+  for(i=0;i<3;i++)
     if(b_fcus->rght->v[i] != b_fcus->left)
-      Update_P_Lk(tree,b_fcus->rght->b[i],b_fcus->rght);
+      Update_Partial_Lk(tree,b_fcus->rght->b[i],b_fcus->rght);
   
   
   /*! Optimize branch lengths and update likelihoods */
@@ -508,33 +507,24 @@ int NNI_Neigh_BL(t_edge *b_fcus, t_tree *tree)
     {
       lk1 = lk_temp;
       
-      For(i,3)
+      for(i=0;i<3;i++)
         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  = MAX(0.0,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);
+            Update_Partial_Lk(tree,b_fcus->left->b[i],b_fcus->left);
+            lk_temp = Br_Len_Brent(b_fcus->left->b[i],tree);
           }
       
-      Update_P_Lk(tree,b_fcus,b_fcus->left);
+      Update_Partial_Lk(tree,b_fcus,b_fcus->left);
+      lk_temp = Br_Len_Brent(b_fcus,tree);
       
-      l_infa  = 10.;
-      l_infb  = MAX(0.0,tree->mod->l_min/b_fcus->l->v);
-      lk_temp = Br_Len_Brent(l_infb,l_infa,b_fcus,tree);
-      
-      For(i,3)
+      for(i=0;i<3;i++)
         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  = MAX(0.0,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);
+            Update_Partial_Lk(tree,b_fcus->rght->b[i],b_fcus->rght);
+            lk_temp = Br_Len_Brent(b_fcus->rght->b[i],tree);
           }
       
-      Update_P_Lk(tree,b_fcus,b_fcus->rght);
+      Update_Partial_Lk(tree,b_fcus,b_fcus->rght);
       
       if(lk_temp < lk1 - tree->mod->s_opt->min_diff_lk_local)
         {
@@ -553,29 +543,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=0;site<tree->n_pattern;site++) 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);
@@ -586,8 +572,8 @@ int NNI_Neigh_BL(t_edge *b_fcus, t_tree *tree)
   
   /* Sanity check */
   MIXT_Set_Alias_Subpatt(YES,tree);
-  Update_P_Lk(tree,b_fcus,b_fcus->rght);
-  Update_P_Lk(tree,b_fcus,b_fcus->left);
+  Update_Partial_Lk(tree,b_fcus,b_fcus->rght);
+  Update_Partial_Lk(tree,b_fcus,b_fcus->left);
   lk_temp = Lk(b_fcus,tree);
   MIXT_Set_Alias_Subpatt(NO,tree);
   if((lk_temp > lk_init + tree->mod->s_opt->min_diff_lk_local) || (lk_temp < lk_init - tree->mod->s_opt->min_diff_lk_local))
@@ -601,18 +587,18 @@ int NNI_Neigh_BL(t_edge *b_fcus, t_tree *tree)
   Swap(v2,b_fcus->left,b_fcus->rght,v4,tree);
   Set_Both_Sides(YES,tree);
   MIXT_Set_Alias_Subpatt(YES,tree);
-  Update_P_Lk(tree,b_fcus,b_fcus->left);
-  Update_P_Lk(tree,b_fcus,b_fcus->rght);
+  Update_Partial_Lk(tree,b_fcus,b_fcus->left);
+  Update_Partial_Lk(tree,b_fcus,b_fcus->rght);
   lk2 = Lk(b_fcus,tree);
   MIXT_Set_Alias_Subpatt(NO,tree);
   
-  For(i,3)
+  for(i=0;i<3;i++)
     if(b_fcus->left->v[i] != b_fcus->rght)
-      Update_P_Lk(tree,b_fcus->left->b[i],b_fcus->left);
+      Update_Partial_Lk(tree,b_fcus->left->b[i],b_fcus->left);
   
-  For(i,3)
+  for(i=0;i<3;i++)
     if(b_fcus->rght->v[i] != b_fcus->left)
-      Update_P_Lk(tree,b_fcus->rght->b[i],b_fcus->rght);
+      Update_Partial_Lk(tree,b_fcus->rght->b[i],b_fcus->rght);
   
   /*! Optimize branch lengths and update likelihoods */
   lk_temp = UNLIKELY;
@@ -620,59 +606,50 @@ int NNI_Neigh_BL(t_edge *b_fcus, t_tree *tree)
     {
       lk2 = lk_temp;
       
-      For(i,3)
+      for(i=0;i<3;i++)
         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  = MAX(0.0,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);
+            Update_Partial_Lk(tree,b_fcus->left->b[i],b_fcus->left);
+            lk_temp = Br_Len_Brent(b_fcus->left->b[i],tree);
             
             if(lk_temp < lk2 - tree->mod->s_opt->min_diff_lk_local)
               {
-                PhyML_Printf("\n== l_infa: %f l_infb: %f l: %f var:%f",l_infa,l_infb,b_fcus->left->b[i]->l->v,b_fcus->left->b[i]->l_var->v);
+                PhyML_Printf("\n== l: %f var:%f",b_fcus->left->b[i]->l->v,b_fcus->left->b[i]->l_var->v);
                 PhyML_Printf("\n== lk_temp = %f lk2 = %f",lk_temp,lk2);
                 PhyML_Printf("\n== Err. in file %s at line %d",__FILE__,__LINE__);
                 Exit("\n");
               }
           }
-      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);
-      lk_temp = Br_Len_Brent(l_infb,l_infa,b_fcus,tree);
+      Update_Partial_Lk(tree,b_fcus,b_fcus->left);
+      lk_temp = Br_Len_Brent(b_fcus,tree);
       
       if(lk_temp < lk2 - tree->mod->s_opt->min_diff_lk_local)
         {
-          PhyML_Printf("\n== l_infa: %f l_infb: %f l: %f var:%f",l_infa,l_infb,b_fcus->l->v,b_fcus->l_var->v);
+          PhyML_Printf("\n== l: %f var:%f",b_fcus->l->v,b_fcus->l_var->v);
           PhyML_Printf("\n== lk_temp = %f lk2 = %f",lk_temp,lk2);
           PhyML_Printf("\n== Err. in file %s at line %d",__FILE__,__LINE__);
           Exit("\n");
         }
       
-      For(i,3)
+      for(i=0;i<3;i++)
         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  = MAX(0.0,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);
+            Update_Partial_Lk(tree,b_fcus->rght->b[i],b_fcus->rght);
+            lk_temp = Br_Len_Brent(b_fcus->rght->b[i],tree);
             
             if(lk_temp < lk2 - tree->mod->s_opt->min_diff_lk_local)
               {
                 Set_Both_Sides(YES,tree);
                 Lk(b_fcus,tree);
                 Check_Lk_At_Given_Edge(YES,tree);
-                PhyML_Printf("\n== l_infa: %f l_infb: %f l: %f var:%f",l_infa,l_infb,b_fcus->rght->b[i]->l->v,b_fcus->rght->b[i]->l_var->v);
+                PhyML_Printf("\n== l: %f var:%f",b_fcus->rght->b[i]->l->v,b_fcus->rght->b[i]->l_var->v);
                 PhyML_Printf("\n== lk_temp = %f lk2 = %f",lk_temp,lk2);
                 PhyML_Printf("\n== Err. in file %s at line %d",__FILE__,__LINE__);
                 Exit("\n");
               }
           }
       
-      Update_P_Lk(tree,b_fcus,b_fcus->rght);
+      Update_Partial_Lk(tree,b_fcus,b_fcus->rght);
       
     }
   while(FABS(lk_temp-lk2) > tree->mod->s_opt->min_diff_lk_global);
@@ -684,16 +661,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=0;site<tree->n_pattern;site++) tree->log_lks_aLRT[2][site]= tree->c_lnL_sorted[site];
       tree = tree->next_mixt;
     }
   while(tree);
@@ -705,11 +673,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);
@@ -719,16 +693,16 @@ int NNI_Neigh_BL(t_edge *b_fcus, t_tree *tree)
   Update_PMat_At_Given_Edge(b_fcus,tree);
 
   MIXT_Set_Alias_Subpatt(YES,tree);
-  Update_P_Lk(tree,b_fcus,b_fcus->left);
-  Update_P_Lk(tree,b_fcus,b_fcus->rght);
+  Update_Partial_Lk(tree,b_fcus,b_fcus->left);
+  Update_Partial_Lk(tree,b_fcus,b_fcus->rght);
 
-  For(i,3)
+  for(i=0;i<3;i++)
     if(b_fcus->left->v[i] != b_fcus->rght)
-      Update_P_Lk(tree,b_fcus->left->b[i],b_fcus->left);
+      Update_Partial_Lk(tree,b_fcus->left->b[i],b_fcus->left);
 
-  For(i,3)
+  for(i=0;i<3;i++)
     if(b_fcus->rght->v[i] != b_fcus->left)
-      Update_P_Lk(tree,b_fcus->rght->b[i],b_fcus->rght);
+      Update_Partial_Lk(tree,b_fcus->rght->b[i],b_fcus->rght);
 
   MIXT_Set_Alias_Subpatt(NO,tree);
 
@@ -769,11 +743,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;
 }
@@ -792,7 +771,6 @@ void Make_Target_Swap(t_tree *tree, t_edge *b_fcus, int swaptodo)
 {
   t_node *v1,*v2,*v3,*v4;
   phydbl lktodo;
-  phydbl l_infa, l_infb;
   phydbl lk_init, lk_temp;
   int i;
 
@@ -843,14 +821,14 @@ 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)
+  
+  for(i=0;i<3;i++)
     if(b_fcus->left->v[i] != b_fcus->rght)
-      Update_P_Lk(tree,b_fcus->left->b[i],b_fcus->left);
-
-  For(i,3)
+      Update_Partial_Lk(tree,b_fcus->left->b[i],b_fcus->left);
+  
+  for(i=0;i<3;i++)
     if(b_fcus->rght->v[i] != b_fcus->left)
-      Update_P_Lk(tree,b_fcus->rght->b[i],b_fcus->rght);
+      Update_Partial_Lk(tree,b_fcus->rght->b[i],b_fcus->rght);
 
   MIXT_Set_Alias_Subpatt(NO,tree);
 
@@ -860,43 +838,32 @@ 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);
-      }
-
-
-      Update_P_Lk(tree,b_fcus,b_fcus->left);
-
-      l_infa  = 10.;
-      l_infb  = tree->mod->l_min/b_fcus->l->v;
-      lk_temp = Br_Len_Brent(l_infb,l_infa,b_fcus,tree);
+      for(i=0;i<3;i++)
+        if(b_fcus->left->v[i] != b_fcus->rght)
+          {
+            Update_Partial_Lk(tree,b_fcus->left->b[i],b_fcus->left);
+            lk_temp = Br_Len_Brent(b_fcus->left->b[i],tree);
+          }
 
 
+      Update_Partial_Lk(tree,b_fcus,b_fcus->left);
+      lk_temp = Br_Len_Brent(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);
-      }
+      for(i=0;i<3;i++)
+        if(b_fcus->rght->v[i] != b_fcus->left)
+          {
+            Update_Partial_Lk(tree,b_fcus->rght->b[i],b_fcus->rght);
+            lk_temp = Br_Len_Brent(b_fcus->rght->b[i],tree);
+          }
 
-      Update_P_Lk(tree,b_fcus,b_fcus->rght);
+      Update_Partial_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,10 +880,9 @@ 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. 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__);
+      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,17 +1073,16 @@ 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;
 
   /*! 1000 times */
-  For(i,occurence)
+  for(i=0;i<occurence;i++)
     {
       lk0=0.0;
       lk1=0.0;
@@ -1127,19 +1092,19 @@ phydbl Statistics_to_RELL(t_tree *tree)
       buff_tree = tree;
       do
         {
+          pi = (phydbl *)mCalloc(tree->data->crunch_len,sizeof(phydbl));
+          for(site=0;site<tree->n_pattern;site++) 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 +1134,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;
     }
@@ -1227,7 +1192,7 @@ phydbl Statistics_To_SH(t_tree *tree)
     }
 
   /*! 1000 times */
-  For(i,occurence)
+  for(i=0;i<occurence;i++)
     {
       lk0=0.0;
       lk1=0.0;
@@ -1236,20 +1201,20 @@ phydbl Statistics_To_SH(t_tree *tree)
       buff_tree = tree;
       do
         {
+          pi = (phydbl *)mCalloc(tree->data->crunch_len,sizeof(phydbl));
+          for(site=0;site<tree->n_pattern;site++) 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;
@@ -1320,9 +1285,9 @@ phydbl Statistics_To_SH(t_tree *tree)
 phydbl Update_Lk_At_Given_Edge_Excluding(t_edge *b_fcus, t_tree *tree, t_node *exclude)
 {
   if((!b_fcus->left->tax) && (exclude == NULL || exclude != b_fcus->left))
-    Update_P_Lk(tree,b_fcus,b_fcus->left);
+    Update_Partial_Lk(tree,b_fcus,b_fcus->left);
   if((!b_fcus->rght->tax) && (exclude == NULL || exclude != b_fcus->rght))
-    Update_P_Lk(tree,b_fcus,b_fcus->rght);
+    Update_Partial_Lk(tree,b_fcus,b_fcus->rght);
 
   tree->c_lnL = Lk(b_fcus,tree);
 
diff --git a/src/avx.c b/src/avx.c
new file mode 100644
index 0000000..570bc45
--- /dev/null
+++ b/src/avx.c
@@ -0,0 +1,424 @@
+/*
+
+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 "assert.h"
+#include "avx.h"
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+#if defined(__AVX__)
+
+void AVX_Update_Eigen_Lr(t_edge *b, t_tree *tree)
+{
+  unsigned int site,catg,state;
+  int is_ambigu,observed_state;
+  unsigned int i,j,k,l;
+  
+  unsigned const int npattern = tree->n_pattern;
+  unsigned const int ncatg = tree->mod->ras->n_catg;
+  unsigned const int ns = tree->mod->ns;
+  unsigned const int sz = (int)BYTE_ALIGN / 8;  
+  unsigned const int ncatgns = ncatg * ns;
+  unsigned const int nblocks = ns / sz;
+
+  __m256d _fplk[nblocks],_fplkev[sz],_colsum[nblocks];
+  phydbl *ev;
+      
+  assert(sz == 4);  
+  assert(tree->update_eigen_lr == YES);
+  observed_state = -1;
+  
+  ev = NULL;
+#ifndef WIN32
+  if(posix_memalign((void **)&ev,BYTE_ALIGN,(size_t)sz*sizeof(double))) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
+#else
+  ev = _aligned_malloc(sz * sizeof(phydbl),BYTE_ALIGN);
+#endif
+    
+  for(site=0;site<npattern;++site)
+    {
+      is_ambigu = YES;
+      if(b->rght->tax == YES) is_ambigu = b->rght->c_seq->is_ambigu[site];
+      if(is_ambigu == NO) observed_state = b->rght->c_seq->d_state[site];
+
+      for(catg=0;catg<ncatg;++catg)
+        {
+          // Dot product left partial likelihood with equilibrium freqs
+          for(i=0;i<nblocks;++i) _fplk[i] = _mm256_mul_pd(_mm256_load_pd(&(b->p_lk_left[site*ncatgns + catg*ns + i*sz])),
+                                                          _mm256_load_pd(&(tree->mod->e_frq->pi->v[i*sz])));
+          
+          for(i=0;i<nblocks;++i) _colsum[i] = _mm256_setzero_pd();
+          // Multiply by matrix of right eigen vectors
+          // This matrix is made of nblocks*nblocks squares,
+          // each square being of 'area' sz*sz
+          for(i=0;i<nblocks;++i) // row 
+            {
+              for(j=0;j<nblocks;++j) // column
+                {
+                  for(k=0;k<sz;++k) // column in sz*sz square
+                    {
+                      for(l=0;l<sz;++l) // row in that same square
+                        {
+                          // Copy right eigen vector values column-by-column in block (i,j)
+                          ev[l] = tree->mod->eigen->r_e_vect[i*nblocks*sz*sz + j*sz + l*nblocks*sz + k];
+                        }
+                      _fplkev[k] = _mm256_mul_pd(_mm256_load_pd(ev),_fplk[i]);
+                    }
+                  _colsum[j] = _mm256_add_pd(_colsum[j],AVX_Horizontal_Add(_fplkev));
+                }
+            }          
+          for(j=0;j<nblocks;++j) _mm256_store_pd(&(tree->eigen_lr_left[catg*ns + j*sz]),_colsum[j]);
+
+
+          if(b->rght->tax == YES)
+            for(i=0;i<nblocks;++i) _fplk[i] = _mm256_load_pd(b->p_lk_tip_r + site*ns + i*sz); 
+          else
+            for(i=0;i<nblocks;++i) _fplk[i] = _mm256_load_pd(&(b->p_lk_rght[site*ncatgns + catg*ns + i*sz])); 
+
+          if(is_ambigu == YES)
+            {
+              for(i=0;i<nblocks;++i) _colsum[i] = _mm256_setzero_pd();
+              // Multiply by matrix of right eigen vectors
+              // This matrix is made of nblocks*nblocks squares,
+              // each square being of 'area' sz*sz
+              for(i=0;i<nblocks;++i) // row
+                {
+                  for(j=0;j<nblocks;++j) // column
+                    {
+                      for(l=0;l<sz;++l) // row in that same square
+                        {
+                          for(k=0;k<sz;++k) // column in sz*sz square
+                            {
+                              // Copy left eigen vector values column-by-column in block (i,j)
+                              ev[k] = tree->mod->eigen->l_e_vect[i*nblocks*sz*sz + j*sz + l*nblocks*sz + k];
+                            }                          
+                          _fplkev[l] = _mm256_mul_pd(_mm256_load_pd(ev),_fplk[j]);
+                        }
+                      _colsum[i] = _mm256_add_pd(_colsum[i],AVX_Horizontal_Add(_fplkev));
+                    }
+                }
+              for(j=0;j<nblocks;++j) _mm256_store_pd(&(tree->eigen_lr_rght[catg*ns + j*sz]),_colsum[j]);
+            }
+          else
+            {
+              for(state=0;state<ns;++state) tree->eigen_lr_rght[catg*ns + state] =
+                                              tree->mod->eigen->l_e_vect[state*ns + observed_state];
+            }
+          
+          for(j=0;j<nblocks;++j)
+            _mm256_store_pd(tree->dot_prod + site*ncatgns + catg*ns + j*sz,
+                            _mm256_mul_pd(_mm256_load_pd(tree->eigen_lr_rght + catg*ns + j*sz),
+                                          _mm256_load_pd(tree->eigen_lr_left + catg*ns + j*sz)));
+          
+        }
+    }
+
+  if(ev)  Free(ev);
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+phydbl AVX_Lk_Core_One_Class_No_Eigen_Lr(phydbl *p_lk_left, phydbl *p_lk_rght, phydbl *Pij, phydbl *pi, int ns, int ambiguity_check, int observed_state)
+{
+  const unsigned int sz = (int)BYTE_ALIGN / 8;
+  const unsigned nblocks = ns/sz;
+
+  __m256d _plk_l[nblocks],_plk_r[nblocks];
+  __m256d _plk; // parent partial likelihood
+
+  /* [ Pi . Lkr ]' x Pij x Lkl */
+
+  if(ambiguity_check == NO) // tip case.
+    {
+      unsigned int i;
+      for(i=0;i<nblocks;++i) _plk_l[i] = _mm256_load_pd(p_lk_left + i*sz);
+      for(i=0;i<nblocks;++i) _plk_r[i] = _mm256_load_pd(Pij + observed_state*ns + i*sz);
+      for(i=0;i<nblocks;++i) _plk_r[i] = _mm256_mul_pd(_plk_r[i],_mm256_set1_pd(pi[observed_state]));
+      for(i=0;i<nblocks;++i) _plk_r[i] = _mm256_mul_pd(_plk_r[i],_plk_l[i]);
+      _plk = _mm256_setzero_pd();
+      for(i=0;i<nblocks;++i) _plk = _mm256_add_pd(_plk,_plk_r[i]);
+      return AVX_Vect_Norm(_plk);
+    }
+  else
+    {
+      unsigned int i,j,k;
+      __m256d _pij[sz]; 
+      __m256d _pijplk[sz];
+      phydbl lk=.0;
+
+      for(i=0;i<nblocks;++i) _plk_r[i] = _mm256_load_pd(p_lk_rght + i*sz);
+      for(i=0;i<nblocks;++i) _plk_r[i] = _mm256_mul_pd(_plk_r[i],_mm256_load_pd(pi + i*sz));
+      for(i=0;i<nblocks;++i) _plk_l[i] = _mm256_load_pd(p_lk_left + i*sz);
+
+      for(j=0;j<nblocks;++j)
+        {
+          for(i=0;i<sz;++i) _pijplk[i] = _mm256_setzero_pd();
+
+          for(i=0;i<nblocks;++i)
+            {
+              for(k=0;k<sz;++k)
+                {
+                  _pij[k] = _mm256_load_pd(Pij + j*nblocks*sz*sz + i*sz + k*ns);
+                  _pij[k] = _mm256_mul_pd(_pij[k],_plk_l[i]);
+                  _pijplk[k] = _mm256_add_pd(_pijplk[k],_pij[k]);
+                }
+            }
+          
+          _plk = AVX_Horizontal_Add(_pijplk);
+          _plk = _mm256_mul_pd(_plk,_plk_r[j]);
+
+          lk += AVX_Vect_Norm(_plk);
+        }
+      return lk;
+    }
+  return UNLIKELY;
+}
+ 
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+phydbl AVX_Lk_Core_One_Class_Eigen_Lr(phydbl *dot_prod, phydbl *expl, unsigned int ns)
+{
+  unsigned int l;
+  const unsigned int sz = (int)BYTE_ALIGN / 8;
+  const unsigned nblocks = ns/sz;
+  __m256d _prod[nblocks],_x;
+  
+  for(l=0;l<nblocks;++l) _prod[l] = _mm256_load_pd(dot_prod + l*sz);
+  if(expl != NULL) for(l=0;l<nblocks;++l) _prod[l] = _mm256_mul_pd(_prod[l],_mm256_load_pd(expl + l*sz));
+  _x = _mm256_setzero_pd();
+  for(l=0;l<nblocks;++l) _x = _mm256_add_pd(_x,_prod[l]);
+  
+  return AVX_Vect_Norm(_x);
+}
+ 
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+phydbl AVX_Vect_Norm(__m256d _z)
+{
+  phydbl r;
+  __m256d _x = _mm256_hadd_pd(_z,_z);
+  __m256d _y = _mm256_permute2f128_pd(_x,_x,0x21);
+  _mm_store_sd(&r,_mm256_castpd256_pd128(_mm256_add_pd(_x,_y)));
+  return r;
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+__m256d AVX_Horizontal_Add(__m256d x[4])
+{
+  __m256d y[2],z[2];
+
+  // y[0] = [x00+x01;x10+x11;x02+x03;x12+x13]
+  y[0] = _mm256_hadd_pd(x[0], x[1]);
+  // y[1] = [x20+x21;x30+x31;x22+x23;x32+x33]
+  y[1] = _mm256_hadd_pd(x[2], x[3]);
+
+  // z[0] = [x00+x01;x10+x11;x22+x23;x32+x33]
+  /* z[0] = _mm256_blend_pd(y[0],y[1],0b1100); */
+  z[0] = _mm256_blend_pd(y[0],y[1],12);
+  // z[1] = [x02+x03;x12+x13;x20+x21;x30+x31]
+  z[1] = _mm256_permute2f128_pd(y[0],y[1],0x21);
+
+  return(_mm256_add_pd(z[0],z[1]));
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void AVX_Update_Partial_Lk(t_tree *tree, t_edge *b, t_node *d)
+{
+/*
+           |
+           |<- b
+           |
+           d
+          / \
+         /   \
+        /     \
+    n_v1   n_v2
+*/
+  t_node *n_v1, *n_v2;
+  phydbl *p_lk,*p_lk_v1,*p_lk_v2;
+  phydbl *Pij1,*Pij2;
+  phydbl *tPij1,*tPij2;
+  int *sum_scale, *sum_scale_v1, *sum_scale_v2;
+  int sum_scale_v1_val, sum_scale_v2_val;
+  unsigned int i,k;
+  unsigned int catg,site;
+  phydbl smallest_p_lk,largest_p_lk;
+  phydbl p_lk_lim_inf;
+  int *p_lk_loc;
+
+  const unsigned int npattern = tree->n_pattern;
+  const unsigned int ns = tree->mod->ns;
+  const unsigned int ncatg = tree->mod->ras->n_catg;
+
+  const unsigned int ncatgns =  ncatg * ns;
+  const unsigned int nsns =  ns * ns;
+    
+  const unsigned int sz = (int)BYTE_ALIGN / 8;
+  const unsigned nblocks = ns/sz;
+
+  __m256d _x1[nblocks], _x2[nblocks];
+  __m256d _plk[nblocks],_plk1[nblocks],_plk2[nblocks];
+
+  sum_scale_v1_val            = 0;
+  sum_scale_v2_val            = 0;  
+  p_lk_lim_inf                = (phydbl)P_LK_LIM_INF;
+  n_v1 = n_v2                 = NULL;
+  p_lk = p_lk_v1 = p_lk_v2    = NULL;
+  Pij1 = Pij2                 = NULL;
+  tPij1 = tPij2               = NULL;
+  sum_scale_v1 = sum_scale_v2 = NULL;
+  p_lk_loc                    = NULL;
+
+  Set_All_Partial_Lk(&n_v1,&n_v2,
+                     &p_lk,&sum_scale,&p_lk_loc,
+                     &Pij1,&tPij1,&p_lk_v1,&sum_scale_v1,
+                     &Pij2,&tPij2,&p_lk_v2,&sum_scale_v2,
+                     d,b,tree);
+  
+  if(tree->mod->augmented == YES && n_v1 && n_v1->tax == NO)
+    {
+      PhyML_Printf("\n== AVX version of the Update_Partial_Lk function does not");
+      PhyML_Printf("\n== allow augmented data.");
+      Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
+    }
+    
+  /* For every site in the alignment */
+  for(site=0;site<npattern;++site)
+    {
+      if(n_v1->tax == YES &&
+         n_v2->tax == YES &&
+         n_v1->c_seq->state[site] == 'X' &&
+         n_v2->c_seq->state[site] == 'X')
+        {
+          for(i=0;i<ncatgns;++i) p_lk[site*ncatgns + i] = 1.0;
+        }
+      else
+        {
+          /* For all rate classes */
+          for(catg=0;catg<ncatg;++catg)
+            {              
+              for(k=0;k<nblocks;++k) _plk1[k] = _mm256_setzero_pd();
+              for(k=0;k<nblocks;++k) _plk2[k] = _mm256_setzero_pd();
+              
+              for(i=0;i<ns;++i)
+                {
+                  for(k=0;k<nblocks;++k) _x1[k] = _mm256_setzero_pd();
+                  for(k=0;k<nblocks;++k) _x2[k] = _mm256_setzero_pd();
+                  
+                  if(n_v1->tax == NO)
+                    {
+                      if(p_lk_v1[site*ncatgns + catg*ns + i] > 0.0)
+                        {
+                          for(k=0;k<nblocks;++k) _x1[k] = _mm256_mul_pd(_mm256_load_pd(tPij1 + catg*nsns + i*ns + sz*k),
+                                                                        _mm256_set1_pd(p_lk_v1[site*ncatgns + catg*ns + i]));
+                          
+                          for(k=0;k<nblocks;++k) _plk1[k] = _mm256_add_pd(_plk1[k],_x1[k]);
+                        }
+                    }                  
+                  else
+                    {
+                      if(p_lk_v1[site*ns + i] > 0.0)
+                        {
+                          for(k=0;k<nblocks;++k) _x1[k] = _mm256_mul_pd(_mm256_load_pd(tPij1 + catg*nsns + i*ns + sz*k),
+                                                                        _mm256_set1_pd(p_lk_v1[site*ns + i]));
+                          
+                          for(k=0;k<nblocks;++k) _plk1[k] = _mm256_add_pd(_plk1[k],_x1[k]);
+                        }
+                    }
+                  
+                  if(n_v2->tax == NO)
+                    {
+                      if(p_lk_v2[site*ncatgns + catg*ns + i] > 0.0)
+                        {
+                          for(k=0;k<nblocks;++k) _x2[k] = _mm256_mul_pd(_mm256_load_pd(tPij2 + catg*nsns + i*ns + sz*k),
+                                                                        _mm256_set1_pd(p_lk_v2[site*ncatgns + catg*ns + i]));
+                          
+                          for(k=0;k<nblocks;++k) _plk2[k] = _mm256_add_pd(_plk2[k],_x2[k]);
+                        }
+                    }
+                  else
+                    {
+                      if(p_lk_v2[site*ns + i] > 0.0)
+                        {
+                          for(k=0;k<nblocks;++k) _x2[k] = _mm256_mul_pd(_mm256_load_pd(tPij2 + catg*nsns + i*ns + sz*k),
+                                                                        _mm256_set1_pd(p_lk_v2[site*ns + i]));
+                          
+                          for(k=0;k<nblocks;++k) _plk2[k] = _mm256_add_pd(_plk2[k],_x2[k]);
+                        }
+                    }
+                }
+              
+              for(k=0;k<nblocks;++k) _plk[k] = _mm256_mul_pd(_plk1[k],_plk2[k]);
+              
+              for(k=0;k<nblocks;++k) _mm256_store_pd(p_lk + site*ncatgns + catg*ns + sz*k,_plk[k]);
+              
+              
+              if(tree->scaling_method == SCALE_RATE_SPECIFIC)
+                {
+                  smallest_p_lk = BIG;
+                  for(i=0;i<ns;++i)
+                    if(p_lk[site*ncatgns+catg*ns+i] < smallest_p_lk)
+                      smallest_p_lk = p_lk[site*ncatgns+catg*ns+i] ;
+                  
+                  /* Current scaling values at that site */
+                  sum_scale_v1_val = (sum_scale_v1)?(sum_scale_v1[site*ncatg+catg]):(0);
+                  sum_scale_v2_val = (sum_scale_v2)?(sum_scale_v2[site*ncatg+catg]):(0);
+                  
+                  sum_scale[site*ncatg+catg] = sum_scale_v1_val + sum_scale_v2_val;
+                  
+                  /* Scaling. We have p_lk_lim_inf = 2^-500. Consider for instance that
+                     smallest_p_lk = 2^-600, then curr_scaler_pow will be equal to 100, and
+                     each element in the partial likelihood vector will be multiplied by
+                     2^100. */
+                  if(smallest_p_lk < p_lk_lim_inf &&
+                     tree->mod->augmented == NO &&
+                     tree->apply_lk_scaling == YES)
+                    {
+                      int curr_scaler_pow;
+                      curr_scaler_pow = (int)(-500.*LOG2-log(smallest_p_lk))/LOG2;
+                      sum_scale[site*ncatg+catg] += curr_scaler_pow;
+                      for(i=0;i<ns;++i) Rate_Correction(curr_scaler_pow, p_lk + site*ncatgns + catg*ns + i);
+                    }
+                }            
+            }          
+        }
+      if(tree->scaling_method == SCALE_FAST)
+        {
+          sum_scale_v1_val = (sum_scale_v1)?(sum_scale_v1[site]):(0);
+          sum_scale_v2_val = (sum_scale_v2)?(sum_scale_v2[site]):(0);              
+          sum_scale[site] = sum_scale_v1_val + sum_scale_v2_val;
+          
+          largest_p_lk = -BIG; 
+          for(i=0;i<ncatgns;++i)
+            if(p_lk[site*ncatgns+i] > largest_p_lk)
+              largest_p_lk = p_lk[site*ncatgns+i] ;
+          
+          if(largest_p_lk < INV_TWO_TO_THE_LARGE &&
+             tree->mod->augmented == NO &&
+             tree->apply_lk_scaling == YES)
+            {
+              for(i=0;i<ncatgns;++i) p_lk[site*ncatgns + i] *= TWO_TO_THE_LARGE;
+              sum_scale[site] += LARGE;
+            }
+        }      
+    }
+}
+
+#endif
diff --git a/src/avx.h b/src/avx.h
new file mode 100644
index 0000000..3d01cf8
--- /dev/null
+++ b/src/avx.h
@@ -0,0 +1,39 @@
+/*
+
+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 AVX_H
+#define AVX_H
+
+#include "utilities.h"
+#include "optimiz.h"
+#include "models.h"
+#include "free.h"
+#include "times.h"
+#include "mixt.h"
+
+
+#if defined(__AVX__)
+
+void AVX_Update_Partial_Lk(t_tree *tree,t_edge *b_fcus,t_node *n);
+__m256d AVX_Horizontal_Add(__m256d x[4]);
+void AVX_Update_Eigen_Lr(t_edge *b, t_tree *tree);
+phydbl AVX_Lk_Core_One_Class_Eigen_Lr(phydbl *dot_prod, phydbl *expl, unsigned int ns);
+phydbl AVX_Lk_Core_One_Class_No_Eigen_Lr(phydbl *p_lk_left,phydbl *p_lk_rght,phydbl *Pij,phydbl *pi,int ns, int ambiguity_check, int observed_state);  
+phydbl AVX_Vect_Norm(__m256d _z);
+phydbl AVX_Lk_Core(int state, int ambiguity_check, t_edge *b, t_tree *tree);
+phydbl AVX_Lk_Core_Nucl(int state, int ambiguity_check, t_edge *b, t_tree *tree);
+phydbl AVX_Lk_Core_AA(int state, int ambiguity_check, t_edge *b, t_tree *tree);
+
+#endif
+#endif
diff --git a/src/beagle_utils.c b/src/beagle_utils.c
index 0b318a2..5fcf6df 100644
--- a/src/beagle_utils.c
+++ b/src/beagle_utils.c
@@ -53,7 +53,7 @@ void print_beagle_flags(long inFlags) {
     if (inFlags & BEAGLE_FLAG_SCALING_ALWAYS)     fprintf(stdout, " SCALING_ALWAYS");
     if (inFlags & BEAGLE_FLAG_SCALING_DYNAMIC)    fprintf(stdout, " SCALING_DYNAMIC");
     if (inFlags & BEAGLE_FLAG_SCALERS_RAW)        fprintf(stdout, " SCALERS_RAW");
-    if (inFlags & BEAGLE_FLAG_SCALERS_LOG)        fprintf(stdout, " SCALERS_LOG");
+    if (inFlags & BEAGLE_FLAG_SCALERS_log)        fprintf(stdout, " SCALERS_log");
     if (inFlags & BEAGLE_FLAG_VECTOR_NONE)        fprintf(stdout, " VECTOR_NONE");
     if (inFlags & BEAGLE_FLAG_VECTOR_SSE)         fprintf(stdout, " VECTOR_SSE");
     if (inFlags & BEAGLE_FLAG_VECTOR_AVX)         fprintf(stdout, " VECTOR_AVX");
@@ -359,7 +359,7 @@ if(ret<0){
   }
   //Transform
   for(i=0;i<tree->n_pattern;++i)
-    tree->cur_site_lk[i]=EXP(tree->cur_site_lk[i]);
+    tree->cur_site_lk[i]=exp(tree->cur_site_lk[i]);
 }
 
 void update_beagle_eigen(t_mod* mod)
@@ -370,10 +370,10 @@ void update_beagle_eigen(t_mod* mod)
     //We use Eigen Decomposition only for GTR models and AA datasets
     if((mod->io->datatype == AA || whichmodel==GTR || whichmodel==CUSTOM) && mod->use_m4mod == NO)
     {
-        //Beagle expects untransformed eigen-values (i.e. recall e_val is EXP() scaled, so we undo that)
+        //Beagle expects untransformed eigen-values (i.e. recall e_val is exp() scaled, so we undo that)
         phydbl* evals = (phydbl*)malloc(mod->ns * sizeof(phydbl));
         int i;
-        for(i=0;i<mod->ns;++i)  evals[i]=LOG(mod->eigen->e_val[i]);
+        for(i=0;i<mod->ns;++i)  evals[i]=log(mod->eigen->e_val[i]);
         int ret=-1;
         if((sizeof(float)==sizeof(phydbl)))//Need to convert to doubles?
         {
diff --git a/src/bionj.c b/src/bionj.c
index 8934ce1..8fcdb91 100644
--- a/src/bionj.c
+++ b/src/bionj.c
@@ -1,7 +1,7 @@
 /*
 
-PHYML :  a program that  computes maximum likelihood  phyLOGenies from
-DNA or AA homoLOGous sequences 
+PHYML :  a program that  computes maximum likelihood  phylogenies from
+DNA or AA homologous sequences 
 
 Copyright (C) Stephane Guindon. Oct 2003 onward
 
@@ -28,7 +28,7 @@ void Bionj(matrix *mat)
   phydbl vxy,lx,ly,lamda,score;
 
   Clean_Tree_Connections(mat->tree);  
-  For(i,mat->tree->n_otu) mat->tip_node[i] = mat->tree->a_nodes[i];
+  for(i=0;i<mat->tree->n_otu;i++) mat->tip_node[i] = mat->tree->a_nodes[i];
   mat->tree->num_curr_branch_available = 0;
 
   while(mat->r > 3)
@@ -62,7 +62,7 @@ void Finish(matrix *mat)
   dxy = dxz = dyz = -1.;
   x = y = z = -1;
 
-  For(i,mat->n_otu)
+  for(i=0;i<mat->n_otu;i++)
     {
       if(mat->on_off[i])
 	{
@@ -115,7 +115,7 @@ void Update_Mat(matrix *mat, int x, int y, phydbl lx, phydbl ly, phydbl vxy, phy
   int a,b;
   
   a = b = -1;
-  For(i,mat->n_otu)
+  for(i=0;i<mat->n_otu;i++)
     {
       if((mat->on_off[i]) && (i != x) && (i != y))
 	{
@@ -190,7 +190,7 @@ void Best_Pair(matrix *mat, int *x, int *y,phydbl *score)
 
   Qmin = 1.e+10;
   
-  For(i,mat->n_otu)
+  for(i=0;i<mat->n_otu;i++)
     {
       if(mat->on_off[i])
 	{
@@ -212,7 +212,7 @@ void Best_Pair(matrix *mat, int *x, int *y,phydbl *score)
     }
   
 /*   n_ties = 0; */
-/*   For(i,mat->n_otu) */
+/*   for(i=0;i<mat->n_otu;i++) */
 /*     { */
 /*       if(mat->on_off[i]) */
 /* 	{ */
@@ -251,12 +251,12 @@ void Best_Pair(matrix *mat, int *x, int *y,phydbl *score)
 
   Qmin2 = 1e+10;
 
-  For(i,mat->n_otu)
+  for(i=0;i<mat->n_otu;i++)
     {
       if((i != *y) && (i != *x) && (t_Qij[mat->n_otu*(*x)+i] < Qmin2)) Qmin2 = t_Qij[mat->n_otu*(*x)+i];
     }
 
-  For(i,mat->n_otu)
+  for(i=0;i<mat->n_otu;i++)
     {
       if((i != *y) && (i != *x) && (t_Qij[mat->n_otu*i+(*y)] < Qmin2)) Qmin2 = t_Qij[mat->n_otu*i+(*y)];
     }
@@ -275,12 +275,12 @@ void Compute_Sx(matrix *mat)
 {
   int i,j;
   
-  For(i,mat->n_otu)
+  for(i=0;i<mat->n_otu;i++)
     {
       mat->dist[i][i] = .0;
       if(mat->on_off[i])
 	{
-	  For(j,mat->n_otu)
+	  for(j=0;j<mat->n_otu;j++)
 	    {
 	      if((i != j) && (mat->on_off[j]))
 		{
@@ -378,7 +378,7 @@ phydbl Lamda(matrix *mat, int x, int y, phydbl vxy)
 	  lamda=0.5;
 	else
 	  {
-	    For(i,mat->n_otu)
+	    for(i=0;i<mat->n_otu;i++)
 	      {
 		if((x != i) && (y != i) && (mat->on_off[i]))
 		  lamda = lamda + BioNJ_Variance(mat,y,i) - BioNJ_Variance(mat,x,i);
@@ -441,7 +441,7 @@ int Bionj_Br_Length_Post(t_node *a, t_node *d, matrix *mat)
       int x,y;
 
       d_v1 = d_v2 = -1;
-      For(i,3)
+      for(i=0;i<3;i++)
 	if(d->v[i] != a) {(d_v1 < 0)?(d_v1 = i):(d_v2 = i);}
       
 
diff --git a/src/cl.c b/src/cl.c
index 4e75756..3a1c2ef 100644
--- a/src/cl.c
+++ b/src/cl.c
@@ -1,7 +1,7 @@
 /*
 
-PhyML:  a program that  computes maximum likelihood phyLOGenies from
-DNA or AA homoLOGous sequences.
+PhyML:  a program that  computes maximum likelihood phylogenies from
+DNA or AA homologous sequences.
 
 Copyright (C) Stephane Guindon. Oct 2003 onward.
 
@@ -24,12 +24,14 @@ int Read_Command_Line(option *io, int argc, char **argv)
   int i;
   int writemode;
 
-  PhyML_Printf("\n. command-line: ");
-  For(i,argc) PhyML_Printf("%s ",argv[i]);
-
-
-  if(argc == 1) Exit("\n. No argument was passed to the program. Please check the documentation. \n");
+  PhyML_Printf("\n. Command line: ");
+  for(i=0;i<argc;i++) PhyML_Printf("%s ",argv[i]);
+  PhyML_Printf("\n");
+  writemode = WRITE;
 
+  if(argc == 1) Exit("\n== No argument was passed to the program. Please check the documentation. \n");
+  PhyML_Printf("",writemode);
+  
   struct option longopts[] =
     {
       {"n_rgrft",           required_argument,NULL,0},
@@ -123,6 +125,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 +145,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 +212,32 @@ 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(PHYTIME)
+
+            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;
@@ -333,7 +362,6 @@ int Read_Command_Line(option *io, int argc, char **argv)
 	  }
 	case 59:
 	  {
-	    io->mcmc->use_data = NO;
 	    break;
 	  }
 	case 58:
@@ -487,7 +515,7 @@ int Read_Command_Line(option *io, int argc, char **argv)
 	  }
 	case 40 :
 	  {
-	    writemode = 2;
+	    writemode = APPEND;
 	    break;
 	  }
 	case 39 :
@@ -508,9 +536,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 +1046,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 +1058,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 +1067,40 @@ 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->e_frq = (t_efrq *)Make_Efrq(4);
+                Init_Efrq(NULL,io->mod->e_frq);
+
+		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;
@@ -1121,20 +1147,20 @@ int Read_Command_Line(option *io, int argc, char **argv)
 		strcpy(io->out_file, optarg);
 		strcpy(io->out_tree_file,optarg);
 #ifdef PHYML
-		strcat(io->out_tree_file,"_phyml_tree");
+		strcat(io->out_tree_file,"_phyml_tree.txt");
 #elif M4
-		strcat(io->out_tree_file,"_m4_tree");
+		strcat(io->out_tree_file,"_m4_tree.txt");
 #elif PHYREX
-		strcat(io->out_tree_file,"_phyrex_tree");
+		strcat(io->out_tree_file,"_phyrex_tree.txt");
 #endif
                 
 		strcpy(io->out_stats_file,optarg);
 #ifdef PHYML
-		strcat(io->out_stats_file,"_phyml_stats");
+		strcat(io->out_stats_file,"_phyml_stats.txt");
 #elif M4
-		strcat(io->out_stats_file,"_m4_stats");
+		strcat(io->out_stats_file,"_m4_stats.txt");
 #elif PHYREX
-		strcat(io->out_stats_file,"_phyrex_stats");
+		strcat(io->out_stats_file,"_phyrex_stats.txt");
 #endif
 
 
@@ -1314,7 +1340,7 @@ int Read_Command_Line(option *io, int argc, char **argv)
 	    else
 	      {
 		char choix;
-		PhyML_Printf ("\n. The optimization parameter must be 'tlr' or 'tl' or 'lr' or 'l' or 'r' or ''.");
+		PhyML_Printf ("\n. The optimization parameter must be 'tlr' or 'tl' or 'lr' or 'l' or 'r' or 'n'.");
 		PhyML_Printf("\n. Type any key to exit.\n");
 		if(!scanf("%c",&choix)) Exit("\n");
 		Exit("\n");
@@ -1398,9 +1424,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;
@@ -1418,7 +1441,7 @@ int Read_Command_Line(option *io, int argc, char **argv)
   if(io->print_site_lnl)
     {
       strcpy(io->out_lk_file,io->in_align_file);
-      strcat(io->out_lk_file, "_phyml_lk");
+      strcat(io->out_lk_file, "_phyml_lk.txt");
       if(io->append_run_ID) { strcat(io->out_lk_file,"_"); strcat(io->out_lk_file,io->run_id_string); }
       io->fp_out_lk = Openfile(io->out_lk_file,1);
     }
@@ -1426,15 +1449,24 @@ int Read_Command_Line(option *io, int argc, char **argv)
   if(io->print_trace)
     {
       strcpy(io->out_trace_file,io->in_align_file);
-      strcat(io->out_trace_file,"_phyml_trace");
+      strcat(io->out_trace_file,"_phyml_trace.txt");
       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)
     {
       strcpy(io->out_trees_file,io->in_align_file);
-      strcat(io->out_trees_file,"_phyml_rand_trees");
+      strcat(io->out_trees_file,"_phyml_rand_trees.txt");
       if(io->append_run_ID) { strcat(io->out_trees_file,"_"); strcat(io->out_trees_file,io->run_id_string); }
       io->fp_out_trees = Openfile(io->out_trees_file,1);
     }
@@ -1442,12 +1474,12 @@ int Read_Command_Line(option *io, int argc, char **argv)
   if((io->print_boot_trees) && (io->mod->bootstrap > 0))
     {
       strcpy(io->out_boot_tree_file,io->in_align_file);
-      strcat(io->out_boot_tree_file,"_phyml_boot_trees");
+      strcat(io->out_boot_tree_file,"_phyml_boot_trees.txt");
       if(io->append_run_ID) { strcat(io->out_boot_tree_file,"_"); strcat(io->out_boot_tree_file,io->run_id_string); }
       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");
+      strcat(io->out_boot_stats_file,"_phyml_boot_stats.txt");
       if(io->append_run_ID) { strcat(io->out_boot_stats_file,"_"); strcat(io->out_boot_stats_file,io->run_id_string); }
       io->fp_out_boot_stats = Openfile(io->out_boot_stats_file,1);
     }
@@ -1464,11 +1496,11 @@ int Read_Command_Line(option *io, int argc, char **argv)
   
   if(!io->mod->s_opt->opt_subst_param)
     {
-      io->mod->s_opt->opt_alpha  = 0;
-      io->mod->s_opt->opt_kappa  = 0;
-      io->mod->s_opt->opt_lambda = 0;
-      io->mod->s_opt->opt_pinvar = 0;
-      io->mod->s_opt->opt_rr     = 0;	
+      io->mod->s_opt->opt_alpha  = NO;
+      io->mod->s_opt->opt_kappa  = NO;
+      io->mod->s_opt->opt_lambda = NO;
+      io->mod->s_opt->opt_pinvar = NO;
+      io->mod->s_opt->opt_rr     = NO;	
     }
   
   if(io->mod->whichmodel != K80 && 
@@ -1488,9 +1520,8 @@ int Read_Command_Line(option *io, int argc, char **argv)
 #if !defined(PHYTIME) 
   // Make sure you don't erase the input file...
   if(!strcmp(io->out_tree_file,io->in_align_file) ||
-     !strcmp(io->out_stats_file,io->in_align_file)) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);    
-
-  writemode = WRITE;
+     !strcmp(io->out_stats_file,io->in_align_file)) 
+    Generic_Exit(__FILE__,__LINE__,__FUNCTION__);    
 
   io->fp_out_tree  = Openfile(io->out_tree_file,writemode);
   io->fp_out_stats = Openfile(io->out_stats_file,writemode);
@@ -1500,8 +1531,6 @@ int Read_Command_Line(option *io, int argc, char **argv)
 #if defined(PHYREX)
   io->fp_out_summary = Openfile(io->out_summary_file,writemode);
 #endif
-
-  writemode++; // just to silence a warning message at compilation
   
   if(io->mod->whichmodel == GTR) 
     {
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..24aef1d
--- /dev/null
+++ b/src/date.c
@@ -0,0 +1,1249 @@
+/*
+
+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;
+
+  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,*tree;
+  phydbl low,up,*res;
+  char *clade_name;
+  int seed;
+  
+  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);
+
+  
+  tree = mixt_tree;
+  do
+    {
+      // All rate stuctures point to the same object
+      tree->rates = mixt_tree->rates;
+      tree = tree->next;
+    }
+  while(tree);
+
+  
+  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); */
+  xroot = mixt_tree->xml_root;
+
+  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_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);
+  MIXT_Connect_Cseqs_To_Nodes(mixt_tree);
+  MIXT_Init_T_Beg(mixt_tree);
+  MIXT_Chain_Edges(mixt_tree);
+  MIXT_Chain_Nodes(mixt_tree);
+  Add_Root(mixt_tree->a_edges[0],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);
+
+  
+  
+  xnd = xroot->child;
+  assert(xnd);
+  do
+    {
+      if(!strcmp(xnd->name,"calibration")) // Found a XML node <calibration>.
+	{
+          // 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);
+	  if(xnd_dum != NULL) low = String_To_Dbl(xnd_dum->value); 
+
+	  xnd_dum = XML_Search_Node_Name("upper",YES,xnd);
+	  if(xnd_dum != NULL) up = String_To_Dbl(xnd_dum->value);
+          
+          xnd_cal = xnd->child;
+          do
+            {
+              if(!strcmp("appliesto",xnd_cal->name)) 
+                {
+                  clade_name = XML_Get_Attribute_Value(xnd_cal,"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 **xclade,**clade;
+                          int clade_size,nd_num;
+                          t_cal *cal;
+                          int i;
+                          
+                          xclade     = 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();
+
+                          clade = (char **)mCalloc(clade_size,sizeof(char *));
+                          for(i=0;i<clade_size;i++) clade[i] = (char *)mCalloc(strlen(xclade[i])+1,sizeof(char));
+                          for(i=0;i<clade_size;i++) strcpy(clade[i],xclade[i]);
+
+                          cal->clade_id = (char *)mCalloc(strlen(clade_name)+1,sizeof(char));
+                          strcpy(cal->clade_id,clade_name);
+                          
+                          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);
+
+                          cal->target_tip = Make_Target_Tip(cal->n_target_tax);
+                          Init_Target_Tip(cal,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. .......................................................................");
+
+                          Free(xclade);
+                        }
+                      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 = xnd_cal->next;
+            }
+          while(xnd_cal != NULL);
+        }
+      xnd = xnd->next;
+    }
+  while(xnd != NULL);
+  
+  seed = (mixt_tree->io->r_seed < 0)?(time(NULL)):(mixt_tree->io->r_seed);
+  srand(seed);
+  mixt_tree->io->r_seed = seed;
+  PhyML_Printf("\n. Seed: %d",seed);
+
+  MIXT_Chain_Cal(mixt_tree);
+
+  mixt_tree->rates->model = GAMMA;
+  
+  res = DATE_MCMC(mixt_tree);
+
+
+  // Cleaning up...
+  RATES_Free_Rates(mixt_tree->rates);
+  RATES_Free_Rates(mixt_tree->extra_tree->rates);
+  MCMC_Free_MCMC(mixt_tree->mcmc);
+  MCMC_Free_MCMC(mixt_tree->extra_tree->mcmc);
+  Free_Mmod(mixt_tree->mmod);
+  Free_Spr_List(mixt_tree);
+  Free_Triplet(mixt_tree->triplet_struct);
+  Free_Tree_Pars(mixt_tree);
+  Free_Tree_Lk(mixt_tree);
+
+  if(mixt_tree->io->fp_out_trees)      fclose(mixt_tree->io->fp_out_trees);
+  if(mixt_tree->io->fp_out_tree)       fclose(mixt_tree->io->fp_out_tree);
+  if(mixt_tree->io->fp_out_stats)      fclose(mixt_tree->io->fp_out_stats);
+  if(mixt_tree->io->fp_out_json_trace) fclose(mixt_tree->io->fp_out_json_trace);
+  Free_Input(mixt_tree->io);
+
+
+  tree = mixt_tree;
+  do
+    {
+      Free_Calign(tree->data);
+      tree = tree->next_mixt;
+    }
+  while(tree);
+
+  tree = mixt_tree;
+  do
+    {
+      Free_Optimiz(tree->mod->s_opt);
+      tree = tree->next;
+    }
+  while(tree);
+
+  
+  Free_Model_Complete(mixt_tree->mod);
+  Free_Model_Basic(mixt_tree->mod);
+  Free_Tree(mixt_tree->extra_tree);  
+  Free_Tree(mixt_tree);  
+  Free(res);
+  XML_Free_XML_Tree(xroot);
+  fclose(fp_xml_in);
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+// 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;
+
+  /* printf("\n"); */
+  
+  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],tree->a_nodes[i]->cal[j]->lower);
+            }         
+        }
+    }
+
+  /* // TO DO: chain t_rank */
+  /* TIMES_Update_Node_Ordering(tree); */
+  /* rk = tree->rates->t_rank; */
+
+  /* for(i=0;i<tree->n_otu-2;i++) */
+  /*   { */
+  /*     /\* printf("\n> [%3d] t:%f|%f -- min:%f|%f", *\/ */
+  /*     /\*        tree->a_nodes[rk[i+1]]->num, *\/ */
+  /*     /\*        tree->rates->nd_t[rk[i]], *\/ */
+  /*     /\*        tree->rates->nd_t[rk[i+1]], *\/ */
+  /*     /\*        tree->rates->t_prior_min[rk[i]], *\/ */
+  /*     /\*        tree->rates->t_prior_min[rk[i+1]]); *\/ */
+
+  /*     if(tree->rates->t_prior_min[rk[i+1]] < tree->rates->t_prior_min[rk[i]]) */
+  /*       { */
+  /*         /\* printf("  --> %f",tree->rates->t_prior_min[rk[i]]); *\/ */
+  /*         tree->rates->t_prior_min[rk[i+1]] = tree->rates->t_prior_min[rk[i]]; */
+  /*       } */
+  /*   } */
+  
+
+  /* for(i=tree->n_otu-2;i>0;i--) */
+  /*   { */
+  /*     /\* printf("\n< [%3d] t:%f|%f -- max:%f|%f", *\/ */
+  /*     /\*        tree->a_nodes[rk[i-1]]->num, *\/ */
+  /*     /\*        tree->rates->nd_t[rk[i]], *\/ */
+  /*     /\*        tree->rates->nd_t[rk[i-1]], *\/ */
+  /*     /\*        tree->rates->t_prior_max[rk[i]], *\/ */
+  /*     /\*        tree->rates->t_prior_max[rk[i-1]]); *\/ */
+  /*     if(tree->rates->t_prior_max[rk[i-1]] > tree->rates->t_prior_max[rk[i]]) */
+  /*       { */
+  /*         /\* printf("  --> %f ",tree->rates->t_prior_max[rk[i]]); *\/ */
+  /*         tree->rates->t_prior_max[rk[i-1]] = tree->rates->t_prior_max[rk[i]]; */
+  /*       } */
+  /*   } */
+    
+  /* /\* for(i=tree->n_otu;i<2*tree->n_otu-1;i++) *\/ */
+  /* /\*   { *\/ */
+  /* /\*     if(tree->rates->t_prior_min[i] > tree->rates->t_prior_max[i]) *\/ */
+  /* /\*       { *\/ */
+  /* /\*         PhyML_Printf("\n== i: %d t_prior_min: %f t_prior_max: %f", *\/ */
+  /* /\*                      i, *\/ */
+  /* /\*                      tree->rates->t_prior_min[i], *\/ */
+  /* /\*                      tree->rates->t_prior_max[i]); *\/ */
+  /* /\*         Generic_Exit(__FILE__,__LINE__,__FUNCTION__); *\/ */
+  /* /\*       } *\/ */
+  /* /\*   } *\/ */
+  
+  /* /\* printf("\n. min:%f max:%f rk: %d n_cal: %d low: %f up: %f", *\/ */
+  /* /\*        tree->rates->t_prior_min[tree->n_root->num], *\/ */
+  /* /\*        tree->rates->t_prior_max[tree->n_root->num], *\/ */
+  /* /\*        tree->rates->t_rank[tree->n_root->num], *\/ */
+  /* /\*        tree->a_nodes[tree->n_root->num]->n_cal, *\/ */
+  /* /\*        tree->a_nodes[tree->n_root->num]->n_cal > 0 ? tree->a_nodes[tree->n_root->num]->cal[0]->lower : -1, *\/ */
+  /* /\*        tree->a_nodes[tree->n_root->num]->n_cal > 0 ? tree->a_nodes[tree->n_root->num]->cal[0]->upper : -1); *\/ */
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void DATE_Assign_Primary_Calibration(t_tree *tree)
+{
+  int i,j,idx,node_num;
+
+  for(i=0;i<tree->rates->n_cal;i++) tree->rates->a_cal[i]->target_nd = NULL;
+  
+  For(i,2*tree->n_otu-1) 
+    for(j=0;j<MAX_N_CAL;j++) 
+    {
+      tree->a_nodes[i]->cal[j] = NULL;
+      tree->a_nodes[i]->n_cal  = 0;
+    }
+  
+  for(i=0;i<tree->rates->n_cal;i++)
+    {
+      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]->cal[idx]->target_nd = tree->a_nodes[node_num];
+      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");
+        }
+    }
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+// 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=0;i<len-1;i++) 
+        {
+          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=0;i<len-1;i++) assert(!(minmax[i] > minmax[i+1]));
+  
+  // Remove ties
+  for(i=0;i<len-1;i++) 
+    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=0;i<len-1;i++) 
+        {
+          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);
+
+  Free(splitted_cal);
+
+  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);
+
+  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;
+                
+        if(tree->rates->t_rank[tree->n_otu-2] == d->num) // Youngest internal node 
+          {
+            (*total) += prod;
+            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;
+      }
+    }
+
+  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);
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+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])
+            {
+              /* PhyML_Printf("\n. Node %d t: %f min:%f max:%f",i,tree->rates->nd_t[i],tree->rates->t_prior_min[i],tree->rates->t_prior_max[i]); */
+              return 0;
+            }
+        }
+    }
+  return 1;
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+phydbl *DATE_MCMC(t_tree *tree)
+{
+  t_mcmc *mcmc;
+  char *s_tree;
+  int move, n_vars, i, adjust_len;
+  phydbl u;
+  phydbl *res;
+  FILE *fp_stats,*fp_tree;
+  int t_beg;
+
+  t_beg = (int)time(NULL);
+
+  fp_stats = tree->io->fp_out_stats;
+  fp_tree = tree->io->fp_out_tree;
+  
+  TIMES_Randomize_Tree_With_Time_Constraints(tree->rates->a_cal[0],tree);
+
+  mcmc = MCMC_Make_MCMC_Struct();
+  tree->mcmc = mcmc;
+  MCMC_Init_MCMC_Struct(NULL,NULL,mcmc);
+  MCMC_Complete_MCMC(mcmc,tree);
+  
+  MCMC_Randomize_Birth(tree);
+  MCMC_Randomize_Death(tree);
+  MCMC_Randomize_Clock_Rate(tree);
+  MCMC_Randomize_Rate_Across_Sites(tree);
+  MCMC_Randomize_Rates(tree);
+  
+  n_vars                  = 10;
+  adjust_len              = 1E+5;
+  mcmc->sample_interval   = 200;
+  mcmc->print_every       = 10;
+  mcmc->chain_len         = 1E+7;
+  tree->rates->bl_from_rt = YES;
+
+  res = (phydbl *)mCalloc(tree->mcmc->chain_len / tree->mcmc->sample_interval * n_vars,sizeof(phydbl));
+  
+  Set_Both_Sides(YES,tree);
+  Switch_Eigen(YES,tree->mod);
+  Lk(NULL,tree);
+  Switch_Eigen(NO,tree->mod);
+  RATES_Lk_Rates(tree);
+  DATE_Assign_Primary_Calibration(tree);
+  TIMES_Lk_Times(NO,tree);
+
+  /* Time_To_Branch(tree); */
+  /* tree->bl_ndigits = 1; */
+  /* printf("\n. Random init tree: %s",Write_Tree(tree,NO)); */
+  /* tree->bl_ndigits = 7; */
+  RATES_Update_Cur_Bl(tree);
+  PhyML_Printf("\n. log(Pr(Seq|Tree)) = %f",tree->c_lnL);
+  PhyML_Printf("\n. log(Pr(Tree)) = %f",tree->rates->c_lnL_times);
+    
+  tree->extra_tree = Make_Tree_From_Scratch(tree->n_otu,tree->data);
+  Copy_Tree(tree,tree->extra_tree);
+  tree->extra_tree->rates = RATES_Make_Rate_Struct(tree->n_otu);
+  RATES_Init_Rate_Struct(tree->extra_tree->rates,NULL,tree->n_otu);
+  RATES_Copy_Rate_Struct(tree->rates,tree->extra_tree->rates,tree->n_otu);
+  RATES_Duplicate_Calib_Struct(tree,tree->extra_tree);
+  MIXT_Chain_Cal(tree->extra_tree);
+  DATE_Assign_Primary_Calibration(tree->extra_tree);
+  TIMES_Randomize_Tree_With_Time_Constraints(tree->extra_tree->rates->a_cal[0],tree->extra_tree);
+  TIMES_Lk_Times(NO,tree->extra_tree);
+  PhyML_Printf("\n. log(Pr(extra tree)) = %f",tree->extra_tree->rates->c_lnL_times);
+  mcmc = MCMC_Make_MCMC_Struct();
+  tree->extra_tree->mcmc = mcmc;
+  MCMC_Init_MCMC_Struct(NULL,NULL,mcmc);
+  MCMC_Complete_MCMC(mcmc,tree->extra_tree);
+
+ 
+  PhyML_Fprintf(fp_stats,"\n%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t",
+                "sample",
+                "lnL(posterior)",
+                "lnL(seq)",
+                "lnL(times)",
+                "lnL(rates)",
+                "birth",
+                "death",
+                "clock",
+                "root",
+                "tstv",
+                "nu");
+  for(i=0;i<tree->mod->ras->n_catg;i++) PhyML_Fprintf(fp_stats,"rr%d\t",i);
+  for(i=0;i<tree->mod->ras->n_catg;i++) PhyML_Fprintf(fp_stats,"pr%d\t",i);
+
+  for(i=0;i<tree->rates->n_cal;i++) PhyML_Fprintf(fp_stats,"t(%s)\t",tree->rates->a_cal[i]->clade_id);
+          
+  For(i,2*tree->n_otu-2) PhyML_Fprintf(fp_stats,"br%d\t",i);
+  
+  PhyML_Fprintf(fp_stats,"accRT\t");
+  PhyML_Fprintf(fp_stats,"tuneRT\t");
+
+  PhyML_Fprintf(fp_stats,"accT\t");
+  PhyML_Fprintf(fp_stats,"tuneT\t");
+
+  PhyML_Fprintf(fp_stats,"accClock\t");
+  PhyML_Fprintf(fp_stats,"tuneClock\t");
+
+  PhyML_Fprintf(fp_stats,"accTCr\t");
+  PhyML_Fprintf(fp_stats,"tuneTCr\t");
+
+  PhyML_Fprintf(fp_stats,"accTreeRates\t");
+  PhyML_Fprintf(fp_stats,"tuneTreeRates\t");
+
+  PhyML_Fprintf(fp_stats,"accSprW\t");
+  PhyML_Fprintf(fp_stats,"tuneSprW\t");
+
+  PhyML_Fprintf(fp_stats,"accSpr\t");
+  PhyML_Fprintf(fp_stats,"tuneSpr\t");
+
+  PhyML_Fprintf(fp_stats,"accSprLoc\t");
+  PhyML_Fprintf(fp_stats,"tuneSprLoc\t");
+
+  fflush(NULL);
+  
+  for(i=0;i<tree->mcmc->n_moves;i++) tree->mcmc->start_ess[i] = YES;
+  Set_Both_Sides(NO,tree);
+  tree->mcmc->always_yes = NO;
+  move                   = -1;
+  
+  // Get in the range of sensible values for clock_r
+  i = 0;
+  do { MCMC_Clock_R(tree); } while(i++ < 100);
+
+
+  
+  
+  do
+    {
+      if(tree->mcmc->run > adjust_len) for(i=0;i<tree->mcmc->n_moves;i++) 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=0;move<tree->mcmc->n_moves;move++) if(tree->mcmc->move_weight[move] > u-1.E-10) break;
+      
+      assert(!(move == tree->mcmc->n_moves));      
+      
+      if(!strcmp(tree->mcmc->move_name[move],"clock"))                   MCMC_Clock_R(tree);
+      else if(!strcmp(tree->mcmc->move_name[move],"birth_rate"))         MCMC_Birth_Rate(tree);
+      else if(!strcmp(tree->mcmc->move_name[move],"death_rate"))         MCMC_Death_Rate(tree);
+      else if(!strcmp(tree->mcmc->move_name[move],"birth_death_updown")) MCMC_Birth_Death_Updown(tree);
+      else if(!strcmp(tree->mcmc->move_name[move],"tree_height"))        MCMC_Tree_Height(tree);
+      else if(!strcmp(tree->mcmc->move_name[move],"times"))              MCMC_Times_All(tree);
+      else if(!strcmp(tree->mcmc->move_name[move],"times_and_rates"))    MCMC_Times_And_Rates_All(tree);
+      else if(!strcmp(tree->mcmc->move_name[move],"spr"))                MCMC_Prune_Regraft(tree);
+      else if(!strcmp(tree->mcmc->move_name[move],"spr_local"))          MCMC_Prune_Regraft_Local(tree);
+      else if(!strcmp(tree->mcmc->move_name[move],"spr_weighted"))       MCMC_Prune_Regraft_Weighted(tree);
+      else if(!strcmp(tree->mcmc->move_name[move],"updown_t_cr"))        MCMC_Updown_T_Cr(tree);
+      else if(!strcmp(tree->mcmc->move_name[move],"kappa"))              MCMC_Kappa(tree);
+      else if(!strcmp(tree->mcmc->move_name[move],"ras"))                MCMC_Rate_Across_Sites(tree);
+      else if(!strcmp(tree->mcmc->move_name[move],"nu"))                 MCMC_Nu(tree);
+      else if(!strcmp(tree->mcmc->move_name[move],"subtree_height"))     MCMC_Subtree_Height(tree);
+      else if(!strcmp(tree->mcmc->move_name[move],"time_slice"))         MCMC_Time_Slice(tree);
+      else if(!strcmp(tree->mcmc->move_name[move],"br_rate"))            MCMC_Rates_All(tree);
+      else if(!strcmp(tree->mcmc->move_name[move],"tree_rates"))         MCMC_Tree_Rates(tree);
+      else continue;
+      
+      if(!TIMES_Check_Node_Height_Ordering(tree))
+        {
+          PhyML_Printf("\n== move: %s",tree->mcmc->move_name[move]);
+          Exit("\n");
+        }
+      
+      
+      if(!(tree->rates->c_lnL_times > UNLIKELY))
+        {
+          PhyML_Printf("\n== move: %s",tree->mcmc->move_name[move]);
+          PhyML_Printf("\n== glnL=%f",tree->rates->c_lnL_times);
+          Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
+        }
+
+      
+      if(!(tree->mcmc->run%tree->mcmc->print_every))
+        {
+          phydbl mean_r,post;
+
+          mean_r = RATES_Average_Substitution_Rate(tree);
+          post = Get_Lk(tree) + tree->rates->c_lnL_times + tree->rates->c_lnL_rates;
+
+          PhyML_Printf("\n. %10d lnL: [%12.2f -- %12.2f -- %12.2f -- %12.2f] clock: %12f root age: %12f [time: %7d sec run: %8d] mean:%15f %20s",
+                       tree->mcmc->run,
+                       post,
+                       Get_Lk(tree),
+                       tree->rates->c_lnL_times,
+                       tree->rates->c_lnL_rates,
+                       tree->rates->clock_r,
+                       tree->rates->nd_t[tree->n_root->num],                       
+                       (int)time(NULL) - t_beg,
+                       tree->mcmc->run,
+                       mean_r,
+                       tree->mcmc->move_name[move]);
+        }
+      
+      if(!(tree->mcmc->run%tree->mcmc->sample_interval))
+        {
+          phydbl mean_r,post;
+          
+          mean_r = RATES_Average_Substitution_Rate(tree);
+          post = Get_Lk(tree) + tree->rates->c_lnL_times + tree->rates->c_lnL_rates;
+          
+          PhyML_Fprintf(fp_stats,"\n%6d\t%9.1f\t%9.1f\t%9.1f\t%9.1f\t%12G\t%12G\t%12G\t%12G\t%12G\t%12G\t",
+                        tree->mcmc->run,
+                        post,
+                        Get_Lk(tree),
+                        tree->rates->c_lnL_times,
+                        tree->rates->c_lnL_rates,
+                        tree->rates->birth_rate,
+                        tree->rates->death_rate,
+                        mean_r,
+                        tree->rates->nd_t[tree->n_root->num],
+                        tree->next->mod->kappa->v,
+                        tree->rates->nu);
+          
+          for(i=0;i<tree->mod->ras->n_catg;i++) PhyML_Fprintf(fp_stats,"%G\t",tree->mod->ras->gamma_rr->v[i]);
+          for(i=0;i<tree->mod->ras->n_catg;i++) PhyML_Fprintf(fp_stats,"%G\t",tree->mod->ras->gamma_r_proba->v[i]);
+
+
+          for(i=0;i<tree->rates->n_cal;i++) PhyML_Fprintf(fp_stats,"%G\t",tree->rates->nd_t[tree->rates->a_cal[i]->target_nd->num]);
+
+          For(i,2*tree->n_otu-2)
+              PhyML_Fprintf(fp_stats,"%G\t",tree->rates->br_r[i]);
+
+          PhyML_Fprintf(fp_stats,"%G\t",tree->mcmc->acc_rate[tree->mcmc->num_move_times_and_rates_root]);
+          PhyML_Fprintf(fp_stats,"%G\t",tree->mcmc->tune_move[tree->mcmc->num_move_times_and_rates_root]);
+
+          PhyML_Fprintf(fp_stats,"%G\t",tree->mcmc->acc_rate[tree->mcmc->num_move_root_time]);
+          PhyML_Fprintf(fp_stats,"%G\t",tree->mcmc->tune_move[tree->mcmc->num_move_root_time]);
+
+          PhyML_Fprintf(fp_stats,"%G\t",tree->mcmc->acc_rate[tree->mcmc->num_move_clock_r]);
+          PhyML_Fprintf(fp_stats,"%G\t",tree->mcmc->tune_move[tree->mcmc->num_move_clock_r]);
+
+          PhyML_Fprintf(fp_stats,"%G\t",tree->mcmc->acc_rate[tree->mcmc->num_move_updown_t_cr]);
+          PhyML_Fprintf(fp_stats,"%G\t",tree->mcmc->tune_move[tree->mcmc->num_move_updown_t_cr]);
+
+          PhyML_Fprintf(fp_stats,"%G\t",tree->mcmc->acc_rate[tree->mcmc->num_move_tree_rates]);
+          PhyML_Fprintf(fp_stats,"%G\t",tree->mcmc->tune_move[tree->mcmc->num_move_tree_rates]);
+
+          PhyML_Fprintf(fp_stats,"%G\t",tree->mcmc->acc_rate[tree->mcmc->num_move_spr_weighted]);
+          PhyML_Fprintf(fp_stats,"%G\t",tree->mcmc->tune_move[tree->mcmc->num_move_spr_weighted]);
+
+          PhyML_Fprintf(fp_stats,"%G\t",tree->mcmc->acc_rate[tree->mcmc->num_move_spr]);
+          PhyML_Fprintf(fp_stats,"%G\t",tree->mcmc->tune_move[tree->mcmc->num_move_spr]);
+
+          PhyML_Fprintf(fp_stats,"%G\t",tree->mcmc->acc_rate[tree->mcmc->num_move_spr_local]);
+          PhyML_Fprintf(fp_stats,"%G\t",tree->mcmc->tune_move[tree->mcmc->num_move_spr_local]);
+          
+          if(tree->mcmc->sample_num == 0)
+            {
+              PhyML_Fprintf(fp_tree,"\n#NEXUS");
+              PhyML_Fprintf(fp_tree,"\nBegin trees;");
+            }
+          else
+            {
+              fseek(fp_tree,-11,SEEK_CUR);
+            }
+          
+          
+          Time_To_Branch(tree);
+          tree->bl_ndigits = 3;
+          /* RATES_Update_Cur_Bl(tree); */
+          s_tree = Write_Tree(tree,NO);
+          tree->bl_ndigits = 7;
+          PhyML_Fprintf(fp_tree,"\ntree %f [&lnP=-1] = [&R] %s",s_tree,tree->c_lnL);          
+          Free(s_tree);
+          PhyML_Fprintf(fp_tree,"\nEnd trees;");          
+          fflush(NULL);
+          RATES_Update_Cur_Bl(tree);
+
+          tree->mcmc->sample_num++;
+
+        }
+
+      tree->mcmc->run++;
+      MCMC_Get_Acc_Rates(tree->mcmc);
+    }
+  while(tree->mcmc->run < tree->mcmc->chain_len);
+
+
+  return(res);
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+// Update the list of nodes that are younger than lim
+void DATE_List_Of_Nodes_Younger_Than(t_node *a, t_node *d, phydbl lim, t_ll **list, t_tree *tree)
+{
+  if(tree->rates->nd_t[d->num] > lim) Push_Bottom_Linked_List(d,list,YES);
+  
+  if(d->tax == YES) return;
+  else
+    {
+      int i;
+
+      if(d == tree->n_root)
+        {
+          DATE_List_Of_Nodes_Younger_Than(d,d->v[1],lim,list,tree);
+          DATE_List_Of_Nodes_Younger_Than(d,d->v[2],lim,list,tree);
+        }
+      else
+        {
+          for(i=0;i<3;i++)
+            if(d->v[i] != a && d->b[i] != tree->e_root)
+              DATE_List_Of_Nodes_Younger_Than(d,d->v[i],lim,list,tree);            
+        }
+    }
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+// Update the list of nodes that are younger than lim with direct ancestors 
+// not younger than lim
+void DATE_List_Of_Nodes_And_Ancestors_Younger_Than(t_node *a, t_node *d, phydbl lim, t_ll **list, t_tree *tree)
+{
+  if(tree->rates->nd_t[d->num] > lim && a != NULL && tree->rates->nd_t[a->num] > lim) Push_Bottom_Linked_List(d,list,YES);
+  
+  if(d->tax == YES) return;
+  else
+    {
+      int i;
+      
+      if(d == tree->n_root)
+        {
+          DATE_List_Of_Nodes_And_Ancestors_Younger_Than(d,d->v[1],lim,list,tree);
+          DATE_List_Of_Nodes_And_Ancestors_Younger_Than(d,d->v[2],lim,list,tree);
+        }
+      else
+        {      
+          for(i=0;i<3;i++)
+            if(d->v[i] != a && d->b[i] != tree->e_root)
+              DATE_List_Of_Nodes_And_Ancestors_Younger_Than(d,d->v[i],lim,list,tree);            
+        }
+    }
+}
+
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+// List of valid regraft nodes, taking into account calibration
+// constraints. The subtree (defined by prune and prune_daughter
+// will be re-attached *on top of* one of the nodes in this list
+// (as opposed to *on one of the sister edges below*).
+t_ll *DATE_List_Of_Regraft_Nodes(t_node *prune, t_node *prune_daughter, phydbl *t_min, phydbl *t_max, int verbose, t_tree *tree)
+{
+  t_node *n,*m;
+  int i,j;
+  t_ll *out,*in,*ll;
+  int is_clade_affected;
+
+  n = NULL;
+  m = NULL;
+  *t_min = -INFINITY;
+  in = NULL;
+  out = NULL;
+  is_clade_affected = NO;
+
+
+  // Find the oldest LCA of calibrated sets among the nodes between
+  // prune and root. These clades might see the position of their
+  // LCA change.
+
+  if(prune != tree->n_root)
+    {
+      n = prune;
+      while(n)
+        {
+          for(i=0;i<tree->rates->n_cal;i++)
+            {
+              // That node is the LCA of calibration a_cal[i]
+              if(n == tree->rates->a_cal[i]->target_nd)
+                {
+                  is_clade_affected = NO;
+                  For(j,tree->rates->a_cal[i]->n_target_tax)
+                    {
+                      m = tree->rates->a_cal[i]->target_tip[j];
+                      do
+                        {
+                          if(m == prune_daughter)
+                            {
+                              is_clade_affected = YES;
+                              break;
+                            }
+                          m = m->anc;
+                        }
+                      while(m);
+                      
+                      if(is_clade_affected == YES) break;
+                    }
+                  
+                  // Maximum of the lower bounds for calibration intervals
+                  /* if(is_clade_affected == YES) *t_min = MAX(*t_min,tree->rates->a_cal[i]->lower); */
+                  if(is_clade_affected == YES) *t_min = MAX(*t_min,tree->rates->t_prior_min[n->num]);
+                }
+            }
+          n = n->anc;
+        }
+    }
+
+  // Find the oldest internal node within intervals defined by
+  // calibrations affected by the pruning.
+  n = prune_daughter;
+  while(n->anc && !(tree->rates->nd_t[n->anc->num] < *t_min))
+    {
+      n = n->anc;
+      assert(n);
+    }
+  
+
+  if(verbose) printf("\n. Apical: %d @ time %f min: %f",n->num,tree->rates->nd_t[n->num],*t_min); fflush(NULL);
+     
+  // List all nodes younger than this apical node
+  DATE_List_Of_Nodes_Younger_Than(n->anc,n,-INFINITY,&in,tree);
+
+  assert(in != NULL);
+  
+  if(verbose)
+    {
+      ll = in->head;
+      t_node *x;
+      do
+        {
+          x = (t_node *)ll->v;
+          PhyML_Printf("\nx Inlist %d @ %f",x->num,tree->rates->nd_t[x->num]);
+          ll = ll->next;
+        }
+      while(ll != NULL);
+    }
+  
+  // Remove from that list the nodes that are too young to be suitable regraft points.
+  /* n = prune_daughter; */
+  /* out = NULL; */
+  /* while(n) */
+  /*   { */
+  /*     for(i=0;i<tree->rates->n_cal;i++) */
+  /*       { */
+  /*         if(n->anc && n->anc == tree->rates->a_cal[i]->target_nd) */
+  /*           { */
+  /*             For(j,tree->rates->a_cal[i]->n_target_tax) */
+  /*               { */
+  /*                 m = tree->rates->a_cal[i]->target_tip[j]; */
+  /*                 do */
+  /*                   { */
+  /*                     if(m == prune_daughter) break;                       */
+  /*                     if(m == prune) break; */
+  /*                     m = m->anc; */
+  /*                   } */
+  /*                 while(m); */
+  /*                 if(m == prune) break; // Prune-regraft anywhere below calibrated node will not change that node. */
+  /*               } */
+              
+  /*             if(m != prune) */
+  /*               { */
+  /*                 for(j=0;j<3;j++) */
+  /*                   { */
+  /*                     if(n->anc->v[j] != n->anc->anc && n->anc->b[j] != tree->e_root && n->anc->v[j] != n) */
+  /*                       { */
+  /*                         DATE_List_Of_Nodes_And_Ancestors_Younger_Than(n->anc, */
+  /*                                                                       n->anc->v[j], */
+  /*                                                                       tree->rates->a_cal[i]->upper, */
+  /*                                                                       &out, */
+  /*                                                                       tree); */
+  /*                         break; */
+  /*                       } */
+  /*                   } */
+  /*               } */
+  /*           } */
+  /*       } */
+  /*     n = n->anc; */
+  /*   } */
+
+  // Remove nodes that are `strictly' younger than prune_daughter
+  DATE_List_Of_Nodes_And_Ancestors_Younger_Than(tree->n_root,tree->n_root->v[1],tree->rates->nd_t[prune_daughter->num],&out,tree);
+  DATE_List_Of_Nodes_And_Ancestors_Younger_Than(tree->n_root,tree->n_root->v[2],tree->rates->nd_t[prune_daughter->num],&out,tree);
+
+  // Remove nodes that are below prune_daughter (prune_daughter included)
+  DATE_List_Of_Nodes_Younger_Than(prune,prune_daughter,-INFINITY,&out,tree);
+
+  // Add prune node to the list of node that can't be targeted for regraft
+  Push_Bottom_Linked_List(prune,&out,YES);
+
+  // Add root node as one cannot regraft above it
+  /* Push_Bottom_Linked_List(tree->n_root,&out); */
+
+  if(verbose)
+    {
+      printf("\nx outlist: %p",(void *)out); fflush(NULL);
+      ll = out->head;
+      do
+        {
+          t_node *x = (t_node *)ll->v;
+          PhyML_Printf("\nx Outlist %d @ %f",x->num,tree->rates->nd_t[x->num]);
+          ll = ll->next;
+        }
+      while(ll != NULL);
+    }
+  
+
+  /* Print_List(in); */
+  ll = out->head;
+  do
+    {
+      if(verbose)
+        {
+          t_node *x = (t_node *)ll->v;
+          printf("\nx Remove %d",x->num);
+        }
+
+      Remove_From_Linked_List(NULL,ll->v,&in);
+
+      if(verbose) PhyML_Printf("\n. List in (in->head:%p in->tail:%p):",in?in->head:NULL,in?in->tail:NULL);
+
+      /* Print_List(in); */
+      ll = ll->next;
+    }
+  while(ll != NULL);
+  
+  Free_Linked_List(out);
+
+  if(verbose)
+    {
+      ll = in->head;
+      do
+        {
+          t_node *x;
+          x = (t_node *)ll->v;
+          printf("\n. In1: %d",x->num); fflush(NULL);
+          ll = ll->next;
+        }
+      while(ll != NULL);
+    }
+  
+  return(in);
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
diff --git a/src/date.h b/src/date.h
new file mode 100644
index 0000000..f9f8fc3
--- /dev/null
+++ b/src/date.h
@@ -0,0 +1,44 @@
+/*
+
+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);
+void DATE_List_Of_Nodes_Younger_Than(t_node *a, t_node *d, phydbl lim, t_ll **list, t_tree *tree);
+void DATE_List_Of_Nodes_And_Ancestors_Younger_Than(t_node *a, t_node *d, phydbl lim, t_ll **list, t_tree *tree);
+t_ll *DATE_List_Of_Regraft_Nodes(t_node *prune, t_node *prune_daughter, phydbl *t_min, phydbl *t_max, int verbose, t_tree *tree);
+
+
+
+
+#endif
diff --git a/src/draw.c b/src/draw.c
index 862e8ac..0f3cb1f 100644
--- a/src/draw.c
+++ b/src/draw.c
@@ -1,7 +1,7 @@
 /*
 
-PHYML :  a program that  computes maximum likelihood  phyLOGenies from
-DNA or AA homoLOGous sequences
+PHYML :  a program that  computes maximum likelihood  phylogenies from
+DNA or AA homologous sequences
 
 Copyright (C) Stephane Guindon. Oct 2003 onward
 
@@ -339,7 +339,7 @@ void DR_Print_Tree_Postscript_Pre(t_node *a, t_node *d, t_edge *b, int render_na
       PhyML_Fprintf(fp,"stroke\n");
       PhyML_Fprintf(fp,"gr\n");
       PhyML_Fprintf(fp,"0 0 0 sc\n");
-      For(i,3)
+      for(i=0;i<3;i++)
 	if(d->v[i] != a && d->b[i] != tree->e_root) DR_Print_Tree_Postscript_Pre(d,d->v[i],d->b[i],render_name,fp,w,tree);
     }
 
@@ -362,7 +362,7 @@ void DR_Get_X_Coord_Pre(t_node *a, t_node *d, t_edge *b, tdraw *w, int fixed_tip
   if(d->tax) return;
   else
     {
-      For(i,3)
+      for(i=0;i<3;i++)
 	if((d->v[i] != a) && (d->b[i] != tree->e_root)) 
 	  DR_Get_X_Coord_Pre(d,d->v[i],d->b[i],w,fixed_tips,tree);
     }
@@ -418,7 +418,7 @@ void DR_Get_Y_Coord_Post(t_node *a, t_node *d, t_edge *b, int *next_y_slot, int
       int d1, d2;
 
       d1 = d2 = -1;
-      For(i,3)
+      for(i=0;i<3;i++)
 	{
 	  if(d->v[i] != a && d->b[i] != tree->e_root)
 	    {
@@ -471,7 +471,7 @@ void DR_Get_Tree_Box_Width(tdraw *w, t_tree *tree)
   int max_name_len, curr_len;
 
   max_name_len = curr_len = 0;
-  For(i,tree->n_otu)
+  for(i=0;i<tree->n_otu;i++)
     {
       curr_len = (int)strlen(tree->a_nodes[i]->name);
       if(curr_len > max_name_len) max_name_len = curr_len;
@@ -491,7 +491,7 @@ phydbl DR_Get_Max_Dist_To_Root(t_tree *tree)
   int i;
 
   mx = .0;
-  For(i,tree->n_otu)
+  for(i=0;i<tree->n_otu;i++)
     {
       if(tree->a_nodes[i]->dist_to_root > mx)
 	{
diff --git a/src/eigen.c b/src/eigen.c
index 5329f3b..6e439d4 100644
--- a/src/eigen.c
+++ b/src/eigen.c
@@ -3,9 +3,9 @@
 *         for real general square matrix A
 *         A will be destroyed
 *         rr,ri are vectors containing eigenvalues
-*         vr,vi are matrices containing (right) eigenvectors
+*         vr,vi are matrices containing (right) real and imaginary eigenvectors
 *
-*              A*[vr+vi*i] = [vr+vi*i] * diag{rr+ri*i}
+*              A * [vr+vi*i] = [vr+vi*i] * diag{rr+ri*i}
 *
 *  Algorithm: Handbook for Automatic Computation, vol 2
 *             by Wilkinson and Reinsch, 1971
@@ -51,25 +51,42 @@ int Eigen(int job, phydbl *A, int n, phydbl *rr, phydbl *ri,
     phydbl tiny, t; 
 
 /*     tiny=SQRT(POW((phydbl)BASE,(phydbl)(1-(int)DIGITS))); */
-    tiny=FLT_MIN;
+    /* tiny=FLT_MIN; */
+    tiny = SMALL;
 
+    
     balance(A,n,&low,&hi,work);
     elemhess(job,A,n,low,hi,vr,vi, (int*)(work+n));
     if (-1 == realeig(job,A,n,low,hi,rr,ri,vr,vi)) return (-1);
     if (job) unbalance(n,vr,vi,low,hi,work);
-
+    
 /* sort, added by Z. Yang */
-   for (i=0; i<n; i++) {
-       for (j=i+1,it=i,t=rr[i]; j<n; j++)
-           if (t<rr[j]) { t=rr[j]; it=j; }
-       rr[it]=rr[i];   rr[i]=t;
-       t=ri[it];       ri[it]=ri[i];  ri[i]=t;
-       for (k=0; k<n; k++) {
-          t=vr[k*n+it];  vr[k*n+it]=vr[k*n+i];  vr[k*n+i]=t;
-          t=vi[k*n+it];  vi[k*n+it]=vi[k*n+i];  vi[k*n+i]=t;
-       }
+   for (i=0; i<n; ++i)
+     {
+       for (j=i+1,it=i,t=rr[i]; j<n; ++j)
+         if (t<rr[j])
+           {
+             t=rr[j];
+             it=j;
+           }
+       rr[it]=rr[i];
+       rr[i]=t;
+       t=ri[it];
+       ri[it]=ri[i];
+       ri[i]=t;
+
+       for (k=0; k<n; ++k)
+         {
+           t=vr[k*n+it];
+           vr[k*n+it]=vr[k*n+i];
+           vr[k*n+i]=t;
+
+           t=vi[k*n+it];
+           vi[k*n+it]=vi[k*n+i];
+           vi[k*n+i]=t;
+         }
        if (FABS(ri[i])>tiny) istate=1;
-   }
+     }
 
     return (istate) ;
 }
@@ -140,7 +157,7 @@ complex cdiv (complex a,complex b)
 /* complex local_cexp (complex a) */
 /* { */
 /*    complex c; */
-/*    c.re = EXP(a.re); */
+/*    c.re = exp(a.re); */
 /*    if (FABS(a.im)==0) c.im = 0;  */
 /*    else  { c.im = c.re*sin(a.im); c.re*=cos(a.im); } */
 /*    return (c); */
@@ -168,7 +185,7 @@ int cmatby (complex *a, complex *b, complex *c, int n,int m,int k)
    int i,j,i1;
    complex t;
 
-   For (i,n)  For(j,k) {
+   For (i,n)  for(j=0;j<k;j++) {
        for (i1=0,t=compl(0,0); i1<m; i1++)  
            t = cplus (t, cby(a[i*m+i1],b[i1*k+j]));
        c[i*k+j] = t;
@@ -184,7 +201,7 @@ int cmatinv( complex *x, int n, int m, phydbl *space)
    phydbl xmaxsize, ee=1e-20;
    complex t,t1;
 
-   For(i,n)  {
+   for(i=0;i<n;i++)  {
        xmaxsize = 0.;
        for (j=i; j<n; j++) {
           if ( xmaxsize < csize (x[j*m+i]))  {
@@ -197,25 +214,25 @@ int cmatinv( complex *x, int n, int m, phydbl *space)
            return(-1);
        }
        if (irow[i] != i) {
-           For(j,m) {
+           for(j=0;j<m;j++) {
                 t = x[i*m+j];
                 x[i*m+j] = x[irow[i]*m+j];
                 x[ irow[i]*m+j] = t;
            }
        }
        t = cdiv (compl(1,0), x[i*m+i]);
-       For(j,n) {
+       for(j=0;j<n;j++) {
            if (j == i) continue;
            t1 = cby (t,x[j*m+i]);
-           For(k,m)  x[j*m+k] = cminus (x[j*m+k], cby(t1,x[i*m+k]));
+           for(k=0;k<m;k++)  x[j*m+k] = cminus (x[j*m+k], cby(t1,x[i*m+k]));
            x[j*m+i] = cfactor (t1, -1);
        }
-       For(j,m)   x[i*m+j] = cby (x[i*m+j], t);
+       for(j=0;j<m;j++)   x[i*m+j] = cby (x[i*m+j], t);
        x[i*m+i] = t;
    }                         
    for (i=n-1; i>=0; i--) {
         if (irow[i] == i) continue;
-        For(j,n)  {
+        for(j=0;j<n;j++)  {
            t = x[j*m+i];
            x[j*m+i] = x[j*m+irow[i]];
            x[ j*m+irow[i]] = t;
@@ -312,7 +329,8 @@ void balance(phydbl *mat, int n,int *low, int *hi, phydbl *scale)
             }
 
 /*             if (c != 0 && r != 0) {  */
-            if (FABS(c) > SMALL && FABS(r) > SMALL) {
+            if ((FABS(c) > SMALL || FABS(c) < -SMALL) && (FABS(r) > SMALL || FABS(r) < -SMALL))
+              {
                g = r / BASE;
                 f = 1;
                 s = c + r;
@@ -861,7 +879,7 @@ void det(phydbl **a, int n, phydbl *d)
 {
   int j;
   ludcmp(a,n,d);
-  For(j,n) *d *= a[j][j];
+  for(j=0;j<n;j++) *d *= a[j][j];
 }
 
 
@@ -929,7 +947,7 @@ void det_1D(phydbl *a, int n, phydbl *d)
 {
   int j;
   ludcmp_1D(a,n,d);
-  For(j,n) *d *= a[j*n+j];
+  for(j=0;j<n;j++) *d *= a[j*n+j];
 }
 
 /* Find L such that L.L' = A */
@@ -941,7 +959,7 @@ phydbl *Cholesky_Decomp(phydbl *A,  int dim)
 
   L = (phydbl *)mCalloc(dim*dim,sizeof(phydbl));
 
-  For(i,dim)
+  for(i=0;i<dim;i++)
     {
       for(j=i;j<dim;j++)
 	{
diff --git a/src/free.c b/src/free.c
index 10ef233..37f1cc2 100644
--- a/src/free.c
+++ b/src/free.c
@@ -1,6 +1,6 @@
 /*
 
-PHYML :  a program that  computes maximum likelihood  phyLOGenies from
+PHYML :  a program that  computes maximum likelihood  phylogenies from
 DNA or AA homologous sequences
 
 Copyright (C) Stephane Guindon. Oct 2003 onward
@@ -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);
@@ -125,7 +127,7 @@ void Free_Mat(matrix *mat)
 {
   int i;
 
-  For(i,mat->n_otu)
+  for(i=0;i<mat->n_otu;i++)
     {
       Free(mat->P[i]);
       Free(mat->Q[i]);
@@ -152,9 +154,9 @@ void Free_Partial_Lk(phydbl *p_lk, int len, int n_catg)
   Free(p_lk);
 
 /*   int i,j; */
-/*   For(i,len) */
+/*   for(i=0;i<len;i++) */
 /*     { */
-/*       For(j,n_catg) Free((*p_lk)[i][j]); */
+/*       for(j=0;j<n_catg;j++) Free((*p_lk)[i][j]); */
 /*       Free((*p_lk)[i]); */
 /*     } */
 /*   Free((*p_lk)); */
@@ -212,7 +214,7 @@ void Free_Bip(t_tree *tree)
       For(i,2*tree->n_otu-2)
     {
       Free(tree->a_nodes[i]->bip_size);
-      For(j,3) Free(tree->a_nodes[i]->bip_node[j]);
+      for(j=0;j<3;j++) Free(tree->a_nodes[i]->bip_node[j]);
       Free(tree->a_nodes[i]->bip_node);
     }
     }
@@ -222,16 +224,17 @@ 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);
   Free(data->b_frq);
   Free(data->sitepatt);
-  For(i,data->n_otu)
+  for(i=0;i<data->n_otu;i++)
     {
       Free(data->c_seq[i]->name);
       if(data->c_seq[i]->state)
@@ -252,7 +255,7 @@ void Free_Cseq(calign *data)
 void Free_Seq(align **d, int n_otu)
 {
   int i;
-  For(i,n_otu)
+  for(i=0;i<n_otu;i++)
     {
       Free(d[i]->name);
       Free(d[i]->state);
@@ -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);
 }
@@ -285,7 +288,7 @@ void Free_SubTree(t_edge *b_fcus, t_node *a, t_node *d, t_tree *tree)
   if(d->tax) return;
   else
     {
-      For(i,3)
+      for(i=0;i<3;i++)
     {
       if(d->v[i] != a)
         {
@@ -318,20 +321,16 @@ void Free_Tree_Pars(t_tree *mixt_tree)
     {
       Free(tree->step_mat);
       Free(tree->site_pars);
-
+      
       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
         {
@@ -378,7 +377,6 @@ void Free_Edge_Pars(t_edge *b)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Free_Tree_Lk(t_tree *mixt_tree)
 {
   int i;
@@ -392,31 +390,45 @@ void Free_Tree_Lk(t_tree *mixt_tree)
       Free(tree->old_site_lk);
       Free(tree->site_lk_cat);
       Free(tree->fact_sum_scale);
-
-      For(i,3) Free(tree->log_lks_aLRT[i]);
+      Free(tree->eigen_lr_left);
+      Free(tree->eigen_lr_rght);
+      Free(tree->dot_prod);
+      Free(tree->expl);
+      
+      for(i=0;i<3;i++) Free(tree->log_lks_aLRT[i]);
       Free(tree->log_lks_aLRT);
 
       Free(tree->unscaled_site_lk_cat);
-
-      For(i,2*tree->n_otu-3) Free_Edge_Lk(tree->a_edges[i]);
-
-      if(tree->n_root)
-        {
-          Free(tree->n_root->b[1]->nni);
-          Free(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]); */
-        }
-      else
+      
+      For(i,2*tree->n_otu-1) Free_NNI(tree->a_edges[i]->nni);
+  
+      if(tree->is_mixt_tree == NO)
         {
-          Free_Edge_Lk(tree->a_edges[2*tree->n_otu-3]);
-          Free_Edge_Lk(tree->a_edges[2*tree->n_otu-2]);
+          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 != NULL)
+            {
+              Free(tree->n_root->b[1]->Pij_rr);
+              Free(tree->n_root->b[2]->Pij_rr);
+              Free(tree->n_root->b[1]->tPij_rr);
+              Free(tree->n_root->b[2]->tPij_rr);
+              Free_Edge_Lk_Left(tree->n_root->b[1]);
+              Free_Edge_Lk_Left(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 +456,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 +475,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 +485,7 @@ void Free_Edge_Lk_Left(t_edge *b)
 
 void Free_Edge_Lk(t_edge *b)
 {
-  Free(b->nni);
+  Free(b->tPij_rr);
   Free(b->Pij_rr);
   Free_Edge_Lk_Left(b);
   Free_Edge_Lk_Rght(b);
@@ -488,6 +494,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 +532,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 +615,29 @@ void Free_Vect_Dbl(vect_dbl *v)
 {
   vect_dbl *next;
 
+  assert(v);
+
+  next = v->next;
+  do
+    {
+      Free(v->v);
+      Free(v);
+
+      v = next;
+      if(v) next = v->next;
+    }
+  while(v);
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void Free_Vect_Int(vect_int *v)
+{
+  vect_int *next;
+
+  assert(v);
+
   next = v->next;
   do
     {
@@ -561,6 +656,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 +672,50 @@ void Free_Scalar_Dbl(scalar_dbl *v)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
+void Free_Scalar_Int(scalar_int *v)
+{
+  scalar_int *next;
+  
+  assert(v);
+
+  next = v->next;
+  do
+    {
+      Free(v);
+      v = next;
+      if(v) next = v->next;
+    }
+  while(v);
+}
+
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void Free_Linked_List(t_ll *t)
+{
+  t_ll *next,*ll;
+
+  if(t == NULL) return;
+
+  ll = t->head;
+  next = ll->next;
+  do
+    {
+      /* t_node *n = ll->v; */
+      /* printf("\n. free node %d",n?n->num:-1); */
+      /* printf(" ll: %p",ll); */
+      /* printf(" hd: %p",ll?ll->head:NULL); fflush(NULL); */
+      Free(ll);
+      ll = next;
+      if(ll) next = ll->next;
+    }
+  while(ll);
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
 void Free_String(t_string *ts)
 {
   t_string *next;
@@ -609,6 +750,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);
@@ -691,7 +835,16 @@ void Free_Model(t_mod *mod)
 
 void Free(void *p)
 {
+#if (defined(__AVX__) || defined(__SSE3__))
+#ifndef WIN32
   free(p);
+#else
+  _aligned_free(p);
+#endif
+#else  
+  free(p);
+#endif
+
   p = NULL;
 }
 
@@ -717,19 +870,21 @@ 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);
       Free(io->clade_list_file);
-      For(i,T_MAX_ALPHABET) Free(io->alphabet[i]);
+      for(i=0;i<T_MAX_ALPHABET;i++) Free(io->alphabet[i]);
       Free(io->alphabet);
       if(io->short_tax_names)
         {
-          For(i,io->size_tax_names)
+          for(i=0;i<io->size_tax_names;i++)
             {
               Free(io->short_tax_names[i]);
               Free(io->long_tax_names[i]);
@@ -774,9 +929,9 @@ 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]);
+  for(i=0;i<st->n_part;i++) Free(st->match_st_node_in_gt[i]);
 
   Free(st->match_st_node_in_gt);
 
@@ -812,7 +967,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);  
 }
 
 //////////////////////////////////////////////////////////////
@@ -849,27 +1014,27 @@ void Free_Triplet(triplet *t)
   Free(t->pi_cd);
   Free(t->pi_bd);
 
-  For(k,t->mod->ras->n_catg)
+  for(k=0;k<t->mod->ras->n_catg;k++)
     {
-      For(i,t->size)
+      for(i=0;i<t->size;i++)
     {
-      For(j,t->size) Free(t->core[k][i][j]);
+      for(j=0;j<t->size;j++) Free(t->core[k][i][j]);
       Free(t->core[k][i]);
     }
       Free(t->core[k]);
     }
   Free(t->core);
 
-  For(i,t->size)
+  for(i=0;i<t->size;i++)
     {
-      For(j,t->size) Free(t->p_one_site[i][j]);
+      for(j=0;j<t->size;j++) Free(t->p_one_site[i][j]);
       Free(t->p_one_site[i]);
     }
   Free(t->p_one_site);
 
-  For(i,t->size)
+  for(i=0;i<t->size;i++)
     {
-      For(j,t->size) Free(t->sum_p_one_site[i][j]);
+      for(j=0;j<t->size;j++) Free(t->sum_p_one_site[i][j]);
       Free(t->sum_p_one_site[i]);
     }
   Free(t->sum_p_one_site);
@@ -888,7 +1053,7 @@ void Free_Triplet(triplet *t)
 void Free_Actual_CSeq(calign *data)
 {
   int i;
-  For(i,data->n_otu)
+  for(i=0;i<data->n_otu;i++)
     {
       Free(data->c_seq[i]->state);
       Free(data->c_seq[i]->d_state);
@@ -904,7 +1069,7 @@ void Free_Prefix_Tree(pnode *n, int size)
 {
   int i;
 
-  For(i,size)
+  for(i=0;i<size;i++)
     {
       if(n->next[i])
     {
@@ -939,7 +1104,7 @@ void Free_Nexus(option *io)
 {
   int i,j;
 
-  For(i,N_MAX_NEX_COM)
+  for(i=0;i<N_MAX_NEX_COM;i++)
     {
       For(j,io->nex_com_list[i]->nparm) Free_Nexus_Parm(io->nex_com_list[i]->parm[j]);
       Free(io->nex_com_list[i]->parm);
@@ -957,7 +1122,7 @@ void Free_Nexus_Com(nexcom **com)
 {
   int i;
 
-  For(i,N_MAX_NEX_COM)
+  for(i=0;i<N_MAX_NEX_COM;i++)
     {
       Free(com[i]->parm);
       Free(com[i]->name);
@@ -981,6 +1146,7 @@ void Free_Nexus_Parm(nexparm *parm)
 
 void XML_Free_XML_Tree(xml_node *node)
 {
+  if(!node) return;
   if(node->child) XML_Free_XML_Tree(node->child);
   if(node->next)  XML_Free_XML_Tree(node->next);
   XML_Free_XML_Node(node);
@@ -1042,7 +1208,7 @@ void MCMC_Free_MCMC(t_mcmc *mcmc)
   Free(mcmc->prev_run_move);
   Free(mcmc->acc_rate);
   Free(mcmc->tune_move);
-  For(i,mcmc->n_moves) Free(mcmc->move_name[i]);
+  for(i=0;i<mcmc->n_moves;i++) Free(mcmc->move_name[i]);
   Free(mcmc->move_name);
   Free(mcmc->ess_run);
   Free(mcmc->start_ess);
@@ -1065,7 +1231,7 @@ void M4_Free_M4_Model(m4 *m4mod)
 
   if(m4mod->o_mats)
     {
-      For(i,m4mod->n_h) Free(m4mod->o_mats[i]);
+      for(i=0;i<m4mod->n_h;i++) Free(m4mod->o_mats[i]);
       Free(m4mod->o_mats);
       Free(m4mod->h_mat);
       Free(m4mod->o_rr);
@@ -1087,6 +1253,7 @@ 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);
@@ -1139,14 +1306,13 @@ void RATES_Free_Rates(t_rate *rates)
       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=0;i<rates->n_cal;i++) Free_Calib(rates->a_cal[i]);
+      Free(rates->a_cal);
     }
-  Free_Calib(rates->calib);
   Free(rates);
 }
 
@@ -1156,8 +1322,18 @@ void RATES_Free_Rates(t_rate *rates)
 void Free_Calib(t_cal *cal)
 {
   if(!cal) return;
-  else Free_Calib(cal->next);
-  Free(cal);
+  else 
+    {    
+      if(cal->target_tax != NULL)
+        {
+          int i;
+          for(i=0;i<cal->n_target_tax;i++) Free(cal->target_tax[i]);
+          Free(cal->target_tax);
+          Free(cal->target_tip);
+        }
+      Free(cal->clade_id);
+      Free(cal);
+    }
 }
 
 /*////////////////////////////////////////////////////////////
@@ -1173,7 +1349,7 @@ void Free_Geo(t_geo *t)
   Free(t->sorted_nd);
   Free(t->cov);
   Free(t->idx_loc_beneath);
-  For(i,t->ldscape_sz) Free_Geo_Coord(t->coord_loc[i]);
+  for(i=0;i<t->ldscape_sz;i++) Free_Geo_Coord(t->coord_loc[i]);
   Free(t->coord_loc);
   Free(t);
 }
@@ -1213,8 +1389,6 @@ void Free_Ldisk(t_ldsk *t)
     {
       Free(t->next);
       Free_Geo_Coord(t->coord);
-      /* if(t->min_coord) Free_Geo_Coord(t->min_coord); */
-      /* if(t->max_coord) Free_Geo_Coord(t->max_coord); */
       if(t->cpy_coord) Free_Geo_Coord(t->cpy_coord);
       Free(t);
     }
@@ -1227,7 +1401,7 @@ void Free_Ldisk(t_ldsk *t)
 void Free_Poly(t_poly *p)
 {
   int i;
-  For(i,p->n_poly_vert) Free_Geo_Coord(p->poly_vert[i]);
+  for(i=0;i<p->n_poly_vert;i++) Free_Geo_Coord(p->poly_vert[i]);
   Free(p->poly_vert);
   Free(p);
 }
@@ -1237,13 +1411,65 @@ void Free_Poly(t_poly *p)
 
 void Free_Mmod(t_phyrex_mod *mmod)
 {
+  if(mmod == NULL) return;
   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..4b13f96 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);
@@ -66,7 +66,9 @@ void XML_Free_XML_Attr(xml_attr *attr);
 void XML_Free_XML_Ds(t_ds *ds);
 void Free_String(t_string *ts);
 void Free_Vect_Dbl(vect_dbl *v);
+void Free_Vect_Int(vect_int *v);
 void Free_Scalar_Dbl(scalar_dbl *v);
+void Free_Scalar_Int(scalar_int *v);
 void Free_Edge_Core(t_edge *b);
 void M4_Free_M4_Model(m4 *m4mod);
 void RATES_Free_Rates(t_rate *rates);
@@ -79,5 +81,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/geo.c b/src/geo.c
index 8d554c8..6380e9b 100644
--- a/src/geo.c
+++ b/src/geo.c
@@ -70,7 +70,7 @@ int GEO_Estimate(int argc, char **argv)
     
   
   j = 0;
-  For(i,t->ldscape_sz) 
+  for(i=0;i<t->ldscape_sz;i++) 
     {
       t->coord_loc[i]->lonlat[0] = ldscp[j];
       t->coord_loc[i]->lonlat[1] = ldscp[j+1];      
@@ -78,7 +78,7 @@ int GEO_Estimate(int argc, char **argv)
       j+=2;
     }
 
-  For(i,tree->n_otu) t->idx_loc[i] = loc_hash[i];
+  for(i=0;i<tree->n_otu;i++) t->idx_loc[i] = loc_hash[i];
 
   t->cov[0*t->n_dim+0] = t->sigma;
   t->cov[1*t->n_dim+1] = t->sigma;
@@ -96,8 +96,8 @@ int GEO_Estimate(int argc, char **argv)
   probs = (phydbl *)mCalloc(tree->geo->ldscape_sz,sizeof(phydbl));
   
   sum = 0.0;
-  For(i,tree->geo->ldscape_sz) sum += tree->geo->idx_loc_beneath[tree->n_root->num * tree->geo->ldscape_sz + i];
-  For(i,tree->geo->ldscape_sz) probs[i] = tree->geo->idx_loc_beneath[tree->n_root->num * tree->geo->ldscape_sz + i]/sum;
+  for(i=0;i<tree->geo->ldscape_sz;i++) sum += tree->geo->idx_loc_beneath[tree->n_root->num * tree->geo->ldscape_sz + i];
+  for(i=0;i<tree->geo->ldscape_sz;i++) probs[i] = tree->geo->idx_loc_beneath[tree->n_root->num * tree->geo->ldscape_sz + i]/sum;
   tree->geo->idx_loc[tree->n_root->num] = Sample_i_With_Proba_pi(probs,tree->geo->ldscape_sz);        
   Free(probs);
 
@@ -181,7 +181,7 @@ int GEO_Simulate_Estimate(int argc, char **argv)
   PhyML_Printf("\n. sigma max: %f threshold: %f",t->max_sigma,t->sigma_thresh);
   
   /* t->tau   = Uni()*(t->max_tau/100.-t->min_tau*10.)  + t->min_tau*10.; */
-  /* t->lbda  = EXP(Uni()*(LOG(t->max_lbda/100.)-LOG(t->min_lbda*10.))  + LOG(t->min_lbda*10.)); */
+  /* t->lbda  = exp(Uni()*(log(t->max_lbda/100.)-log(t->min_lbda*10.))  + log(t->min_lbda*10.)); */
   /* t->sigma = Uni()*(t->max_sigma-t->min_sigma) + t->min_sigma; */
 
   t->lbda  = 1.;
@@ -211,7 +211,7 @@ int GEO_Simulate_Estimate(int argc, char **argv)
   PhyML_Printf("\n. rf: %f",rf);
   
   phydbl scale;
-  scale = EXP(Rnorm(0,0.2));
+  scale = exp(Rnorm(0,0.2));
   PhyML_Printf("\n. Scale: %f",scale);
   For(i,2*tree->n_otu-1) tree->rates->nd_t[i] *= scale;
   
@@ -224,9 +224,9 @@ int GEO_Simulate_Estimate(int argc, char **argv)
   
   geo_dist = (phydbl *)mCalloc(tree->n_otu*tree->n_otu,sizeof(phydbl));
 
-  For(i,tree->n_otu)
+  for(i=0;i<tree->n_otu;i++)
     {
-      For(j,tree->n_otu)
+      for(j=0;j<tree->n_otu;j++)
         {
           /* geo_dist[i*tree->n_otu+j] = */
           /*   FABS(t->ldscape[t->idx_loc[i]*t->n_dim+0] - */
@@ -280,8 +280,8 @@ int GEO_Simulate_Estimate(int argc, char **argv)
   probs = (phydbl *)mCalloc(tree->geo->ldscape_sz,sizeof(phydbl));
   
   sum = 0.0;
-  For(i,tree->geo->ldscape_sz) sum += tree->geo->idx_loc_beneath[tree->n_root->num * tree->geo->ldscape_sz + i];
-  For(i,tree->geo->ldscape_sz) probs[i] = tree->geo->idx_loc_beneath[tree->n_root->num * tree->geo->ldscape_sz + i]/sum;
+  for(i=0;i<tree->geo->ldscape_sz;i++) sum += tree->geo->idx_loc_beneath[tree->n_root->num * tree->geo->ldscape_sz + i];
+  for(i=0;i<tree->geo->ldscape_sz;i++) probs[i] = tree->geo->idx_loc_beneath[tree->n_root->num * tree->geo->ldscape_sz + i]/sum;
   tree->geo->idx_loc[tree->n_root->num] = Sample_i_With_Proba_pi(probs,tree->geo->ldscape_sz);
   Free(probs);
   GEO_Randomize_Locations(tree->n_root,tree->geo,tree);
@@ -356,7 +356,6 @@ phydbl *GEO_MCMC(t_tree *tree)
 
   tree->mcmc->io               = NULL;
   tree->mcmc->is               = NO;
-  tree->mcmc->use_data         = YES;
   tree->mcmc->run              = 0;
   tree->mcmc->sample_interval  = 1E+3;
   tree->mcmc->chain_len        = 1E+6;
@@ -517,9 +516,9 @@ void GEO_Update_Fmat(t_geo *t)
   int err;
   phydbl lognloc;
   
-  For(i,t->n_dim) t->cov[i*t->n_dim+i] = t->sigma; // Diagonal covariance matrix. Same variance in every direction
+  for(i=0;i<t->n_dim;i++) t->cov[i*t->n_dim+i] = t->sigma; // Diagonal covariance matrix. Same variance in every direction
 
-  lognloc = LOG(t->ldscape_sz);
+  lognloc = log(t->ldscape_sz);
 
   // Fill in F matrix;
   for(i=0;i<t->ldscape_sz;i++)
@@ -533,12 +532,12 @@ void GEO_Update_Fmat(t_geo *t)
           t->f_mat[i*t->ldscape_sz+j] = .0;
 
           // Calculate log(f(l_i,l_j)) - log(f(l_i,l_i) - log(m) 
-          For(k,t->n_dim) t->f_mat[i*t->ldscape_sz+j] += Log_Dnorm(loc2[k],loc1[k],t->cov[k*t->n_dim+k],&err);
+          for(k=0;k<t->n_dim;k++) t->f_mat[i*t->ldscape_sz+j] += Log_Dnorm(loc2[k],loc1[k],t->cov[k*t->n_dim+k],&err);
           t->f_mat[i*t->ldscape_sz+j] -= lognloc;
-          For(k,t->n_dim) t->f_mat[i*t->ldscape_sz+j] -= Log_Dnorm(loc1[k],loc1[k],t->cov[k*t->n_dim+k],&err);
+          for(k=0;k<t->n_dim;k++) t->f_mat[i*t->ldscape_sz+j] -= Log_Dnorm(loc1[k],loc1[k],t->cov[k*t->n_dim+k],&err);
 
           // Take the exponential
-          t->f_mat[i*t->ldscape_sz+j] = EXP(t->f_mat[i*t->ldscape_sz+j]);
+          t->f_mat[i*t->ldscape_sz+j] = exp(t->f_mat[i*t->ldscape_sz+j]);
           
           // Matrix is symmetric
           t->f_mat[j*t->ldscape_sz+i] = t->f_mat[i*t->ldscape_sz+j];
@@ -598,7 +597,7 @@ void GEO_Update_Occup(t_geo *t, t_tree *tree)
   
   for(i=1;i<2*tree->n_otu-1;i++)
     {
-      For(j,t->ldscape_sz) 
+      for(j=0;j<t->ldscape_sz;j++) 
         {
           t->occup[t->sorted_nd[i]->num*t->ldscape_sz + j] = 
             t->occup[t->sorted_nd[i-1]->num*t->ldscape_sz + j];
@@ -615,7 +614,7 @@ void GEO_Update_Occup(t_geo *t, t_tree *tree)
             }
           else
             {
-              For(j,3)
+              for(j=0;j<3;j++)
                 {
                   if(t->sorted_nd[i-1]->v[j] != t->sorted_nd[i-1]->anc &&
                      t->sorted_nd[i-1]->b[j] != tree->e_root)
@@ -642,7 +641,7 @@ void GEO_Update_Occup(t_geo *t, t_tree *tree)
   /* For(i,2*tree->n_otu-1) */
   /*   { */
   /*     printf("\n. Node %3d: ",t->sorted_nd[i]->num); */
-  /*     For(j,t->ldscape_sz) */
+  /*     for(j=0;j<t->ldscape_sz;j++) */
   /*       { */
   /*         /\* printf("%3d [%12f;%12f]   ", *\/ */
   /*         /\*        t->occup[t->sorted_nd[i]->num*t->ldscape_sz + j], *\/ */
@@ -662,9 +661,9 @@ void GEO_Update_Rmat(t_node *n, t_geo *t, t_tree *tree)
   int i,j;
   phydbl lbda_j;
 
-  For(i,t->ldscape_sz)
+  for(i=0;i<t->ldscape_sz;i++)
     {
-      For(j,t->ldscape_sz)
+      for(j=0;j<t->ldscape_sz;j++)
         {
           lbda_j = ((t->occup[n->num*t->ldscape_sz + j]==0) ? (1.0) : (t->lbda));
           t->r_mat[i*t->ldscape_sz+j] = t->f_mat[i*t->ldscape_sz+j] * lbda_j * t->tau * t->dum;          
@@ -722,7 +721,7 @@ phydbl GEO_Lk(t_geo *t, t_tree *tree)
           
       /*     printf("\n >> "); */
       /*     int j; */
-      /*     For(j,t->ldscape_sz)  */
+      /*     for(j=0;j<t->ldscape_sz;j++)  */
       /*       if(t->occup[t->sorted_nd[i]->num * t->ldscape_sz + j] > 0)  */
       /*         printf("%f %f -- ", */
       /*                t->ldscape[j*t->n_dim+0], */
@@ -733,7 +732,7 @@ phydbl GEO_Lk(t_geo *t, t_tree *tree)
       /* printf("\n. %d %d (%d) %f %p %p \n",i,curr_n->num,curr_n->tax,tree->rates->nd_t[curr_n->num],curr_n->v[1],curr_n->v[2]); */
 
       v1 = v2 = NULL;
-      For(j,3) 
+      for(j=0;j<3;j++) 
         if(curr_n->v[j] != curr_n->anc && curr_n->b[j] != tree->e_root)
           {
             if(!v1) v1 = curr_n->v[j];
@@ -751,12 +750,12 @@ phydbl GEO_Lk(t_geo *t, t_tree *tree)
       /*        t->ldscape[arr*t->n_dim+1]-t->ldscape[dep*t->n_dim+1]); */
 
       loglk -= R * FABS(tree->rates->nd_t[curr_n->num] - tree->rates->nd_t[prev_n->num]);
-      loglk += LOG(t->r_mat[dep * t->ldscape_sz + arr]);
+      loglk += log(t->r_mat[dep * t->ldscape_sz + arr]);
 
       /* printf("\n <> %d %f %f %d %d v1:%d v2:%d anc:%d %d %d %d", */
       /*        curr_n->num, */
       /*        R * FABS(tree->rates->nd_t[curr_n->num] - tree->rates->nd_t[prev_n->num]), */
-      /*        LOG(t->r_mat[dep * t->ldscape_sz + arr]), */
+      /*        log(t->r_mat[dep * t->ldscape_sz + arr]), */
       /*        dep,arr,v1->num,v2->num,curr_n->anc->num,curr_n->v[0]->num,curr_n->v[1]->num,curr_n->v[2]->num); */
 
       /* if(i<2) */
@@ -776,7 +775,7 @@ phydbl GEO_Lk(t_geo *t, t_tree *tree)
   // the next node)
   GEO_Update_Rmat(tree->n_root,t,tree);
 
-  loglk -= LOG(t->ldscape_sz); 
+  loglk -= log(t->ldscape_sz); 
   dep = t->idx_loc[tree->n_root->num];
   arr = 
     (t->idx_loc[tree->n_root->num] != t->idx_loc[tree->n_root->v[1]->num] ? 
@@ -785,12 +784,12 @@ phydbl GEO_Lk(t_geo *t, t_tree *tree)
   
   /* printf("\n %f %f",t->ldscape[dep],t->ldscape[arr]); */
 
-  loglk += LOG(t->r_mat[dep * t->ldscape_sz + arr]);
+  loglk += log(t->r_mat[dep * t->ldscape_sz + arr]);
     
   sum = .0;
-  For(i,t->ldscape_sz) sum += t->r_mat[dep * t->ldscape_sz + i];
+  for(i=0;i<t->ldscape_sz;i++) sum += t->r_mat[dep * t->ldscape_sz + i];
   
-  loglk -= LOG(sum);
+  loglk -= log(sum);
 
   tree->geo->c_lnL = loglk;
 
@@ -805,7 +804,7 @@ void GEO_Init_Tloc_Tips(t_geo *t, t_tree *tree)
   int i;
 
   // TO DO
-  For(i,tree->n_otu)
+  for(i=0;i<tree->n_otu;i++)
     {
       t->idx_loc[i] = i;
     }
@@ -822,9 +821,9 @@ phydbl GEO_Total_Migration_Rate(t_node *n, t_geo *t)
 
   R = .0;
 
-  For(i,t->ldscape_sz)
+  for(i=0;i<t->ldscape_sz;i++)
     {
-      For(j,t->ldscape_sz)
+      for(j=0;j<t->ldscape_sz;j++)
         {
           R += 
             t->r_mat[i * t->ldscape_sz + j] * 
@@ -846,7 +845,7 @@ int GEO_Get_Arrival_Location(t_node *n, t_geo *t, t_tree *tree)
 
   v1 = v2 = NULL;
 
-  For(i,3)
+  for(i=0;i<3;i++)
     {
       if(n->v[i] && n->v[i] != n->anc)
         {
@@ -943,7 +942,7 @@ t_tree *GEO_Simulate(t_geo *t, int n_otu)
 
  // total migration rate
   R = 0.0;
-  For(i,t->ldscape_sz) 
+  for(i=0;i<t->ldscape_sz;i++) 
     {
       R += 
         t->f_mat[t->idx_loc[tree->n_root->num]*t->ldscape_sz+i] * 
@@ -968,7 +967,7 @@ t_tree *GEO_Simulate(t_geo *t, int n_otu)
       dep = t->idx_loc[branching_nodes[hit]->num]; // Departure point
            
       sum = .0;
-      For(i,t->ldscape_sz) // Total rate of migration out of departure point
+      for(i=0;i<t->ldscape_sz;i++) // Total rate of migration out of departure point
         {
           p_mig[i] = 
             t->f_mat[dep*t->ldscape_sz+i] * 
@@ -977,7 +976,7 @@ t_tree *GEO_Simulate(t_geo *t, int n_otu)
 
           sum += p_mig[i];
         }      
-      For(i,t->ldscape_sz) p_mig[i] /= sum;
+      for(i=0;i<t->ldscape_sz;i++) p_mig[i] /= sum;
 
       arr = Sample_i_With_Proba_pi(p_mig,t->ldscape_sz);
 
@@ -1014,11 +1013,11 @@ t_tree *GEO_Simulate(t_geo *t, int n_otu)
 
       // Update total migration rate 
       R = .0;
-      For(i,t->ldscape_sz)
+      for(i=0;i<t->ldscape_sz;i++)
         {
           if(occup[i] > 0)
             {
-              For(j,t->ldscape_sz)
+              for(j=0;j<t->ldscape_sz;j++)
                 {
                   R += 
                     occup[i] *
@@ -1037,7 +1036,7 @@ t_tree *GEO_Simulate(t_geo *t, int n_otu)
         {
           dep = t->idx_loc[branching_nodes[i]->num];
           p_branch[i] = 0.0;
-          For(j,t->ldscape_sz)
+          for(j=0;j<t->ldscape_sz;j++)
             {
               p_branch[i] +=
                 t->f_mat[dep*t->ldscape_sz+j] * 
@@ -1119,7 +1118,7 @@ t_tree *GEO_Simulate(t_geo *t, int n_otu)
     /* } */
 
 
-  For(i,tree->n_otu) 
+  for(i=0;i<tree->n_otu;i++) 
     {
       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");
@@ -1160,7 +1159,7 @@ t_tree *GEO_Simulate(t_geo *t, int n_otu)
 
   DR_Draw_Tree("essai.ps",tree);
 
-  /* For(i,tree->n_otu) */
+  /* for(i=0;i<tree->n_otu;i++) */
   /*   printf("\n. %4s %4d [%5.2f %5.2f]",tree->a_nodes[i]->name, */
   /*          t->idx_loc[i], */
   /*          t->ldscape[t->idx_loc[i]*t->n_dim+0], */
@@ -1188,7 +1187,7 @@ void GEO_Simulate_Coordinates(int n, t_geo *t)
 
   width = 5.;
 
-  For(i,n)
+  for(i=0;i<n;i++)
     {
       /* t->ldscape[i*t->n_dim+0] = -width/2. + Uni()*width; */
       /* t->ldscape[i*t->n_dim+1] = width/2.; */
@@ -1302,7 +1301,7 @@ void GEO_Randomize_Locations(t_node *n, t_geo *t, t_tree *tree)
       probs = (phydbl *)mCalloc(t->ldscape_sz,sizeof(phydbl));
       
       v1 = v2 = NULL;
-      For(i,3)
+      for(i=0;i<3;i++)
         {
           if(n->v[i] != n->anc && n->b[i] != tree->e_root)
             {
@@ -1327,16 +1326,16 @@ void GEO_Randomize_Locations(t_node *n, t_geo *t, t_tree *tree)
       else if(v1->tax && !v2->tax && t->idx_loc[v1->num] == t->idx_loc[n->num])
         {
           sum = 0.0;
-          For(i,t->ldscape_sz) sum += t->idx_loc_beneath[v2->num * t->ldscape_sz + i];
-          For(i,t->ldscape_sz) probs[i] = t->idx_loc_beneath[v2->num * t->ldscape_sz + i]/sum;
+          for(i=0;i<t->ldscape_sz;i++) sum += t->idx_loc_beneath[v2->num * t->ldscape_sz + i];
+          for(i=0;i<t->ldscape_sz;i++) probs[i] = t->idx_loc_beneath[v2->num * t->ldscape_sz + i]/sum;
           
           t->idx_loc[v2->num] = Sample_i_With_Proba_pi(probs,t->ldscape_sz);      
         }
       else if(v2->tax && !v1->tax && t->idx_loc[v2->num] == t->idx_loc[n->num])
         {
           sum = 0.0;
-          For(i,t->ldscape_sz) sum += t->idx_loc_beneath[v1->num * t->ldscape_sz + i];
-          For(i,t->ldscape_sz) probs[i] = t->idx_loc_beneath[v1->num * t->ldscape_sz + i]/sum;
+          for(i=0;i<t->ldscape_sz;i++) sum += t->idx_loc_beneath[v1->num * t->ldscape_sz + i];
+          for(i=0;i<t->ldscape_sz;i++) probs[i] = t->idx_loc_beneath[v1->num * t->ldscape_sz + i]/sum;
           
           t->idx_loc[v1->num] = Sample_i_With_Proba_pi(probs,t->ldscape_sz);      
         }
@@ -1362,8 +1361,8 @@ void GEO_Randomize_Locations(t_node *n, t_geo *t, t_tree *tree)
           if(u < p)
             {              
               sum = 0.0;
-              For(i,t->ldscape_sz) sum += t->idx_loc_beneath[v2->num * t->ldscape_sz + i];
-              For(i,t->ldscape_sz) probs[i] = t->idx_loc_beneath[v2->num * t->ldscape_sz + i]/sum;
+              for(i=0;i<t->ldscape_sz;i++) sum += t->idx_loc_beneath[v2->num * t->ldscape_sz + i];
+              for(i=0;i<t->ldscape_sz;i++) probs[i] = t->idx_loc_beneath[v2->num * t->ldscape_sz + i]/sum;
               
               t->idx_loc[v2->num] = Sample_i_With_Proba_pi(probs,t->ldscape_sz);      
               t->idx_loc[v1->num] = t->idx_loc[n->num];                
@@ -1373,8 +1372,8 @@ void GEO_Randomize_Locations(t_node *n, t_geo *t, t_tree *tree)
               if(t->idx_loc_beneath[v2->num * t->ldscape_sz + t->idx_loc[n->num]] > 0)
                 {
                   sum = 0.0;
-                  For(i,t->ldscape_sz) sum += t->idx_loc_beneath[v1->num * t->ldscape_sz + i];
-                  For(i,t->ldscape_sz) probs[i] = t->idx_loc_beneath[v1->num * t->ldscape_sz + i]/sum;
+                  for(i=0;i<t->ldscape_sz;i++) sum += t->idx_loc_beneath[v1->num * t->ldscape_sz + i];
+                  for(i=0;i<t->ldscape_sz;i++) probs[i] = t->idx_loc_beneath[v1->num * t->ldscape_sz + i]/sum;
                   
                   t->idx_loc[v1->num] = Sample_i_With_Proba_pi(probs,t->ldscape_sz);      
                   t->idx_loc[v2->num] = t->idx_loc[n->num];
@@ -1382,8 +1381,8 @@ void GEO_Randomize_Locations(t_node *n, t_geo *t, t_tree *tree)
               else
                 {
                   sum = 0.0;
-                  For(i,t->ldscape_sz) sum += t->idx_loc_beneath[v2->num * t->ldscape_sz + i];
-                  For(i,t->ldscape_sz) probs[i] = t->idx_loc_beneath[v2->num * t->ldscape_sz + i]/sum;
+                  for(i=0;i<t->ldscape_sz;i++) sum += t->idx_loc_beneath[v2->num * t->ldscape_sz + i];
+                  for(i=0;i<t->ldscape_sz;i++) probs[i] = t->idx_loc_beneath[v2->num * t->ldscape_sz + i]/sum;
                   
                   t->idx_loc[v2->num] = Sample_i_With_Proba_pi(probs,t->ldscape_sz);      
                   t->idx_loc[v1->num] = t->idx_loc[n->num];                
@@ -1415,7 +1414,7 @@ void GEO_Randomize_Locations(t_node *n, t_geo *t, t_tree *tree)
       
       Free(probs);
       
-      For(i,3)
+      for(i=0;i<3;i++)
         if(n->v[i] != n->anc && n->b[i] != tree->e_root) 
           GEO_Randomize_Locations(n->v[i],t,tree);
     }
@@ -1430,7 +1429,7 @@ void GEO_Get_Locations_Beneath(t_geo *t, t_tree *tree)
   GEO_Get_Locations_Beneath_Post(tree->n_root,tree->n_root->v[1],t,tree);
   GEO_Get_Locations_Beneath_Post(tree->n_root,tree->n_root->v[2],t,tree);
 
-  For(i,t->ldscape_sz)
+  for(i=0;i<t->ldscape_sz;i++)
     {
       t->idx_loc_beneath[tree->n_root->num*t->ldscape_sz+i] =
         t->idx_loc_beneath[tree->n_root->v[1]->num*t->ldscape_sz+i] +
@@ -1454,7 +1453,7 @@ void GEO_Get_Locations_Beneath_Post(t_node *a, t_node *d, t_geo *t, t_tree *tree
       int i;
       t_node *v1, *v2;
 
-      For(i,3) 
+      for(i=0;i<3;i++) 
         {
           if(d->v[i] != a && d->b[i] != tree->e_root)
             {
@@ -1464,7 +1463,7 @@ void GEO_Get_Locations_Beneath_Post(t_node *a, t_node *d, t_geo *t, t_tree *tree
           
 
       v1 = v2 = NULL;
-      For(i,3) 
+      for(i=0;i<3;i++) 
         {
           if(d->v[i] != a && d->b[i] != tree->e_root)
             {
@@ -1474,7 +1473,7 @@ void GEO_Get_Locations_Beneath_Post(t_node *a, t_node *d, t_geo *t, t_tree *tree
         }
           
 
-      For(i,t->ldscape_sz) 
+      for(i=0;i<t->ldscape_sz;i++) 
         {
           t->idx_loc_beneath[ d->num*t->ldscape_sz+i] = 
             t->idx_loc_beneath[v1->num*t->ldscape_sz+i] + 
@@ -1503,7 +1502,7 @@ void GEO_Get_Sigma_Max(t_geo *t)
 
   mean_dist = -1.;
   inv_mean_dist = -1.;
-  For(i,t->ldscape_sz-1)
+  for(i=0;i<t->ldscape_sz-1;i++)
     {
       for(j=i+1;j<t->ldscape_sz;j++)
         {
@@ -1612,7 +1611,7 @@ void MCMC_Geo_Updown_Tau_Lbda(t_tree *tree)
   new_lbda = tree->geo->lbda;
 
   u = Uni();
-  mult = EXP(K*(u-0.5));
+  mult = exp(K*(u-0.5));
 
   /* Multiply tau by K */
   new_tau = cur_tau * K;
@@ -1633,18 +1632,18 @@ void MCMC_Geo_Updown_Tau_Lbda(t_tree *tree)
   tree->geo->tau  = new_tau;
   tree->geo->lbda = new_lbda;
 
-  if(tree->mcmc->use_data) new_lnL = GEO_Lk(tree->geo,tree);
+  if(tree->eval_alnL) new_lnL = GEO_Lk(tree->geo,tree);
 
   ratio = 0.0;
   /* Proposal ratio: 2n-2=> number of multiplications, 1=>number of divisions */
-  ratio += 0.0*LOG(mult); /* (1-1)*LOG(mult); */
+  ratio += 0.0*log(mult); /* (1-1)*log(mult); */
   /* Likelihood density ratio */
   ratio += (new_lnL - cur_lnL);
 
   /* printf("\n. new_tau: %f new_lbda:%f cur_lnL:%f new_lnL:%f",new_tau,new_lbda,cur_lnL,new_lnL); */
 
 
-  ratio = EXP(ratio);
+  ratio = exp(ratio);
   alpha = MIN(1.,ratio);
   u = Uni();
   
@@ -1682,7 +1681,7 @@ void MCMC_Geo_Updown_Lbda_Sigma(t_tree *tree)
   new_sigma = tree->geo->sigma;
 
   u = Uni();
-  mult = EXP(K*(u-0.5));
+  mult = exp(K*(u-0.5));
 
   /* Multiply lbda by K */
   new_lbda = cur_lbda * K;
@@ -1703,18 +1702,18 @@ void MCMC_Geo_Updown_Lbda_Sigma(t_tree *tree)
   tree->geo->lbda   = new_lbda;
   tree->geo->sigma = new_sigma;
 
-  if(tree->mcmc->use_data) new_lnL = GEO_Lk(tree->geo,tree);
+  if(tree->eval_alnL) new_lnL = GEO_Lk(tree->geo,tree);
 
   ratio = 0.0;
   /* Proposal ratio: 2n-2=> number of multiplications, 1=>number of divisions */
-  ratio += 0.0*LOG(mult); /* (1-1)*LOG(mult); */
+  ratio += 0.0*log(mult); /* (1-1)*log(mult); */
   /* Likelihood density ratio */
   ratio += (new_lnL - cur_lnL);
 
   /* printf("\n. new_lbda: %f new_sigma:%f cur_lnL:%f new_lnL:%f",new_lbda,new_sigma,cur_lnL,new_lnL); */
 
 
-  ratio = EXP(ratio);
+  ratio = exp(ratio);
   alpha = MIN(1.,ratio);
   u = Uni();
   
@@ -1759,7 +1758,7 @@ void GEO_Read_In_Landscape(char *file_name, t_geo *t, phydbl **ldscape, int **lo
     {
       if(fscanf(fp,"%s",s) == EOF) break;
 
-      if(strlen(s) > 0) For(tax,tree->n_otu) if(!strcmp(tree->a_nodes[tax]->name,s)) break;
+      if(strlen(s) > 0) for(tax=0;tax<tree->n_otu;tax++) if(!strcmp(tree->a_nodes[tax]->name,s)) break;
 
       if(tax == tree->n_otu)
         {
@@ -1775,7 +1774,7 @@ void GEO_Read_In_Landscape(char *file_name, t_geo *t, phydbl **ldscape, int **lo
 
       /* printf("\n. s: %s %f %f",s,longitude,lattitude); */
 
-      For(loc,t->ldscape_sz)
+      for(loc=0;loc<t->ldscape_sz;loc++)
         {
           if(FABS(longitude-(*ldscape)[loc*t->n_dim+0]) < 1.E-10 &&
              FABS(lattitude-(*ldscape)[loc*t->n_dim+1]) < 1.E-10)
@@ -1801,7 +1800,7 @@ void GEO_Read_In_Landscape(char *file_name, t_geo *t, phydbl **ldscape, int **lo
     }
   while(1);
 
-  For(tax,tree->n_otu)
+  for(tax=0;tax<tree->n_otu;tax++)
     PhyML_Printf("\n. Taxon %30s, longitude: %12f, lattitude: %12f [%4d]",
                  tree->a_nodes[tax]->name,
                  (*ldscape)[(*loc_hash)[tax]*t->n_dim+0],
diff --git a/src/help.c b/src/help.c
index 46e34fa..130b7bd 100644
--- a/src/help.c
+++ b/src/help.c
@@ -31,7 +31,7 @@ void Usage()
   char *cha;
 
 
-  cha =getenv("OS");
+  cha = getenv("OS");
 
   if(cha!=NULL) 
     {
diff --git a/src/init.c b/src/init.c
index e3ac4ee..563a6ab 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,11 @@ void Init_Tree(t_tree *tree, int n_otu)
   tree->prev                      = NULL;
   tree->mixt_tree                 = NULL;
   tree->geo                       = NULL;
+  tree->xml_root                  = NULL;
+  tree->extra_tree                = NULL;
+  tree->verbose                   = VL3;
+  tree->edge_list                 = NULL;
+  tree->node_list                 = NULL;
 
   tree->is_mixt_tree              = NO;
   tree->tree_num                  = 0;
@@ -131,8 +138,8 @@ void Init_Tree(t_tree *tree, int n_otu)
   tree->n_root_pos                = -1.;
   tree->write_labels              = YES;
   tree->write_br_lens             = YES;
-  tree->print_boot_val            = 0;
-  tree->print_alrt_val            = 0;
+  tree->print_boot_val            = NO;
+  tree->print_alrt_val            = NO;
   tree->num_curr_branch_available = 0;
   tree->tip_order_score           = .0;
   tree->write_tax_names           = YES;
@@ -147,6 +154,15 @@ 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;
+  tree->update_eigen_lr           = NO;
+  tree->use_eigen_lr              = NO;
+  tree->eval_alnL                 = YES;
+  tree->eval_rlnL                 = YES;
+  tree->eval_glnL                 = YES;
+  tree->scaling_method            = SCALE_FAST;
+  tree->perform_spr_right_away    = YES;
+  
 #ifdef BEAGLE
   tree->b_inst                    = UNINITIALIZED;
 #endif
@@ -190,7 +206,7 @@ void Init_Edge_Light(t_edge *b, int num)
   b->p_pars_r             = NULL;
   b->n_diff_states_l      = NULL;
   b->n_diff_states_r      = NULL;
-
+  
 #ifdef BEAGLE
   b->p_lk_left_idx         = num;
   b->p_lk_rght_idx         = UNINITIALIZED; //Will be initialized later when the total number of branches is known (i.e. in Make_Tree_From_Scratch())
@@ -225,23 +241,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 +267,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;
 }
 
 //////////////////////////////////////////////////////////////
@@ -499,7 +520,7 @@ void Init_Mat(matrix *mat, calign *data)
   mat->curr_int = mat->n_otu;
   mat->method = 1;
 
-  For(i,data->n_otu)
+  for(i=0;i<data->n_otu;i++)
     {
       strcpy(mat->name[i],data->c_seq[i]->name);
       mat->on_off[i] = 1;
@@ -521,6 +542,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 +573,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 +593,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
@@ -623,20 +649,18 @@ void Set_Defaults_Model(t_mod *mod)
   /* mod->r_mat->rr_val           = NULL; */
   /* mod->r_mat->n_rr_per_cat     = NULL; */
 
-  mod->io                       = NULL;
-  mod->log_l                    = NO;
-  mod->gamma_mgf_bl             = NO;
-  mod->br_len_mult->v     = 1.0;
+  mod->io             = NULL;
+  mod->log_l          = NO;
+  mod->gamma_mgf_bl   = NO;
+  mod->br_len_mult->v = 1.0;
 
 
 #if !(defined PHYTIME || defined INVITEE)
-  mod->l_min = 1.E-8;
-  mod->l_max = 10.0;
-  /* mod->l_min = 1.E-4; */
-  /* mod->l_max = 2.0; */
+  mod->l_min = 1.E-10;
+  mod->l_max = 100.0;
 #else
-  mod->l_min = 1.E-8;
-  mod->l_max = 2.0;
+  mod->l_min = 1.E-6;
+  mod->l_max = 10.0;
 #endif
 
   mod->l_var_min  = mod->l_min;
@@ -669,7 +693,6 @@ void Set_Defaults_Ras(t_ras *ras)
 
 void Set_Defaults_Optimiz(t_opt *s_opt)
 {
-  s_opt->print                = YES;
   s_opt->last_opt             = YES;
   s_opt->opt_subst_param      = YES;
   s_opt->opt_alpha            = YES;
@@ -689,15 +712,11 @@ 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; */
-  /* s_opt->min_diff_lk_global   = 1.E-03; */
-  /* s_opt->min_diff_lk_move     = 1.E-02; */
-  s_opt->min_diff_lk_local    = 1.E-02;
-  s_opt->min_diff_lk_global   = 1.E-02;
-  s_opt->min_diff_lk_move     = 1.E-02;
+  s_opt->min_diff_lk_local    = 1.E-03;
+  s_opt->min_diff_lk_global   = 1.E-03;
+  s_opt->min_diff_lk_move     = 1.E-03;
 
   s_opt->p_moves_to_examine   = 0.15;
   s_opt->fast_nni             = NO;
@@ -705,6 +724,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;
 
@@ -713,10 +733,13 @@ void Set_Defaults_Optimiz(t_opt *s_opt)
   s_opt->spr_pars             = YES;
   s_opt->spr_lnL              = NO;
   s_opt->min_depth_path       = 0;
+  s_opt->eval_list_regraft    = NO;
 
-  s_opt->max_depth_path       = 20;
-  s_opt->deepest_path         = 20;
-  s_opt->max_delta_lnL_spr    = 50.;
+  s_opt->max_depth_path            = 20;
+  s_opt->deepest_path              = 20;
+  s_opt->max_delta_lnL_spr         = 2000.;
+  s_opt->max_delta_lnL_spr_current = 0.0;
+  s_opt->worst_lnL_spr             = BIG;
 
   s_opt->br_len_in_spr        = 10;
   s_opt->opt_free_mixt_rates  = YES;
@@ -786,7 +809,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,13 +832,14 @@ 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("");
     }
 
 
   rates->met_within_gibbs = NO;
   rates->c_lnL_rates      = UNLIKELY;
+  rates->c_lnL_times      = UNLIKELY;
   rates->c_lnL_jps        = UNLIKELY;
   rates->adjust_rates     = 0;
   rates->use_rates        = 1;
@@ -825,47 +849,44 @@ void RATES_Init_Rate_Struct(t_rate *rates, t_rate *existing_rates, int n_otu)
   rates->nd_t_recorded    = NO;
   rates->br_r_recorded    = NO;
 
-  rates->birth_rate       = 1.E-2;
+  rates->birth_rate       = 1.E-1;
   rates->birth_rate_min   = 1.E-6;
-  rates->birth_rate_max   = 1.E+1;
+  rates->birth_rate_max   = 1.E+0;
+  rates->birth_rate_pivot = 1.E-1;
+
+  rates->death_rate       = 1.E-1;
+  rates->death_rate_min   = 1.E-6;
+  rates->death_rate_max   = 1.E+0;
+  rates->death_rate_pivot = 1.E-1;
 
   if(rates->model_log_rates == YES)
     {
-      rates->max_rate  =  LOG(10.);
-      rates->min_rate  = -LOG(10.);
+      rates->max_rate  =  log(10.);
+      rates->min_rate  = -log(10.);
       /* rates->max_rate  =  MDBL_MAX; */
       /* rates->min_rate  = -MDBL_MAX; */
     }
   else
     {
-      rates->max_rate  = 10.0;
-      rates->min_rate  = 0.0;
+      rates->max_rate  = 100.0;
+      rates->min_rate  = 0.001;
     }
   /* rates->max_rate         = 6.0; */
   /* rates->min_rate         = 0.0; */
 
 
   rates->clock_r       = 1.E-4;
-  rates->min_clock     = 1.E-8;
-  rates->max_clock     = 1.E-3;
+  rates->min_clock     = 1.E-10;
+  rates->max_clock     = 1.E+2;
 
   /* rates->clock_r       = 3.E-4; */
   /* rates->max_clock     = 1.E-3; */
   /* rates->min_clock     = 1.E-5; */
 
-  if(rates->model != GAMMA)
-    {
-      rates->nu            = 1.E-3;
-      rates->min_nu        = 0.0;
-      rates->max_nu        = 1.0;
-    }
-  else
-    {
-      rates->nu            = 1.E-1;
-      rates->min_nu        = 1.E-2;
-      rates->max_nu        = 100.0;
-    }
-
+  rates->nu            = 1.0E-1;
+  rates->min_nu        = 0.0;
+  rates->max_nu        = 1.E+8;
+  
   /* rates->max_nu        = 2.0; */
 
   /* rates->nu            = 1.E-4; */
@@ -880,6 +901,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 +945,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 +956,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 +964,48 @@ 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;
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void Init_Target_Tip(t_cal *cal, t_tree *tree)
+{
+  int i,j;
+
+  for(i=0;i<cal->n_target_tax;i++)
+    {
+      for(j=0;j<tree->n_otu;j++)
+        {
+          if(!strcmp(tree->a_nodes[j]->name,cal->target_tax[i]))
+            {
+              cal->target_tip[i] = tree->a_nodes[j];
+              break;
+            }
+        }
+      assert(j != tree->n_otu);
+    }
 }
 
 //////////////////////////////////////////////////////////////
@@ -976,6 +1018,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;
@@ -983,9 +1029,9 @@ void Init_Model(calign *data, t_mod *mod, option *io)
 
   mod->ns = io->mod->ns;
 
-  if(io->datatype == GENERIC) mod->whichmodel = JC69;
 
-  /* if(!mod->ras->invar) For(i,data->crunch_len) data->invar[i] = 0; */
+
+  if(io->datatype == GENERIC) mod->whichmodel = JC69;
 
   dr      = (phydbl *)mCalloc(  mod->ns,sizeof(phydbl));
   di      = (phydbl *)mCalloc(  mod->ns,sizeof(phydbl));
@@ -993,30 +1039,34 @@ void Init_Model(calign *data, t_mod *mod, option *io)
 
   if(mod->log_l == YES)
     {
-      mod->l_min = LOG(mod->l_min);
-      mod->l_max = LOG(mod->l_max);
+      mod->l_min = log(mod->l_min);
+      mod->l_max = log(mod->l_max);
     }
-
+  
+  // Init unscaled relative rate frequencies
   if(mod->ras->init_r_proba == YES)
     {
-      For(i,mod->ras->n_catg) mod->ras->gamma_r_proba->v[i]          = (phydbl)1./mod->ras->n_catg;
-      For(i,mod->ras->n_catg) mod->ras->gamma_r_proba_unscaled->v[i] = (phydbl)(i+1);
+      for(i=0;i<mod->ras->n_catg;i++) mod->ras->gamma_r_proba->v[i]          = (phydbl)1./mod->ras->n_catg;
+      for(i=0;i<mod->ras->n_catg;i++) mod->ras->gamma_r_proba_unscaled->v[i] = (phydbl)(i+1);
     }
   else
     {
-      mod->ras->gamma_r_proba_unscaled->v[0] = mod->ras->gamma_r_proba->v[0];
-      for(i=1;i<mod->ras->n_catg;i++)
-        mod->ras->gamma_r_proba_unscaled->v[i] =
-          mod->ras->gamma_r_proba_unscaled->v[i-1] +
-          mod->ras->gamma_r_proba->v[i];
+      mod->ras->gamma_r_proba_unscaled->v[mod->ras->n_catg-1] = 1.0;
+      for(i=0;i<mod->ras->n_catg;i++)
+        {
+          sum = 0.0;
+          For(j,i+1) sum += mod->ras->gamma_r_proba->v[j];
+          mod->ras->gamma_r_proba_unscaled->v[i] = sum * mod->ras->gamma_r_proba_unscaled->v[mod->ras->n_catg-1];
+        }
     }
 
+  // Init unscaled relative rates
   if(mod->ras->init_rr == YES)
     {
       if(mod->ras->n_catg > 1)
         {
-          For(i,mod->ras->n_catg) mod->ras->gamma_rr->v[i]          = (phydbl)i;
-          For(i,mod->ras->n_catg) mod->ras->gamma_rr_unscaled->v[i] = (phydbl)i;
+          for(i=0;i<mod->ras->n_catg;i++) mod->ras->gamma_rr->v[i]          = (phydbl)i;
+          for(i=0;i<mod->ras->n_catg;i++) mod->ras->gamma_rr_unscaled->v[i] = (phydbl)i;
         }
       else
         {
@@ -1024,17 +1074,11 @@ void Init_Model(calign *data, t_mod *mod, option *io)
           mod->ras->gamma_rr_unscaled->v[0] = 1.0;
         }
     }
-  
-  /* 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.;
+  else
+    {      
+      for(i=0;i<mod->ras->n_catg;i++) mod->ras->gamma_rr_unscaled->v[i] = mod->ras->gamma_rr->v[i];      
     }
-
-
+  
   if(io->datatype == NT)
     {
       /* Set the substitution parameters to their default values
@@ -1047,9 +1091,9 @@ void Init_Model(calign *data, t_mod *mod, option *io)
       
       if(mod->whichmodel == CUSTOM)
         {
-          For(i,6) mod->r_mat->rr_val->v[i] = 1.0;
+          for(i=0;i<6;i++) 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] &&
@@ -1066,7 +1110,7 @@ void Init_Model(calign *data, t_mod *mod, option *io)
         }
       else if(mod->whichmodel == GTR)
         {
-          For(i,6) mod->r_mat->rr_val->v[i] = 1.0;
+          for(i=0;i<6;i++) mod->r_mat->rr_val->v[i] = 1.0;
           mod->r_mat->rr_val->v[AG] = 4.0;
           mod->r_mat->rr_val->v[CT] = 4.0;
         }
@@ -1102,12 +1146,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=0;i<4;i++) mod->e_frq->pi->v[i] = mod->e_frq->user_b_freq->v[i];
+          for(i=0;i<mod->ns;i++) 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=0;i<4;i++) mod->e_frq->pi->v[i] = mod->e_frq->user_b_freq->v[i];
+          for(i=0;i<mod->ns;i++) 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,21 +1165,38 @@ 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=0;i<4;i++) mod->e_frq->pi->v[i] = mod->e_frq->user_b_freq->v[i];
+          for(i=0;i<mod->ns;i++) 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=0;i<4;i++) mod->e_frq->pi->v[i] = mod->e_frq->user_b_freq->v[i];
+          for(i=0;i<mod->ns;i++) 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=0;i<4;i++) mod->e_frq->pi->v[i] = mod->e_frq->user_b_freq->v[i];
+          for(i=0;i<mod->ns;i++) mod->e_frq->pi_unscaled->v[i] = mod->e_frq->pi->v[i] * 100.;
           mod->kappa->v          = 1.;
-          mod->update_eigen      = YES;
+          mod->update_eigen      = NO;
           io->mod->s_opt->opt_rr = YES;
         }
       
       if(mod->whichmodel == CUSTOM)
         {
-          mod->kappa->v = 1.;
-          mod->update_eigen = YES;
+          if(mod->e_frq->user_state_freq == NO) Init_Efrqs_Using_Observed_Freqs(mod->e_frq,data->b_frq,mod->ns);  
+          else for(i=0;i<4;i++) mod->e_frq->pi->v[i] = mod->e_frq->user_b_freq->v[i];
+          for(i=0;i<mod->ns;i++) mod->e_frq->pi_unscaled->v[i] = mod->e_frq->pi->v[i] * 100.;
+          mod->kappa->v     = 1.;
+          mod->update_eigen = NO;
           /* 	  io->mod->s_opt->opt_rr     = YES; */ /* What if the user decided not to optimise the rates? */
         }
       
@@ -1143,27 +1210,6 @@ 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)) &&
-         (mod->use_m4mod == NO))
-        {
-          mod->update_eigen = YES;
-          Update_Eigen(mod);
-          mod->update_eigen = NO;
-        }
-      /* if((mod->whichmodel != GTR)    &&  */
-      /* 	 (mod->whichmodel != CUSTOM) &&  */
-      /* 	 (mod->whichmodel != HKY85)) mod->update_eigen = NO; */
     }
   else if(mod->io->datatype == AA)
     {
@@ -1183,138 +1229,118 @@ 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)
+      for(i=0;i<mod->ns;i++) if(mod->e_frq->pi->v[i] < 1.E-10)
         {
           PhyML_Printf("\n. WARNING: at least one amino-acid frequency is equal to 0.0!");
           PhyML_Printf("\n. Numerical precision issues are likely to arise...");
@@ -1322,8 +1348,8 @@ 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 *\/ */
-      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;
+      /* multiply the nth col of Q by the nth term of pi/100 just as in PAML */
+      for(i=0;i<mod->ns;i++) for(j=0;j<mod->ns;j++) 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 */
       mod->mr->v= .0;
@@ -1335,7 +1361,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 */
@@ -1355,8 +1381,8 @@ void Init_Model(calign *data, t_mod *mod, option *io)
               Exit("\n");
             }
           
-          /* compute the diagonal terms of EXP(D) */
-          For(i,mod->ns) mod->eigen->e_val[i] = (phydbl)EXP(mod->eigen->e_val[i]);
+          /* compute the diagonal terms of exp(D) */
+          for(i=0;i<mod->ns;i++) mod->eigen->e_val[i] = (phydbl)exp(mod->eigen->e_val[i]);
         }
       else
         {
@@ -1367,7 +1393,7 @@ void Init_Model(calign *data, t_mod *mod, option *io)
   else if(mod->io->datatype == GENERIC)
     {
       /* Uniform state frequencies */
-      For(i,mod->ns)  mod->e_frq->pi->v[i] = 1./(phydbl)mod->ns;
+      for(i=0;i<mod->ns;i++)  mod->e_frq->pi->v[i] = 1./(phydbl)mod->ns;
       mod->kappa->v = 1;
       mod->s_opt->opt_state_freq = NO;
       mod->s_opt->opt_kappa      = NO;
@@ -1385,7 +1411,32 @@ void Init_Model(calign *data, t_mod *mod, option *io)
 
   Init_Eigen_Struct(mod->eigen);
 
-  free(dr);free(di);free(space);
+  free(dr);
+  free(di);
+  free(space);
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void Init_Efrqs_Using_Observed_Freqs(t_efrq *f, phydbl *o, int ns)
+{
+  int i;
+  phydbl eps,sum;
+
+  assert(f);
+  assert(o);
+
+  // To avoid numerical prevision issues
+  eps = 1.E-50;
+
+  for(i=0;i<ns;i++) f->pi->v[i] = MAX(o[i],eps);
+
+  sum = 0.0;
+  for(i=0;i<ns;i++) sum += f->pi->v[i];
+
+  for(i=0;i<ns;i++) f->pi->v[i] /= sum;;
+
 }
 
 //////////////////////////////////////////////////////////////
@@ -1841,8 +1892,8 @@ int Init_Qmat_MtArt(phydbl *daa, phydbl *pi) // Added by Federico Abascal
             (Habr_orego,Hept_hangz)),Limu_polyp),(Poll_polym,Mega_volca),(Gomp_hodgs,Tetr_biela),
             ((Pagu_longi,Pena_monod),Harp_harpa),Spel_tulum));
 
-            Note this is not the ML topoLOGy but the consensus one (based on morphoLOGical data,
-            phyLOGenetic reconstruction using nuclear genes, etc). Where relationships are
+            Note this is not the ML topology but the consensus one (based on morphological data,
+            phylogenetic reconstruction using nuclear genes, etc). Where relationships are
             not clear, a polytomy was introduced (it contains quite a lot of polytomies!).
 
        The model was estimated using (the great and helpful) Ziheng Yang's Paml software package.
@@ -1904,7 +1955,7 @@ int Init_Qmat_MtArt(phydbl *daa, phydbl *pi) // Added by Federico Abascal
     daa[19*20+ 13] = 51.9;  daa[19*20+ 14] = 31.7;  daa[19*20+ 15] = 60.6;  daa[19*20+ 16] = 544.1;
     daa[19*20+ 17] = 0.2;   daa[19*20+ 18] = 1.6;
 
-/*  MtArt.old: esta es la MtArt que hice con 26 secuencias (2 outgroups) con una topoLOGia incorrecta
+/*  MtArt.old: esta es la MtArt que hice con 26 secuencias (2 outgroups) con una topologia incorrecta
     daa[1*20+ 0] = 0.2;     daa[2*20+ 0] = 0.2;     daa[2*20+ 1] = 8.0;     daa[3*20+ 0] = 0.2;
     daa[3*20+ 1] = 0.2;     daa[3*20+ 2] = 441.7;   daa[4*20+ 0] = 287.9;   daa[4*20+ 1] = 48.4;
     daa[4*20+ 2] = 82.4;    daa[4*20+ 3] = 0.2;     daa[5*20+ 0] = 0.2;     daa[5*20+ 1] = 149.9;
@@ -2741,7 +2792,7 @@ int Init_Qmat_RtREV(phydbl *daa, phydbl *pi)
     /*
     Dimmic M.W., J.S. Rest, D.P. Mindell, and D. Goldstein. 2002. RArtREV:
     An amino acid substitution matrix for inference of retrovirus and
-    reverse transcriptase phyLOGeny. Journal of Molecular Evolution
+    reverse transcriptase phylogeny. Journal of Molecular Evolution
     55: 65-73.
     */
 
@@ -2820,7 +2871,7 @@ int Init_Qmat_CpREV(phydbl *daa, phydbl *pi)
 
     /*
       Adachi, J., P. Waddell, W. Martin, and M. Hasegawa. 2000. Plastid
-      genome phyLOGeny and a model of amino acid substitution for proteins
+      genome phylogeny and a model of amino acid substitution for proteins
       encoded by chloroplast DNA. Journal of Molecular Evolution
       50:348-358.
     */
@@ -3203,7 +3254,7 @@ int Init_Qmat_MtMam(phydbl *daa, phydbl *pi)
 
     /*
       Cao, Y. et al. 1998 Conflict amongst individual mitochondrial
-      proteins in resolving the phyLOGeny of eutherian orders. Journal
+      proteins in resolving the phylogeny of eutherian orders. Journal
       of Molecular Evolution 15:1600-1611.
     */
 
@@ -3369,14 +3420,14 @@ void M4_Init_Model(m4 *m4mod, calign *data, t_mod *mod)
 
   mod->ns = m4mod->n_o * m4mod->n_h;
 
-  For(i,m4mod->n_o) m4mod->o_fq[i] = mod->e_frq->pi->v[i]; /*! At that stage, the mod->pi vector as been initialized
+  for(i=0;i<m4mod->n_o;i++) m4mod->o_fq[i] = mod->e_frq->pi->v[i]; /*! At that stage, the mod->pi vector as been initialized
                                                              under a standard non covarion type of model. Use these
                                                              frequencies as they have been set according to the
                                                              nucleotide substitution model chosen (e.g., 1/4 for JC69). !*/
   For(i,(int)(m4mod->n_h)) m4mod->multipl[i] = 1.;
   
   ct = 0;
-  For(i,m4mod->n_o-1)
+  for(i=0;i<m4mod->n_o-1;i++)
     {
       for(j=i+1;j<m4mod->n_o;j++)
         {
@@ -3390,10 +3441,10 @@ void M4_Init_Model(m4 *m4mod, calign *data, t_mod *mod)
 
   if(mod->s_opt->opt_cov_delta) m4mod->delta = 1.0;
   if(mod->s_opt->opt_cov_alpha) m4mod->alpha = 1.0;
-  For(i,m4mod->n_h) m4mod->h_fq[i] = fq;
-  For(i,m4mod->n_h) m4mod->h_fq_unscaled[i] = 1.0;
-  For(i,m4mod->n_h) m4mod->multipl[i] = (phydbl)i;
-  For(i,m4mod->n_h) m4mod->multipl_unscaled[i] = (phydbl)i;
+  for(i=0;i<m4mod->n_h;i++) m4mod->h_fq[i] = fq;
+  for(i=0;i<m4mod->n_h;i++) m4mod->h_fq_unscaled[i] = 1.0;
+  for(i=0;i<m4mod->n_h;i++) m4mod->multipl[i] = (phydbl)i;
+  for(i=0;i<m4mod->n_h;i++) m4mod->multipl_unscaled[i] = (phydbl)i;
 
   Switch_Eigen(YES,mod);
   M4_Update_Qmat(m4mod,mod);
@@ -3413,11 +3464,11 @@ void GEO_Init_Coord(t_geo_coord *t, int n_dim)
 
 void PHYREX_Init_Disk_Event(t_dsk *t, int n_dim, t_phyrex_mod *mmod)
 {
-  t->prev         = NULL;
-  t->next         = NULL;
-  t->mmod         = NULL;
+  t->prev  = NULL;
+  t->next  = NULL;
+  t->mmod  = NULL;
+  
   Random_String(t->id,3);
-
   GEO_Init_Coord(t->centr,n_dim);
 
   if(mmod != NULL) t->mmod = mmod;
@@ -3466,7 +3517,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,9 +3543,10 @@ 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;
   mcmc->run              = 0;
   mcmc->sample_interval  = 1E+3;
   mcmc->chain_len        = 1E+7;
@@ -3557,6 +3609,78 @@ 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->target_tip = 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->prev = NULL;
+  list->v    = NULL;
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
diff --git a/src/init.h b/src/init.h
index 7beea75..2a60cc4 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,12 @@ 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);
+void Init_Target_Tip(t_cal *cal, t_tree *tree);
 
 #endif
diff --git a/src/interface.c b/src/interface.c
index dc91189..a9119e8 100644
--- a/src/interface.c
+++ b/src/interface.c
@@ -133,42 +133,42 @@ void Launch_Interface(option *io)
   if(io->print_site_lnl)
     {
       strcpy(io->out_lk_file,io->in_align_file);
-      strcat(io->out_lk_file, "_phyml_lk");
+      strcat(io->out_lk_file, "_phyml_lk.txt");
+
       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);
     }
   
   if(io->print_trace)
     {
       strcpy(io->out_trace_file,io->in_align_file);
-      strcat(io->out_trace_file,"_phyml_trace");
+      strcat(io->out_trace_file,"_phyml_trace.txt");
+
       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);
     }
   
   if(io->mod->s_opt->random_input_tree)
     {
       strcpy(io->out_trees_file,io->in_align_file);
-      strcat(io->out_trees_file,"_phyml_trees");
+      strcat(io->out_trees_file,"_phyml_trees.txt");
+
       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);
     }
 
   if((io->print_boot_trees) && (io->mod->bootstrap > 0))
     {
       strcpy(io->out_boot_tree_file,io->in_align_file);
-      strcat(io->out_boot_tree_file,"_phyml_boot_trees");
+      strcat(io->out_boot_tree_file,"_phyml_boot_trees.txt");
+
       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");
+      strcat(io->out_boot_stats_file,"_phyml_boot_stats.txt");
+
       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 +178,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;
@@ -218,7 +216,6 @@ void Clear()
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Launch_Interface_Input(option *io)
 {
   char choix;
@@ -281,19 +278,16 @@ void Launch_Interface_Input(option *io)
 #if defined(PHYML) || defined(PART) || defined(PHYML_INSERT)
 
   strcpy(io->out_stats_file,io->in_align_file);
-  strcat(io->out_stats_file,"_phyml_stats.txt");
   
+  strcat(io->out_stats_file,"_phyml_stats.txt");  
   strcpy(io->out_tree_file,io->in_align_file);
+ 
   strcat(io->out_tree_file,"_phyml_tree.txt");
-
   strcpy(io->out_lk_file,io->in_align_file);
-  strcat(io->out_lk_file,"_phyml_lk.txt");
-
 
+  strcat(io->out_lk_file,"_phyml_lk.txt");
 #endif
 
-
-#ifdef WIN32
 #ifdef EVOLVE
   if(Filexists("evolve_out.txt"));
 #elif OPTIMIZ
@@ -301,15 +295,6 @@ void Launch_Interface_Input(option *io)
 #elif defined(PHYML) || defined(PART) || defined(PHYML_INSERT)
   if(Filexists(io->out_stats_file))
 #endif
-#elif UNIX
-#ifdef EVOLVE
-  if(Filexists("evolve_out"));
-#elif OPTIMIZ
-  if(Filexists("optimiz_out"))
-#elif defined(PHYML) || defined(PART) || defined(PHYML_INSERT)
-   if(Filexists(io->out_stats_file))
-#endif
-#endif
     {
       PhyML_Printf("\n");
 #ifdef EVOLVE
@@ -337,7 +322,6 @@ void Launch_Interface_Input(option *io)
 
   /* io->fp_out_stats = Openfile(io->out_stats_file,io->out_stats_file_open_mode); */
 
-#ifdef WIN32
 #ifdef EVOLVE
   if(Filexists("evolve_seq.txt"))
 #elif OPTIMIZ
@@ -345,15 +329,6 @@ void Launch_Interface_Input(option *io)
 #elif defined(PHYML) || defined(PART) || defined(PHYML_INSERT)
   if(Filexists(io->out_tree_file))
 #endif
-#elif UNIX
-#ifdef EVOLVE
-  if(Filexists("evolve_seq"))
-#elif OPTIMIZ
-  if(Filexists("optimiz_tree"))
-#elif defined(PHYML) || defined(PART) || defined(PHYML_INSERT)
-  if(Filexists(io->out_tree_file))
-#endif
-#endif
     {
       PhyML_Printf("\n");
 #ifdef EVOLVE
@@ -638,7 +613,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 "
@@ -799,7 +774,7 @@ void Launch_Interface_Model(option *io)
 	if(io->mod->whichmodel == CUSTOM)
 	  {
 	    rr_param = (char **)mCalloc(6,sizeof(char *));
-	    For(i,6) rr_param[i] = (char *)mCalloc(10,sizeof(char));
+	    for(i=0;i<6;i++) rr_param[i] = (char *)mCalloc(10,sizeof(char));
 	    rr = (char *)mCalloc(50,sizeof(char));
 
 	    mod = io->mod;
@@ -812,7 +787,7 @@ void Launch_Interface_Model(option *io)
 		Getstring_Stdin(io->mod->custom_mod_string->s);
 		if(strlen(io->mod->custom_mod_string->s) == 6)
 		  {
-		    For(i,6)
+		    for(i=0;i<6;i++)
 		      {
 			while(!isdigit((int)io->mod->custom_mod_string->s[i]))
 			  {
@@ -848,10 +823,10 @@ void Launch_Interface_Model(option *io)
 	    strcpy(rr_param[5],"G<->T");
 
 	    PhyML_Printf("\n. Set the relative rate values\n");
-	    For(i,mod->r_mat->n_diff_rr)
+	    for(i=0;i<mod->r_mat->n_diff_rr;i++)
 	      {
 		sprintf(rr,"\n. [");
-		For(j,6)
+		for(j=0;j<6;j++)
 		  {
 		    if(mod->r_mat->rr_num->v[j] == i) 
 		      {
@@ -880,7 +855,7 @@ void Launch_Interface_Model(option *io)
 		  }
 	      }
 
-	    For(i,6) Free(rr_param[i]);
+	    for(i=0;i<6;i++) Free(rr_param[i]);
 	    Free(rr_param);
 	    Free(rr);
 	  }
@@ -892,9 +867,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)
 		  {
@@ -904,7 +879,7 @@ void Launch_Interface_Model(option *io)
 		    int n_trial;
 		    
 		    bases = (char **)mCalloc(4,sizeof(char *));
-		    For(i,4) bases[i] = (char *)mCalloc(50,sizeof(char));
+		    for(i=0;i<4;i++) bases[i] = (char *)mCalloc(50,sizeof(char));
 		    bs = (char *)mCalloc(100,sizeof(char));
 		    
 		    strcpy(bases[0],". f(A)> ");
@@ -914,7 +889,7 @@ void Launch_Interface_Model(option *io)
 		    
 		    PhyML_Printf("\n. Set nucleotide frequencies \n");
 		    sum = .0;
-		    For(i,4)
+		    for(i=0;i<4;i++)
 		      {
 			PhyML_Printf("%s",bases[i]);
 			Getstring_Stdin(bs);
@@ -928,25 +903,25 @@ 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=0;i<4;i++) 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");
 		      }
 
-		    For(i,4) Free(bases[i]);
+		    for(i=0;i<4;i++) Free(bases[i]);
 		    Free(bases);
 		    Free(bs);
 		  }
@@ -1759,10 +1734,11 @@ void Launch_Interface_Branch_Support(option *io)
 		  io->print_boot_trees = 1;
 
 		  strcpy(io->out_boot_tree_file,io->in_align_file);
+
 		  strcat(io->out_boot_tree_file,"_phyml_boot_trees.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.txt");
 		  io->fp_out_boot_stats = Openfile(io->out_boot_stats_file,1);
 
@@ -1857,7 +1833,7 @@ void Launch_Interface_Multigene(option *io)
       io->st       = (supert_tree *)PART_Make_Supert_tree_Light(io);
       io->st->n_part = io->n_data_sets;
 
-      For(set,io->n_part)
+      for(set=0;set<io->n_part;set++)
 	{
 	  io->st->optionlist[set] = Make_Input();
 	  Set_Defaults_Input(io->st->optionlist[set]);
diff --git a/src/invitee.c b/src/invitee.c
index 2f49697..4bb3ffb 100644
--- a/src/invitee.c
+++ b/src/invitee.c
@@ -212,13 +212,7 @@ void PhyTime_XML(char *xml_file)
 
  ////////////////////////////////////////////////////////////////////////////
  ////////////////////////////////////////////////////////////////////////////
-  if(XML_Search_Attribute(n_r, "use_data") != NULL) 
-    {
-      if(XML_Search_Attribute(n_r, "use_data") -> value != NULL && (!strcmp(XML_Search_Attribute(n_r, "use_data") -> value, "YES")))
-        io -> mcmc -> use_data = YES;
-      if(XML_Search_Attribute(n_r, "use_data") -> value != NULL && (!strcmp(XML_Search_Attribute(n_r, "use_data") -> value, "NO")))
-        io -> mcmc -> use_data = NO;
-    }
+
 
   n_r = n_r -> child; 
   tree -> rates -> tot_num_cal = 0;
@@ -341,7 +335,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 +411,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 +439,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;
     }
@@ -681,7 +676,7 @@ void PhyTime_XML(char *xml_file)
 
   MCMC(tree);   
   PhyML_Printf("\n");
-  For(i,6) printf(" %d ", tree -> rates -> numb_calib_chosen[i]);
+  for(i=0;i<6;i++) printf(" %d ", tree -> rates -> numb_calib_chosen[i]);
   PhyML_Printf("\n");
                                        															
   MCMC_Close_MCMC(tree -> mcmc);																	
@@ -693,7 +688,7 @@ void PhyTime_XML(char *xml_file)
   Free_Tree_Pars(tree);
   Free_Tree_Lk(tree);
   Free_Tree(tree);
-  Free_Cseq(cdata);
+  Free_Calign(cdata);
   Free_Model(mod);
   if(io -> fp_in_align)   fclose(io -> fp_in_align);
   if(io -> fp_in_tree)    fclose(io -> fp_in_tree);
@@ -743,11 +738,6 @@ phydbl TIMES_Calib_Cond_Prob(t_tree *tree)
 
       constant = 0.0; 
       if(tot_num_comb > 1 && times_lk > -INFINITY && result != FALSE && tree->rates->update_time_norm_const == YES) 
-        {
-          tree -> rates -> node_height_dens_log_norm_const_update[i] = K_Constant_Prior_Times_Log(tree);
-          constant = tree -> rates -> node_height_dens_log_norm_const_update[i];
-        }
-      else constant = tree -> rates -> node_height_dens_log_norm_const_update[i];
  
       Yule_val[i] = constant + times_lk;
 
@@ -759,10 +749,10 @@ phydbl TIMES_Calib_Cond_Prob(t_tree *tree)
   times_tot_proba = 0.0;
   For(i, tot_num_comb)
     {
-      times_tot_proba += times_partial_proba[i] * EXP(Yule_val[i] + c);
+      times_tot_proba += times_partial_proba[i] * exp(Yule_val[i] + c);
     } 
 
-  ln_t = -c + LOG(times_tot_proba);
+  ln_t = -c + log(times_tot_proba);
 
   free(Yule_val);  
 
@@ -916,8 +906,8 @@ phydbl K_Constant_Prior_Times_Log(t_tree *tree)
           if(indic[i * (2 * n_otu - 3) + j] == 1) 
             {
               /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-              g_i_node[i * (2 * n_otu - 3) + j] =  (EXP(lmbd * t_slice_max[j]) - EXP(lmbd * t_slice_min[j])) / 
-                (EXP(lmbd * t_prior_max[i + n_otu]) - EXP(lmbd * t_prior_min[i + n_otu]));
+              g_i_node[i * (2 * n_otu - 3) + j] =  (exp(lmbd * t_slice_max[j]) - exp(lmbd * t_slice_min[j])) / 
+                (exp(lmbd * t_prior_max[i + n_otu]) - exp(lmbd * t_prior_min[i + n_otu]));
               /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
               slice_numbers[i * (2 * n_otu - 3) + k] = j;
               n_slice[i]++; 
@@ -1082,24 +1072,24 @@ phydbl K_Constant_Prior_Times_Log(t_tree *tree)
                   Number_Of_Nodes_In_Slice(tree -> a_nodes[root_nodes[j] + n_otu], tree -> a_nodes[root_nodes[j] + n_otu] -> v[1], &n_1, t_slice_min_f, t_slice_max_f, tree);
                   Number_Of_Nodes_In_Slice(tree -> a_nodes[root_nodes[j] + n_otu], tree -> a_nodes[root_nodes[j] + n_otu] -> v[2], &n_2, t_slice_min_f, t_slice_max_f, tree);
                   /* printf("\n. n_1 [%d] n_2 [%d]\n", n_1, n_2); */
-                  K_total_cur = K_total_cur + LOG(1) - LOG(n_1 + n_2 + 1) - LnGamma(n_1 + 1) - LnGamma(n_2 + 1);
+                  K_total_cur = K_total_cur + log(1) - log(n_1 + n_2 + 1) - LnGamma(n_1 + 1) - LnGamma(n_2 + 1);
                   /* printf("\n. K_total_cur [%f] \n", K_total_cur); */
-                  /* printf("\n. [START] LOG(m_i) [%f] \n", LOG(1) - LOG(n_1 + n_2 + 1) - LnGamma(n_1 + 1) - LnGamma(n_2 + 1)); */
+                  /* printf("\n. [START] log(m_i) [%f] \n", log(1) - log(n_1 + n_2 + 1) - LnGamma(n_1 + 1) - LnGamma(n_2 + 1)); */
                 }
-              /* printf("\n. [START] LOG(m_i) [%f] \n", K_total_cur); */
+              /* printf("\n. [START] log(m_i) [%f] \n", K_total_cur); */
               /* printf("\n. K_total_cur [%f] \n", K_total_cur); */
                   
               log_g_i = 0.0;
               For(i, n_otu - 2) 
-		  log_g_i += LOG_g_i(lmbd, 
+		  log_g_i += log_g_i(lmbd, 
 				t_slice_max_f[i], 
 				t_slice_min_f[i], 
 				t_prior_max[i + n_otu], 
 				MAX(t_prior_min[i + n_otu],tree->rates->nd_t[tree->n_root->num]));   
 
-       	      /* printf("\n. [START] LOG(g_i) [%f] \n", log_g_i); */
+       	      /* printf("\n. [START] log(g_i) [%f] \n", log_g_i); */
 
-              K_total_cur = EXP(K_total_cur + log_g_i + scl_const);
+              K_total_cur = exp(K_total_cur + log_g_i + scl_const);
 
               if(K_total_cur > max_K_val)
                 {
@@ -1224,10 +1214,10 @@ phydbl K_Constant_Prior_Times_Log(t_tree *tree)
                                   Number_Of_Nodes_In_Slice(tree -> a_nodes[root_nodes[j] + n_otu], tree -> a_nodes[root_nodes[j] + n_otu] -> v[2], &n_2, t_slice_min_f, t_slice_max_f, tree);
                                   /* printf("\n. n_1 [%d] n_2 [%d]\n", n_1, n_2); */
                                       
-                                  K_part = K_part + LOG(1) - LOG(n_1 + n_2 + 1) - LnGamma(n_1 + 1) - LnGamma(n_2 + 1);
-                                  /* printf("\n. [CONT] LOG(m_i) [%f] \n", LOG(1) - LOG(n_1 + n_2 + 1) - LnGamma(n_1 + 1) - LnGamma(n_2 + 1)); */
+                                  K_part = K_part + log(1) - log(n_1 + n_2 + 1) - LnGamma(n_1 + 1) - LnGamma(n_2 + 1);
+                                  /* printf("\n. [CONT] log(m_i) [%f] \n", log(1) - log(n_1 + n_2 + 1) - LnGamma(n_1 + 1) - LnGamma(n_2 + 1)); */
                                 }
-                              /* printf("\n. [CONT] LOG(m_i) [%f] \n", K_part); */
+                              /* printf("\n. [CONT] log(m_i) [%f] \n", K_part); */
                               /* printf("\n. K_part [%f] \n", K_part); */
                                   
                    
@@ -1240,15 +1230,15 @@ phydbl K_Constant_Prior_Times_Log(t_tree *tree)
                                   
                               log_g_i = 0.0;                                          
                               For(i, n_otu - 2) 
-				log_g_i += LOG_g_i(lmbd, 
+				log_g_i += log_g_i(lmbd, 
 					t_slice_max_f[i], 
 					t_slice_min_f[i], 
 					t_prior_max[i + n_otu], 
 					MAX(t_prior_min[i + n_otu],tree->rates->nd_t[tree->n_root->num]));
    
-                              /* printf("\n. [START] LOG(g_i) [%f] \n", log_g_i); */
+                              /* printf("\n. [START] log(g_i) [%f] \n", log_g_i); */
                               
-                              K_part = EXP(K_part + log_g_i + scl_const);
+                              K_part = exp(K_part + log_g_i + scl_const);
  
                               if(K_part > max_K_val)
                                 {
@@ -1375,22 +1365,22 @@ phydbl K_Constant_Prior_Times_Log(t_tree *tree)
                                   Number_Of_Nodes_In_Slice(tree -> a_nodes[root_nodes[j] + n_otu], tree -> a_nodes[root_nodes[j] + n_otu] -> v[2], &n_2, t_slice_min_f, t_slice_max_f, tree);
                                   /* printf("\n. n_1 [%d] n_2 [%d]\n", n_1, n_2); */
                                       
-                                  K_part = K_part + LOG(1) - LOG(n_1 + n_2 + 1) - LnGamma(n_1 + 1) - LnGamma(n_2 + 1);
-                                  /* printf("\n. [CONT] LOG(m_i) [%f] \n", LOG(1) - LOG(n_1 + n_2 + 1) - LnGamma(n_1 + 1) - LnGamma(n_2 + 1)); */
+                                  K_part = K_part + log(1) - log(n_1 + n_2 + 1) - LnGamma(n_1 + 1) - LnGamma(n_2 + 1);
+                                  /* printf("\n. [CONT] log(m_i) [%f] \n", log(1) - log(n_1 + n_2 + 1) - LnGamma(n_1 + 1) - LnGamma(n_2 + 1)); */
                                 }
-                              /* printf("\n. [CONT] LOG(m_i) [%f] \n", K_part); */
+                              /* printf("\n. [CONT] log(m_i) [%f] \n", K_part); */
                               /* printf("\n. K_part [%f] \n", K_part); */
                                   
                               log_g_i = 0.0;                                 
                               For(i, n_otu - 2) 
-				log_g_i += LOG_g_i(lmbd, 
+				log_g_i += log_g_i(lmbd, 
 					t_slice_max_f[i], 
 					t_slice_min_f[i], 
 					t_prior_max[i + n_otu], 
 					MAX(t_prior_min[i + n_otu],tree->rates->nd_t[tree->n_root->num]));   
-                              /* printf("\n. [START] LOG(g_i) [%f] \n", log_g_i); */
+                              /* printf("\n. [START] log(g_i) [%f] \n", log_g_i); */
                               
-                              K_part = EXP(K_part + log_g_i + scl_const);
+                              K_part = exp(K_part + log_g_i + scl_const);
 
                               if(K_part > max_K_val)
                                 {
@@ -1526,22 +1516,22 @@ phydbl K_Constant_Prior_Times_Log(t_tree *tree)
                               Number_Of_Nodes_In_Slice(tree -> a_nodes[root_nodes[j] + n_otu], tree -> a_nodes[root_nodes[j] + n_otu] -> v[2], &n_2, t_slice_min_f, t_slice_max_f, tree);
                               /* printf("\n. n_1 [%d] n_2 [%d]\n", n_1, n_2); */
                                       
-                              K_part = K_part + LOG(1) - LOG(n_1 + n_2 + 1) - LnGamma(n_1 + 1) - LnGamma(n_2 + 1);
-                              /* printf("\n. [CONT] LOG(m_i) [%f] \n", LOG(1) - LOG(n_1 + n_2 + 1) - LnGamma(n_1 + 1) - LnGamma(n_2 + 1)); */
+                              K_part = K_part + log(1) - log(n_1 + n_2 + 1) - LnGamma(n_1 + 1) - LnGamma(n_2 + 1);
+                              /* printf("\n. [CONT] log(m_i) [%f] \n", log(1) - log(n_1 + n_2 + 1) - LnGamma(n_1 + 1) - LnGamma(n_2 + 1)); */
                             }
-                          /* printf("\n. [CONT] LOG(m_i) [%f] \n", K_part); */
+                          /* printf("\n. [CONT] log(m_i) [%f] \n", K_part); */
                           /* printf("\n. K_part [%f] \n", K_part); */
                                   
                           log_g_i = 0.0;               
                           For(i, n_otu - 2) 
-				log_g_i += LOG_g_i(lmbd, 
+				log_g_i += log_g_i(lmbd, 
 					t_slice_max_f[i], 
 					t_slice_min_f[i], 
 					t_prior_max[i + n_otu], 
 					MAX(t_prior_min[i + n_otu],tree->rates->nd_t[tree->n_root->num]));   
-                          /* printf("\n. [START] LOG(g_i) [%f] \n", log_g_i); */
+                          /* printf("\n. [START] log(g_i) [%f] \n", log_g_i); */
                           
-                          K_part = EXP(K_part + log_g_i + scl_const);
+                          K_part = exp(K_part + log_g_i + scl_const);
 
                           if(K_part > max_K_val)
                             {
@@ -1578,8 +1568,8 @@ phydbl K_Constant_Prior_Times_Log(t_tree *tree)
   while(numb_unsuc < 100);
  
   /* printf("\n"); */
-  /* printf("\n. [APPROX TOTAL] LOG(K_total) = [%f] \n", LOG(K_total)); */
-  /* printf("\n. [APPROX TOTAL] LOG(Constant) = scl_const - LOG(K_total) = [%f] \n", scl_const - LOG(K_total)); */
+  /* printf("\n. [APPROX TOTAL] log(K_total) = [%f] \n", log(K_total)); */
+  /* printf("\n. [APPROX TOTAL] log(Constant) = scl_const - log(K_total) = [%f] \n", scl_const - log(K_total)); */
   /* printf("\n. [APPROX TOTAL] Approximated constant 1 / (K_total) = [%f] \n", 1 / (K_total)); */
   /* printf("\n ____________________________________________________________________________________________________ \n"); */
   /* printf("\n. [APPROX TOTAL] Numb_approx = [%d] \n", numb_approx); */
@@ -1613,7 +1603,7 @@ phydbl K_Constant_Prior_Times_Log(t_tree *tree)
   free(g_i_node);   
   free(K_val_approx); 
  
-  return(-LOG(K_total));
+  return(-log(K_total));
 }
 
 ////////////////////////////////////////////////////////////////////////////
@@ -1652,7 +1642,7 @@ void Check_Time_Slices(t_node *a, t_node *d, int *result, phydbl *t_cur_slice_mi
         }
 
       int i;
-      For(i,3) 
+      for(i=0;i<3;i++) 
 	if((d -> v[i] != d -> anc) && (d -> b[i] != tree -> e_root))
              Check_Time_Slices(d, d -> v[i], result, t_cur_slice_min, t_cur_slice_max, tree);
     }
@@ -1675,7 +1665,7 @@ void Number_Of_Nodes_In_Slice(t_node *d_start, t_node *d, int *n, phydbl *t_cur_
         {
           (*n)++; 
           int i;
-          For(i,3) 
+          for(i=0;i<3;i++) 
             if((d -> v[i] != d -> anc) && (d -> b[i] != tree -> e_root))
               Number_Of_Nodes_In_Slice(d_start, d -> v[i], n, t_cur_slice_min, t_cur_slice_max, tree);
         }      
@@ -1718,7 +1708,7 @@ void Search_Root_Node_In_Slice(t_node *d_start, t_node *d, int *root_nodes, int
             }
           
           int i;
-          For(i,3) 
+          for(i=0;i<3;i++) 
             if((d -> v[i] != d -> anc) && (d -> b[i] != tree -> e_root))
               Search_Root_Node_In_Slice(d, d -> v[i], root_nodes, num_elem, t_slice_min, t_slice_max, t_cur_slice_min, t_cur_slice_max, tree);
         }
@@ -1885,7 +1875,7 @@ void Check_Node_Time(t_node *a, t_node *d, int *result, t_tree *tree)
         }
 
       int i;
-      For(i,3) 
+      for(i=0;i<3;i++) 
 	if((d -> v[i] != d -> anc) && (d -> b[i] != tree -> e_root))
           Check_Node_Time(d, d -> v[i], result, tree);
     }
@@ -2113,10 +2103,10 @@ void Lk_Hastings_Ratio_Times(t_node *a, t_node *d, phydbl *tot_prob, t_tree *tre
       t_low = MAX(t_prior_min[d -> num], nd_t[d -> anc -> num]);
       t_up = MIN(t_prior_max[d -> num], MIN(nd_t[d -> v[1] -> num], nd_t[d -> v[2] -> num]));
 
-      (*tot_prob) += LOG(1) - LOG(t_up - t_low);
+      (*tot_prob) += log(1) - log(t_up - t_low);
 
       int i;
-      For(i,3) 
+      for(i=0;i<3;i++) 
 	if((d -> v[i] != d -> anc) && (d -> b[i] != tree -> e_root))
           { 
               Lk_Hastings_Ratio_Times(d, d -> v[i], tot_prob, tree);
@@ -2153,8 +2143,8 @@ void Update_Descendent_Cond_Jump(t_node *a, t_node *d, phydbl *L_Hast_ratio, t_t
         if(t_low < MIN(nd_t[d -> v[1] -> num], nd_t[d -> v[2] -> num])) t_up  = MIN(t_prior_max[d -> num], MIN(nd_t[d -> v[1] -> num], nd_t[d -> v[2] -> num])); 
         else t_up  = t_prior_max[d -> num]; 
         nd_t[d -> num] = Randomize_One_Node_Time(t_low, t_up);
-        (*L_Hast_ratio) += LOG(1) - LOG(t_up - t_low);
-        For(i,3) 
+        (*L_Hast_ratio) += log(1) - log(t_up - t_low);
+        for(i=0;i<3;i++) 
           if((d -> v[i] != d -> anc) && (d -> b[i] != tree -> e_root)) 
             Update_Descendent_Cond_Jump(d, d -> v[i], L_Hast_ratio, tree);
       }
@@ -2189,7 +2179,7 @@ void Update_Ancestor_Cond_Jump(t_node *d, phydbl *L_Hast_ratio, t_tree *tree)
           t_low = t_prior_min[d -> num];
           t_up  = MIN(t_prior_max[d -> num], MIN(nd_t[d -> v[1] -> num], nd_t[d -> v[2] -> num])); 
           nd_t[d -> num] = Randomize_One_Node_Time(t_low, t_up);
-          (*L_Hast_ratio) += LOG(1) - LOG(t_up - t_low);
+          (*L_Hast_ratio) += log(1) - log(t_up - t_low);
           return;
         }
       else
@@ -2198,7 +2188,7 @@ void Update_Ancestor_Cond_Jump(t_node *d, phydbl *L_Hast_ratio, t_tree *tree)
           if(nd_t[d -> anc -> num] > t_up) t_low =  t_prior_min[d -> num];
           else  t_low  = MAX(t_prior_min[d -> num], nd_t[d -> anc -> num]); 
           nd_t[d -> num] = Randomize_One_Node_Time(t_low, t_up);
-          (*L_Hast_ratio) += LOG(1) - LOG(t_up - t_low);
+          (*L_Hast_ratio) += log(1) - log(t_up - t_low);
           Update_Ancestor_Cond_Jump(d -> anc, L_Hast_ratio, tree); 
         }
       
@@ -2227,7 +2217,7 @@ void Update_Times_RND_Node_Ancestor_Descendant(int rnd_node, phydbl *L_Hast_rati
   nd_t[rnd_node] = new_time_rnd_node; 
 
   Update_Ancestor_Cond_Jump(tree -> a_nodes[rnd_node] -> anc, L_Hast_ratio, tree);
-  For(i,3) 
+  for(i=0;i<3;i++) 
     if((tree -> a_nodes[rnd_node] -> v[i] != tree -> a_nodes[rnd_node] -> anc) && (tree -> a_nodes[rnd_node] -> b[i] != tree -> e_root)) 
       Update_Descendent_Cond_Jump(tree -> a_nodes[rnd_node], tree -> a_nodes[rnd_node] -> v[i], L_Hast_ratio, tree);
  
@@ -2261,14 +2251,14 @@ void Update_Times_Down_Tree(t_node *a, t_node *d, phydbl *L_Hastings_ratio, t_tr
       if(nd_t[d -> num] > t_up || nd_t[d -> num] < t_low)
         { 
           //printf("\n. [2] Node number: [%d] \n", d -> num);
-          //(*L_Hastings_ratio) += (LOG(1) - LOG(t_up - t_low));
-          (*L_Hastings_ratio) += (- LOG(t_up - t_low));
+          //(*L_Hastings_ratio) += (log(1) - log(t_up - t_low));
+          (*L_Hastings_ratio) += (- log(t_up - t_low));
           nd_t[d -> num] = Randomize_One_Node_Time(t_low, t_up);
           /* t_prior_min[d -> num] = t_low;  */
           /* t_prior_max[d -> num] = t_up;   */
         }    
       
-      For(i,3) 
+      for(i=0;i<3;i++) 
         if((d -> v[i] != d -> anc) && (d -> b[i] != tree -> e_root)) 
           Update_Times_Down_Tree(d, d -> v[i], L_Hastings_ratio, tree);
     }
@@ -2317,65 +2307,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);
-}
-
 
 
 //////////////////////////////////////////////////////////////
@@ -2437,7 +2372,7 @@ void TIMES_Set_All_Node_Priors_Bottom_Up_S(t_node *a, t_node *d, int *result, t_
     {
       t_node *v1, *v2; /* the two sons of d */
 
-      For(i,3)
+      for(i=0;i<3;i++)
 	{
 	  if((d->v[i] != a) && (d->b[i] != tree->e_root))
 	    {
@@ -2446,7 +2381,7 @@ void TIMES_Set_All_Node_Priors_Bottom_Up_S(t_node *a, t_node *d, int *result, t_
 	}
       
       v1 = v2 = NULL;
-      For(i,3) if((d->v[i] != a) && (d->b[i] != tree->e_root)) 
+      for(i=0;i<3;i++) if((d->v[i] != a) && (d->b[i] != tree->e_root)) 
 	{
 	  if(!v1) v1 = d->v[i]; 
 	  else    v2 = d->v[i];
@@ -2505,7 +2440,7 @@ void TIMES_Set_All_Node_Priors_Top_Down_S(t_node *a, t_node *d, int *result, t_t
 	  tree->rates->t_prior_min[d->num] = tree->rates->t_prior_min[a->num];
 	}
             
-      For(i,3)
+      for(i=0;i<3;i++)
 	{
 	  if((d->v[i] != a) && (d->b[i] != tree->e_root))
 	    {
@@ -2518,7 +2453,7 @@ void TIMES_Set_All_Node_Priors_Top_Down_S(t_node *a, t_node *d, int *result, t_t
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-phydbl LOG_g_i(phydbl lmbd, phydbl t_slice_max, phydbl t_slice_min, phydbl t_prior_max, phydbl t_prior_min)
+phydbl log_g_i(phydbl lmbd, phydbl t_slice_max, phydbl t_slice_min, phydbl t_prior_max, phydbl t_prior_min)
 {
   phydbl result = 0.0;
 
@@ -2531,18 +2466,18 @@ phydbl LOG_g_i(phydbl lmbd, phydbl t_slice_max, phydbl t_slice_min, phydbl t_pri
       if(lmbd * t_prior_max + K > 700.0)
         {
           PhyML_Printf("\n. Please scale your calibration intervals. \n");
-          PhyML_Printf("\n. Cannot calculate EXP(-lmbd * t_prior_max). \n");
+          PhyML_Printf("\n. Cannot calculate exp(-lmbd * t_prior_max). \n");
           PhyML_Printf("\n. Err. in file %s at line %d\n\n",__FILE__,__LINE__);
           Warn_And_Exit("\n");
         }
       else
         {
-          result = LOG(EXP(lmbd * t_slice_max + K) - EXP(lmbd * t_slice_min + K)) - LOG(EXP(lmbd * t_prior_max + K) - EXP(lmbd * t_prior_min + K));
+          result = log(exp(lmbd * t_slice_max + K) - exp(lmbd * t_slice_min + K)) - log(exp(lmbd * t_prior_max + K) - exp(lmbd * t_prior_min + K));
         }
     }
   else 
     {
-      result = LOG(EXP(lmbd * t_slice_max) - EXP(lmbd * t_slice_min)) - LOG(EXP(lmbd * t_prior_max) - EXP(lmbd * t_prior_min));
+      result = log(exp(lmbd * t_slice_max) - exp(lmbd * t_slice_min)) - log(exp(lmbd * t_prior_max) - exp(lmbd * t_prior_min));
     }
   return(result);
 }
@@ -2603,7 +2538,7 @@ void Jump_Calibration_Move_Pre(t_node *a, t_node *d, phydbl old_ta, phydbl *log_
     {    
       if((nd_t[d -> num] > t_up_new || nd_t[d -> num] < t_low_new) || (move_anyway == YES)) /* Hastings ratio */
         {
-          (*log_hastings_ratio) += LOG(t_up_new - t_low_new + eps);
+          (*log_hastings_ratio) += log(t_up_new - t_low_new + eps);
         }
 
       if((nd_t[d -> num] > t_up_new || nd_t[d -> num] < t_low_new) || (move_anyway == YES)) /* Do the jump */
@@ -2614,11 +2549,11 @@ void Jump_Calibration_Move_Pre(t_node *a, t_node *d, phydbl old_ta, phydbl *log_
 
       if((nd_t[d -> num] > t_up_old || nd_t[d -> num] < t_low_old) || (move_anyway == YES)) /* Hastings ratio */
         {
-          (*log_hastings_ratio) -= LOG(t_up_old - t_low_old + eps);
+          (*log_hastings_ratio) -= log(t_up_old - t_low_old + eps);
         }
 
       
-      For(i,3) 
+      for(i=0;i<3;i++) 
         if((d -> v[i] != d -> anc) && (d -> b[i] != tree -> e_root)) 
           Jump_Calibration_Move_Pre(d, d -> v[i], old_t, log_hastings_ratio, tree);
     }
@@ -2647,9 +2582,9 @@ void Multiple_Time_Proposal_Density(t_node *a, t_node *d, phydbl *time_proposal_
       /* t_up  = MIN(t_prior_max[d -> num], MIN(nd_t[d -> v[1] -> num], nd_t[d -> v[2] -> num])); */
       /* printf("\n. Low [%f] Up [%f] \n", t_low, t_up); */
 
-      (*time_proposal_density) += (- LOG(t_up - t_low));
+      (*time_proposal_density) += (- log(t_up - t_low));
            
-      For(i,3) 
+      for(i=0;i<3;i++) 
         if((d -> v[i] != d -> anc) && (d -> b[i] != tree -> e_root)) 
           Multiple_Time_Proposal_Density(d, d -> v[i], time_proposal_density, tree);
     }
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..b8d02e4 100644
--- a/src/io.c
+++ b/src/io.c
@@ -64,13 +64,13 @@ t_tree *Read_Tree(char **s_tree)
       degree = 3;
       Free((*s_tree));
       len = 0;
-      For(i,degree) len += (strlen(subs[i])+1);
+      for(i=0;i<degree;i++) len += (strlen(subs[i])+1);
       len += 5;
       
       (*s_tree) = (char *)mCalloc(len,sizeof(char));
       
       (*s_tree)[0] = '('; (*s_tree)[1] = '\0';
-      For(i,degree)
+      for(i=0;i<degree;i++)
         {
           strcat((*s_tree),subs[i]);
           strcat((*s_tree),",\0");
@@ -78,7 +78,8 @@ t_tree *Read_Tree(char **s_tree)
       
       sprintf((*s_tree)+strlen((*s_tree))-1,"%s",");\0");
       
-      For(i,NODE_DEG_MAX) Free(subs[i]);
+      i = 0;
+      while(subs[i] != NULL) Free(subs[i++]);
       Free(subs);
       
       subs = Sub_Trees((*s_tree),&degree);
@@ -88,9 +89,10 @@ t_tree *Read_Tree(char **s_tree)
   
   tree->has_branch_lengths = 0;
   tree->num_curr_branch_available = 0;
-  For(i,degree) R_rtree((*s_tree),subs[i],root_node,tree,&n_int,&n_ext);
+  for(i=0;i<degree;i++) R_rtree((*s_tree),subs[i],root_node,tree,&n_int,&n_ext);
   
-  for(i=degree;i<NODE_DEG_MAX;i++) Free(subs[i]);
+  i = degree;
+  while(subs[i] != NULL) Free(subs[i++]);
   Free(subs);
   
   if(tree->n_root)
@@ -102,8 +104,8 @@ t_tree *Read_Tree(char **s_tree)
       
       tree->n_root->l[2] = tree->n_root->l[0];
       
-      For(i,3) if(tree->n_root->v[2]->v[i] == tree->n_root) { tree->n_root->v[2]->v[i] = tree->n_root->v[1]; break; }
-      For(i,3) if(tree->n_root->v[1]->v[i] == tree->n_root) { tree->n_root->v[1]->v[i] = tree->n_root->v[2]; break; }
+      for(i=0;i<3;i++) if(tree->n_root->v[2]->v[i] == tree->n_root) { tree->n_root->v[2]->v[i] = tree->n_root->v[1]; break; }
+      for(i=0;i<3;i++) if(tree->n_root->v[1]->v[i] == tree->n_root) { tree->n_root->v[1]->v[i] = tree->n_root->v[2]; break; }
       
       Connect_One_Edge_To_Two_Nodes(tree->n_root->v[2],
                                     tree->n_root->v[1],
@@ -159,7 +161,7 @@ void R_rtree(char *s_tree_a, char *s_tree_d, t_node *a, t_tree *tree, int *n_int
       Read_Branch_Label(s_tree_d,s_tree_a,tree->a_edges[tree->num_curr_branch_available]);
       Read_Branch_Length(s_tree_d,s_tree_a,tree);
 
-      For(i,3)
+      for(i=0;i<3;i++)
         {
           if(!a->v[i])
             {
@@ -191,13 +193,14 @@ void R_rtree(char *s_tree_a, char *s_tree_d, t_node *a, t_tree *tree, int *n_int
           strcat(s_tree_d,",");
           strcat(s_tree_d,subs[1]);
           strcat(s_tree_d,")");
-          For(i,b->n_labels)
+          for(i=0;i<b->n_labels;i++)
             {
               strcat(s_tree_d,"#");
               strcat(s_tree_d,b->labels[i]);
             }
 
-          For(i,NODE_DEG_MAX) Free(subs[i]);
+          i = 0;
+          while(subs[i] != NULL) Free(subs[i++]);
           Free(subs);
 
           subs=Sub_Trees(s_tree_d,&degree);
@@ -206,7 +209,8 @@ void R_rtree(char *s_tree_a, char *s_tree_d, t_node *a, t_tree *tree, int *n_int
       R_rtree(s_tree_d,subs[0],d,tree,n_int,n_ext);
       R_rtree(s_tree_d,subs[1],d,tree,n_int,n_ext);
 
-      for(i=2;i<NODE_DEG_MAX;i++) Free(subs[i]);
+      i = 2;
+      while(subs[i] != NULL) Free(subs[i++]);
       Free(subs);
     }
 
@@ -221,7 +225,7 @@ void R_rtree(char *s_tree_a, char *s_tree_d, t_node *a, t_tree *tree, int *n_int
       Read_Branch_Label(s_tree_d,s_tree_a,tree->a_edges[tree->num_curr_branch_available]);
       Read_Branch_Length(s_tree_d,s_tree_a,tree);
 
-      For(i,3)
+      for(i=0;i<3;i++)
         {
           if(!a->v[i])
             {
@@ -309,11 +313,11 @@ void Read_Branch_Label(char *s_d, char *s_a, t_edge *b)
   if(p)
     {
       /* if(b->n_labels == 1) */
-      /* 	PhyML_Printf("\n. Read label '%s' on t_edge %3d.",b->labels[0],b->num); */
+      /* 	PhyML_Printf("\n\u2022 Read label '%s' on t_edge %3d.",b->labels[0],b->num); */
       /* else */
       /* 	{ */
-      /* 	  PhyML_Printf("\n. Read labels "); */
-      /* 	  For(i,b->n_labels) PhyML_Printf("'%s' ",b->labels[i]); */
+      /* 	  PhyML_Printf("\n\u2022 Read labels "); */
+      /* 	  for(i=0;i<b->n_labels;i++) PhyML_Printf("'%s' ",b->labels[i]); */
       /* 	  PhyML_Printf("on t_edge %3d.",b->num); */
       /* 	} */
 
@@ -324,7 +328,7 @@ void Read_Branch_Label(char *s_d, char *s_a, t_edge *b)
     }
   /* else */
   /*   { */
-  /*     PhyML_Printf("\n. No label found on %s",s_d); */
+  /*     PhyML_Printf("\n\u2022 No label found on %s",s_d); */
   /*   } */
   Free(sub_tp);
 }
@@ -344,7 +348,7 @@ void Read_Branch_Length(char *s_d, char *s_a, t_tree *tree)
   /* sub_tp = (char *)mCalloc(T_MAX_LINE,sizeof(char)); */
   sub_tp = (char *)mCalloc(10+strlen(s_d)+1,sizeof(char));
 
-  For(i,b->n_labels)
+  for(i=0;i<b->n_labels;i++)
     {
       strcat(s_d,"#");
       strcat(s_d,b->labels[i]);
@@ -444,7 +448,6 @@ void Clean_Multifurcation(char **subtrees, int current_deg, int end_deg)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 char **Sub_Trees(char *tree, int *degree)
 {
   char **subs;
@@ -453,57 +456,58 @@ char **Sub_Trees(char *tree, int *degree)
 
   if(tree[0] != '(') {*degree = 1; return NULL;}
 
-  subs=(char **)mCalloc(NODE_DEG_MAX,sizeof(char *));
-
-  For(i,NODE_DEG_MAX) subs[i]=(char *)mCalloc(strlen(tree)+1,sizeof(char));
-
-
   posbeg=posend=1;
   (*degree)=0;
   do
     {
       posbeg = posend;
       if(tree[posend] != '(')
-    {
-      while((tree[posend] != ',' ) &&
-        (tree[posend] != ':' ) &&
-        (tree[posend] != '#' ) &&
-        (tree[posend] != ')' ))
         {
-          posend++ ;
+          while((tree[posend] != ',' ) &&
+                (tree[posend] != ':' ) &&
+                (tree[posend] != '#' ) &&
+                (tree[posend] != ')' ))
+            {
+              posend++ ;
+            }
+          posend -= 1;
         }
-      posend -= 1;
-    }
       else posend=Next_Par(tree,posend);
-
+      
       while((tree[posend+1] != ',') &&
-        (tree[posend+1] != ':') &&
-        (tree[posend+1] != '#') &&
-        (tree[posend+1] != ')')) {posend++;}
-
-
+            (tree[posend+1] != ':') &&
+            (tree[posend+1] != '#') &&
+            (tree[posend+1] != ')')) {posend++;}
+      
+      if(*degree == 0)
+        subs = (char **)mCalloc(1,sizeof(char *));
+      else
+        subs = (char **)mRealloc(subs,*degree+1,sizeof(char *));
+      
+      subs[(*degree)] = (char *)mCalloc(strlen(tree)+1,sizeof(char));
       strncpy(subs[(*degree)],tree+posbeg,posend-posbeg+1);
-/*       strcat(subs[(*degree)],"\0"); */
       subs[(*degree)][posend-posbeg+1]='\0'; /* Thanks to Jean-Baka Domelevo-Entfellner */
-
+      
       posend += 1;
       while((tree[posend] != ',') &&
-        (tree[posend] != ')')) {posend++;}
+            (tree[posend] != ')')) {posend++;}
       posend+=1;
-
-
+            
       (*degree)++;
       if((*degree) == NODE_DEG_MAX)
-    {
-      For(i,(*degree))
-        PhyML_Printf("\n. Subtree %d : %s\n",i+1,subs[i]);
-
-      PhyML_Printf("\n. The degree of a t_node cannot be greater than %d\n",NODE_DEG_MAX);
-      Warn_And_Exit("\n");
-    }
+        {
+          For(i,(*degree))
+            PhyML_Printf("\n\u2022 Subtree %d : %s\n",i+1,subs[i]);
+          
+          PhyML_Printf("\n\u2022 The degree of a t_node cannot be greater than %d\n",NODE_DEG_MAX);
+          Warn_And_Exit("\n");
+        }
     }
   while(tree[posend-1] != ')');
 
+  subs = (char **)mRealloc(subs,*degree+1,sizeof(char *));
+  subs[(*degree)] = NULL;
+
   return subs;
 }
 
@@ -543,7 +547,7 @@ void Print_Tree(FILE *fp, t_tree *tree)
       PhyML_Fprintf(fp,"#NEXUS\n");
       PhyML_Fprintf(fp,"BEGIN TREES;\n");
       PhyML_Fprintf(fp,"\tTRANSLATE\n");
-      For(i,tree->n_otu) PhyML_Fprintf(fp,"\t%3d\t%s,\n",i+1,tree->a_nodes[i]->name);
+      for(i=0;i<tree->n_otu;i++) PhyML_Fprintf(fp,"\t%3d\t%s,\n",i+1,tree->a_nodes[i]->name);
       PhyML_Fprintf(fp,"\tUTREE PAUP_1=\n");
       PhyML_Fprintf(fp,"%s\n",s_tree);
       PhyML_Fprintf(fp,"ENDBLOCK;");
@@ -568,12 +572,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]) ||
@@ -682,12 +685,9 @@ void R_wtree(t_node *pere, t_node *fils, int *available, char **s_tree, t_tree *
           (*s_tree)[(int)strlen(*s_tree)] = ':';
           
 #if !(defined PHYTIME || defined INVITEE)
-          if(!tree->n_root)
+          if(tree->n_root == NULL)
             {
-              if(tree->is_mixt_tree == NO)
-                {
-                  mean_len = fils->b[0]->l->v;
-                }
+              if(tree->is_mixt_tree == NO) mean_len = fils->b[0]->l->v;
               else mean_len = MIXT_Get_Mean_Edge_Len(fils->b[0],tree);
               sprintf(*s_tree+(int)strlen(*s_tree),format,MAX(0.0,mean_len));
             }
@@ -715,13 +715,14 @@ void R_wtree(t_node *pere, t_node *fils, int *available, char **s_tree, t_tree *
                 }
             }
 #else
-          if(!tree->n_root)
+          if(tree->n_root == NULL)
             {
               sprintf(*s_tree+(int)strlen(*s_tree),format,MAX(0.0,fils->b[0]->l->v));
             }
           else
             {
               if(tree->rates) sprintf(*s_tree+(int)strlen(*s_tree),format,MAX(0.0,tree->rates->cur_l[fils->num]));
+              /* sprintf(*s_tree+(int)strlen(*s_tree),format,MAX(0.0,fils->b[0]->l->v)); */
             }
 #endif
         }
@@ -750,7 +751,7 @@ void R_wtree(t_node *pere, t_node *fils, int *available, char **s_tree, t_tree *
           (*s_tree) = (char *)mRealloc(*s_tree,(int)strlen(*s_tree)+3*(int)T_MAX_NAME,sizeof(char));
           For(i,3*(int)T_MAX_NAME) (*s_tree)[(int)strlen(*s_tree)+i] = '\0';
           (*available) = 3*(int)T_MAX_NAME;
-          /* printf("\n. ++ 0 Available = %d",(*available)); */
+          /* printf("\n\u2022 ++ 0 Available = %d",(*available)); */
         }
 #endif
       
@@ -770,7 +771,7 @@ void R_wtree(t_node *pere, t_node *fils, int *available, char **s_tree, t_tree *
           (*s_tree) = (char *)mRealloc(*s_tree,(int)strlen(*s_tree)+3*(int)T_MAX_NAME,sizeof(char));
           For(i,3*(int)T_MAX_NAME) (*s_tree)[(int)strlen(*s_tree)+i] = '\0';
           (*available) = 3*(int)T_MAX_NAME;
-          /* printf("\n. ++ 1 Available = %d",(*available)); */
+          /* printf("\n\u2022 ++ 1 Available = %d",(*available)); */
         }
 #endif
       /* (*available)--; */
@@ -782,9 +783,9 @@ 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)
+          for(i=0;i<3;i++)
             {
               if((fils->v[i] != pere) && (fils->b[i] != tree->e_root))
                 R_wtree(fils,fils->v[i],available,s_tree,tree);
@@ -793,7 +794,7 @@ void R_wtree(t_node *pere, t_node *fils, int *available, char **s_tree, t_tree *
         }
       else
         {
-          For(i,3)
+          for(i=0;i<3;i++)
             {
               if(fils->v[i] != pere)
                 R_wtree(fils,fils->v[i],available,s_tree,tree);
@@ -824,7 +825,8 @@ void R_wtree(t_node *pere, t_node *fils, int *available, char **s_tree, t_tree *
             {
               sprintf(*s_tree+(int)strlen(*s_tree),"%f",fils->b[p]->ratio_test);
             }
-          
+
+
           fflush(NULL);
           
           (*s_tree)[(int)strlen(*s_tree)] = ':';
@@ -863,13 +865,14 @@ void R_wtree(t_node *pere, t_node *fils, int *available, char **s_tree, t_tree *
                 }
             }
 #else
-          if(!tree->n_root)
+          if(tree->n_root == NULL)
             {
               sprintf(*s_tree+(int)strlen(*s_tree),format,MAX(0.0,fils->b[p]->l->v));
             }
           else
             {
 	      if(tree->rates) sprintf(*s_tree+(int)strlen(*s_tree),format,MAX(0.0,tree->rates->cur_l[fils->num]));
+              /* sprintf(*s_tree+(int)strlen(*s_tree),format,MAX(0.0,fils->b[p]->l->v)); */
             }
 #endif
         }
@@ -893,9 +896,9 @@ void R_wtree(t_node *pere, t_node *fils, int *available, char **s_tree, t_tree *
       if(*available < (int)T_MAX_NAME)
         {
           (*s_tree) = (char *)mRealloc(*s_tree,(int)strlen(*s_tree)+3*(int)T_MAX_NAME,sizeof(char));
-      For(i,3*(int)T_MAX_NAME) (*s_tree)[(int)strlen(*s_tree)+i] = '\0';
+          For(i,3*(int)T_MAX_NAME) (*s_tree)[(int)strlen(*s_tree)+i] = '\0';
           (*available) = 3*(int)T_MAX_NAME;
-      /* printf("\n. ++ 2 Available = %d",(*available)); */
+      /* printf("\n\u2022 ++ 2 Available = %d",(*available)); */
         }
 #endif
 
@@ -1046,7 +1049,7 @@ void R_wtree_Custom(t_node *pere, t_node *fils, int *available, char **s_tree, i
 
       if(tree->n_root)
     {
-      For(i,3)
+      for(i=0;i<3;i++)
         {
           if((fils->v[i] != pere) && (fils->b[i] != tree->e_root))
         R_wtree_Custom(fils,fils->v[i],available,s_tree,pos,tree);
@@ -1055,7 +1058,7 @@ void R_wtree_Custom(t_node *pere, t_node *fils, int *available, char **s_tree, i
     }
       else
     {
-      For(i,3)
+      for(i=0;i<3;i++)
         {
           if(fils->v[i] != pere)
         R_wtree_Custom(fils,fils->v[i],available,s_tree,pos,tree);
@@ -1209,21 +1212,21 @@ void Detect_Tree_File_Format(option *io)
       if(errno)
     {
       io->tree_file_format = PHYLIP;
-      PhyML_Printf("\n. Detected PHYLIP tree file format.");
+      PhyML_Printf("\n\u2022 Detected PHYLIP tree file format.");
     }
       else if(c == '#')
     {
       char s[10],t[6]="NEXUS";
       if(!fgets(s,6,io->fp_in_tree))
         {
-          PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__);
+          PhyML_Printf("\n\u2022 Err in file %s at line %d\n",__FILE__,__LINE__);
           Warn_And_Exit("");
         }
       if(!strcmp(t,s))
         {
           fsetpos(io->fp_in_tree,&curr_pos);
           io->tree_file_format = NEXUS;
-          PhyML_Printf("\n. Detected NEXUS tree file format.");
+          PhyML_Printf("\n\u2022 Detected NEXUS tree file format.");
           return;
         }
     }
@@ -1292,9 +1295,9 @@ void Post_Process_Data(option *io)
   int i,j,swap;
   align *data_buff;
 
-  For(i,io->data[0]->len)
+  for(i=0;i<io->data[0]->len;++i)
     {
-      For(j,io->n_otu)
+      for(j=0;j<io->n_otu;++j)
         {
           if((io->data[j]->state[i] == '?') || (io->data[j]->state[i] == '-')) io->data[j]->state[i] = 'X';
           if((io->datatype == NT) && (io->data[j]->state[i] == 'N')) io->data[j]->state[i] = 'X';
@@ -1302,15 +1305,16 @@ void Post_Process_Data(option *io)
         }
     }
 
-  For(i,io->n_otu) io->data[i]->len = io->data[0]->len;
+  for(i=0;i<io->n_otu;++i) io->data[i]->len = io->data[0]->len;
 
   /* Sequences are ordered alphabetically */
   data_buff = NULL;
   swap = TRUE;
+  /* swap = FALSE; */
   while(swap == TRUE)
     {
       swap = FALSE;
-      For(i,io->n_otu-1)
+      for(i=0;i<io->n_otu-1;i++)
         {
           for(j=i+1;j<io->n_otu;j++)
             {
@@ -1354,7 +1358,7 @@ void Post_Process_Data(option *io)
 /* 	{	   */
 /* 	  Get_Token(&s,token);	   */
 
-/* /\* 	  PhyML_Printf("\n. Token: '%s' next_token=%d cur_token=%d",token,nxt_token_t,cur_token_t); *\/ */
+/* /\* 	  PhyML_Printf("\n\u2022 Token: '%s' next_token=%d cur_token=%d",token,nxt_token_t,cur_token_t); *\/ */
 
 /* 	  if(token[0] == '\0') break; */
 
@@ -1627,7 +1631,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);
 
@@ -1660,11 +1663,11 @@ void Read_Ntax_Len_Phylip(FILE *fp ,int *n_otu, int *n_tax)
           if(strcmp(line,"\n") && strcmp(line,"\r") && strcmp(line,"\t"))
             {
               sscanf(line,"%d",n_otu);
-              if(*n_otu <= 0) Warn_And_Exit("\n. The number of taxa cannot be negative.\n");
+              if(*n_otu <= 0) Warn_And_Exit("\n\u2022 The number of taxa cannot be negative.\n");
               
               if(!fscanf(fp,"%s",line)) Exit("\n");
               sscanf(line,"%d",n_tax);
-              if(*n_tax <= 0) Warn_And_Exit("\n. The sequence length cannot be negative.\n");
+              if(*n_tax <= 0) Warn_And_Exit("\n\u2022 The sequence length cannot be negative.\n");
               else readok = 1;
             }
         }
@@ -1693,7 +1696,8 @@ align **Read_Seq_Sequential(option *io)
   
   sprintf(format, "%%%ds", T_MAX_NAME);
 
-  For(i,io->n_otu)
+
+  for(i=0;i<io->n_otu;i++)
     {
       data[i]        = (align *)mCalloc(1,sizeof(align));
       data[i]->name  = (char *)mCalloc(T_MAX_NAME,sizeof(char));
@@ -1706,7 +1710,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)
         {
@@ -1716,7 +1720,7 @@ align **Read_Seq_Sequential(option *io)
         }
     }
 
-  For(i,io->n_otu) data[i]->state[data[i]->len] = '\0';
+  for(i=0;i<io->n_otu;i++) data[i]->state[data[i]->len] = '\0';
 
   Restrict_To_Coding_Position(data,io);
 
@@ -1747,7 +1751,7 @@ align **Read_Seq_Interleaved(option *io)
   sprintf(format, "%%%ds", T_MAX_NAME);
 
   end = 0;
-  For(i,io->n_otu)
+  for(i=0;i<io->n_otu;i++)
     {
       data[i]        = (align *)mCalloc(1,sizeof(align));
       data[i]->name  = (char *)mCalloc(T_MAX_NAME,sizeof(char));
@@ -1776,7 +1780,7 @@ align **Read_Seq_Interleaved(option *io)
   
   if(data[0]->len == io->init_len * io->state_len) end = 1;
 
-/*   if(end) printf("\n. finished yet '%c'\n",fgetc(io->fp_in_align)); */
+/*   if(end) printf("\n\u2022 finished yet '%c'\n",fgetc(io->fp_in_align)); */
   if(!end)
     {
       end = 0;
@@ -1794,11 +1798,11 @@ align **Read_Seq_Interleaved(option *io)
               Exit("");
             }
           
-          For(i,io->n_otu) if(data[i]->len != io->init_len * io->state_len) break;
+          for(i=0;i<io->n_otu;i++) if(data[i]->len != io->init_len * io->state_len) break;
           
           if(i == io->n_otu) break;
           
-          For(i,io->n_otu)
+          for(i=0;i<io->n_otu;i++)
             {
               /* Skip the taxon name, if any, in this interleaved block */
               fgetpos(io->fp_in_align,&curr_pos);
@@ -1830,9 +1834,9 @@ align **Read_Seq_Interleaved(option *io)
         }while(!end);
     }
   
-  For(i,io->n_otu) data[i]->state[data[i]->len] = '\0';
+  for(i=0;i<io->n_otu;i++) data[i]->state[data[i]->len] = '\0';
 
-  For(i,io->n_otu)
+  for(i=0;i<io->n_otu;i++)
     {
       if(data[i]->len != io->init_len * io->state_len)
         {
@@ -1863,7 +1867,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 +1875,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,11 +1903,11 @@ 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;
     }
 
-  /* printf("\n. Exit nchar: %d [%d]\n",nchar,c==EOF); */
+  /* printf("\n\u2022 Exit nchar: %d [%d]\n",nchar,c==EOF); */
   if(c == EOF) return 0;
   else return 1;
 }
@@ -1915,12 +1919,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);
 
@@ -1930,51 +1929,92 @@ t_tree *Read_Tree_File(option *io)
     {
     case PHYLIP:
       {
-    do
-      {
-        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);
-        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;
-        io->treelist->list_size++;
-      }while(io->tree);
-    break;
+        do
+          {
+            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\u2022 Reading tree %d",io->treelist->list_size+1);
+            io->treelist->tree[io->treelist->list_size] = io->tree;
+            io->treelist->list_size++;
+          }while(io->tree);
+        break;
       }
     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:
       {
-    PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__);
-    Warn_And_Exit("");
-    break;
+        PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__);
+        Warn_And_Exit("");
+        break;
       }
     }
-
+  
   if(!io->long_tax_names)
     {
       int i;
-
+      
       tree = io->treelist->tree[0];
-
+      
       io->long_tax_names  = (char **)mCalloc(tree->n_otu,sizeof(char *));
       io->short_tax_names = (char **)mCalloc(tree->n_otu,sizeof(char *));
+      
+      for(i=0;i<tree->n_otu;i++)
+        {
+          io->long_tax_names[i] = (char *)mCalloc(strlen(tree->a_nodes[i]->name)+1,sizeof(char));
+          io->short_tax_names[i] = (char *)mCalloc(strlen(tree->a_nodes[i]->name)+1,sizeof(char));
+          strcpy(io->long_tax_names[i],tree->a_nodes[i]->name);
+          strcpy(io->short_tax_names[i],tree->a_nodes[i]->name);
+        }
+    }
+  return NULL;
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+scalar_dbl *Read_Io_Weights(option *io)
+{
+  scalar_dbl *w,*ori,*prev = NULL;
+  double val;
+
+  assert(io->weight_file);
+  
+  io->fp_weight_file = Openfile(io->weight_file,READ);
 
-      For(i,tree->n_otu)
+  w = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl));
+  ori = w;
+
+  do
     {
-      io->long_tax_names[i] = (char *)mCalloc(strlen(tree->a_nodes[i]->name)+1,sizeof(char));
-      io->short_tax_names[i] = (char *)mCalloc(strlen(tree->a_nodes[i]->name)+1,sizeof(char));
-      strcpy(io->long_tax_names[i],tree->a_nodes[i]->name);
-      strcpy(io->short_tax_names[i],tree->a_nodes[i]->name);
+      if(fscanf(io->fp_weight_file,"%lf,",&val) == EOF) break;      
+      w->v = (phydbl)val;
+      w->next = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl));
+      prev = w;
+      w = w->next;
     }
+  while(1);
+
+  /* Remove the last allocated and empty element of the list */
+  if(prev !=NULL && prev->next != NULL)
+    {
+      Free(prev->next);
+      prev->next=NULL;
     }
-  return NULL;
+
+  fclose(io->fp_weight_file);
+  
+  return(ori);
 }
 
 //////////////////////////////////////////////////////////////
@@ -1989,7 +2029,7 @@ char *Return_Tree_String_Phylip(FILE *fp_input_tree)
 
   if(fp_input_tree == NULL)
     {
-      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("");
     }
 
@@ -2010,21 +2050,21 @@ char *Return_Tree_String_Phylip(FILE *fp_input_tree)
   for(;;)
     {
       if((c == ' ') || (c == '\n'))
-    {
-      c=fgetc(fp_input_tree);
-      if(c == EOF || c == ';') break;
-      else continue;
-    }
+        {
+          c=fgetc(fp_input_tree);
+          if(c == EOF || c == ';') break;
+          else continue;
+        }
 
       if(c == '[')
-    {
-      Skip_Comment(fp_input_tree);
-      c = fgetc(fp_input_tree);
-      if(c == EOF || c == ';') break;
-    }
-
+        {
+          Skip_Comment(fp_input_tree);
+          c = fgetc(fp_input_tree);
+          if(c == EOF || c == ';') break;
+        }
+      
       line = (char *)mRealloc(line,i+2,sizeof(char));
-
+      
       line[i]=c;
       i++;
       c=fgetc(fp_input_tree);
@@ -2034,8 +2074,7 @@ char *Return_Tree_String_Phylip(FILE *fp_input_tree)
       if(open>maxopen) maxopen = open;
     }
   line[i] = '\0';
-
-
+    
   /* if(maxopen == 1) return NULL; */
   return line;
 }
@@ -2063,10 +2102,10 @@ void Print_Site(calign *cdata, int num, int n_otu, char *sep, int stepsize, FILE
 {
   int i,j;
   PhyML_Fprintf(fp,"\n");
-  For(i,n_otu)
+  for(i=0;i<n_otu;i++)
     {
       PhyML_Fprintf(fp,"%20s ",cdata->c_seq[i]->name);
-      For(j,stepsize)
+      for(j=0;j<stepsize;j++)
         PhyML_Fprintf(fp,"%c",cdata->c_seq[i]->state[num+j]);
       PhyML_Fprintf(fp,"%s",sep);
     }
@@ -2120,7 +2159,7 @@ void Print_Site_Lk(t_tree *tree, FILE *fp)
       
       if(tree->mod->ras->n_catg > 1)
         {
-          For(catg,tree->mod->ras->n_catg)
+          for(catg=0;catg<tree->mod->ras->n_catg;catg++)
             {
               sprintf(s,"P*(D|M,rr[%d]=%5.4f)",catg+1,tree->mod->ras->gamma_rr->v[catg]);
               PhyML_Fprintf(fp,"%-23s",s);
@@ -2144,7 +2183,7 @@ void Print_Site_Lk(t_tree *tree, FILE *fp)
       
       Init_Ui_Tips(tree);
 
-      For(site,tree->data->init_len)
+      for(site=0;site<tree->data->init_len;site++)
         {
                     
           PhyML_Fprintf(fp,"%-12d",site+1);
@@ -2157,23 +2196,23 @@ void Print_Site_Lk(t_tree *tree, FILE *fp)
           
           if(tree->mod->ras->n_catg > 1)
             {
-              For(catg,tree->mod->ras->n_catg)
+              for(catg=0;catg<tree->mod->ras->n_catg;catg++)
                 {                  
-                  PhyML_Fprintf(fp,"%-23g",tree->unscaled_site_lk_cat[catg*tree->n_pattern + tree->data->sitepatt[site]]);
+                  PhyML_Fprintf(fp,"%-23g",tree->unscaled_site_lk_cat[tree->data->sitepatt[site]*tree->mod->ras->n_catg + catg]);
                 }
                   
               postmean = .0;
-              For(catg,tree->mod->ras->n_catg)
+              for(catg=0;catg<tree->mod->ras->n_catg;catg++)
                 postmean +=
                 tree->mod->ras->gamma_rr->v[catg] *
-                tree->unscaled_site_lk_cat[catg*tree->n_pattern + tree->data->sitepatt[site]] *
+                tree->unscaled_site_lk_cat[tree->data->sitepatt[site]*tree->mod->ras->n_catg + catg] *
                 tree->mod->ras->gamma_r_proba->v[catg];
 
               sum = .0;
-              For(catg,tree->mod->ras->n_catg)
+              for(catg=0;catg<tree->mod->ras->n_catg;catg++)
                 {
                   sum +=
-                    tree->unscaled_site_lk_cat[catg*tree->n_pattern + tree->data->sitepatt[site]] *
+                    tree->unscaled_site_lk_cat[tree->data->sitepatt[site]*tree->mod->ras->n_catg + catg] *
                     tree->mod->ras->gamma_r_proba->v[catg];
                 }
 
@@ -2200,8 +2239,8 @@ void Print_Site_Lk(t_tree *tree, FILE *fp)
     }
   else
     {
-      For(site,tree->data->init_len)
-        PhyML_Fprintf(fp,"%.2f\t",LOG(tree->cur_site_lk[tree->data->sitepatt[site]]));
+      for(site=0;site<tree->data->init_len;site++)
+        PhyML_Fprintf(fp,"%.2f\t",log(tree->cur_site_lk[tree->data->sitepatt[site]]));
       PhyML_Fprintf(fp,"\n");
     }
 }
@@ -2214,9 +2253,9 @@ void Print_Seq(FILE *fp, align **data, int n_otu)
   int i,j;
 
   PhyML_Fprintf(fp,"%d\t%d\n",n_otu,data[0]->len);
-  For(i,n_otu)
+  for(i=0;i<n_otu;i++)
     {
-      For(j,20)
+      for(j=0;j<20;j++)
         {
           if(j<(int)strlen(data[i]->name))
             fputc(data[i]->name[j],fp);
@@ -2234,18 +2273,17 @@ void Print_Seq(FILE *fp, align **data, int n_otu)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
-void Print_CSeq(FILE *fp, int compressed, calign *cdata)
+void Print_CSeq(FILE *fp, int compressed, calign *cdata, t_tree *tree)
 {
   int i,j;
   int n_otu;
 
   n_otu = cdata->n_otu;
-  if(cdata->format == 0)
+  if(cdata->format == PHYLIP)
     {
       PhyML_Fprintf(fp,"%d\t%d\n",n_otu,cdata->init_len);
     }
-  else
+  else if(cdata->format == NEXUS)
     {
       PhyML_Fprintf(fp,"#NEXUS\n");
       PhyML_Fprintf(fp,"begin data\n");
@@ -2253,46 +2291,87 @@ void Print_CSeq(FILE *fp, int compressed, calign *cdata)
       PhyML_Fprintf(fp,"format sequential datatype=dna;\n");
       PhyML_Fprintf(fp,"matrix\n");
     }
+  else
+    {
+      PhyML_Fprintf(fp,"This sample file is to be processed by IBDSim (http://www1.montpellier.inra.fr/CBGP/software/ibdsim/)");
+    }
 
-  For(i,n_otu)
+  if(cdata->format == PHYLIP || cdata->format == NEXUS)
     {
-      For(j,50)
-        {
-          if(j<(int)strlen(cdata->c_seq[i]->name))
-            fputc(cdata->c_seq[i]->name[j],fp);
-          else fputc(' ',fp);
-        }
-      
-      if(compressed == YES) /* Print out compressed sequences */
-        PhyML_Fprintf(fp,"%s",cdata->c_seq[i]->state);
-      else /* Print out uncompressed sequences */
+      for(i=0;i<n_otu;i++)
         {
-          For(j,cdata->init_len)
+          for(j=0;j<50;j++)
+            {
+              if(j<(int)strlen(cdata->c_seq[i]->name))
+                fputc(cdata->c_seq[i]->name[j],fp);
+              else fputc(' ',fp);
+            }
+          
+          if(compressed == YES) /* Print out compressed sequences */
+            PhyML_Fprintf(fp,"%s",cdata->c_seq[i]->state);
+          else /* Print out uncompressed sequences */
             {
-              PhyML_Fprintf(fp,"%c",cdata->c_seq[i]->state[cdata->sitepatt[j]]);
+              for(j=0;j<cdata->init_len;j++)
+                {
+                  PhyML_Fprintf(fp,"%c",cdata->c_seq[i]->state[cdata->sitepatt[j]]);
+                }
             }
+          PhyML_Fprintf(fp,"\n");
         }
       PhyML_Fprintf(fp,"\n");
+      
+      if(cdata->format == NEXUS)
+        {
+          PhyML_Fprintf(fp,";\n");
+          PhyML_Fprintf(fp,"END;\n");
+        }
     }
-  PhyML_Fprintf(fp,"\n");
-
-  if(cdata->format == 1)
+  else if(cdata->format == IBDSIM)
     {
-      PhyML_Fprintf(fp,";\n");
-      PhyML_Fprintf(fp,"END;\n");
+      for(i=0;i<cdata->init_len;i++) PhyML_Fprintf(fp,"\nlocus %6d",i);
+      for(i=0;i<n_otu;i++)
+        {
+          PhyML_Fprintf(fp,"\npop");
+          PhyML_Fprintf(fp,"%12f  %12f , ",
+                        tree->a_nodes[i]->coord->lonlat[0],
+                        tree->a_nodes[i]->coord->lonlat[1]);
+          for(j=0;j<cdata->init_len;j++)
+            {
+              switch(tree->a_nodes[i]->c_seq->state[j])
+                {
+                case 'A' :
+                  {
+                    PhyML_Fprintf(fp,"001 ");
+                    break;
+                  }
+                case 'C' :
+                  {
+                    PhyML_Fprintf(fp,"002 ");
+                    break;
+                  }
+                case 'G' :
+                  {
+                    PhyML_Fprintf(fp,"003 ");
+                    break;
+                  }
+                case 'T' :
+                  {
+                    PhyML_Fprintf(fp,"004 ");
+                    break;
+                  }
+                }
+            }   
+        }
     }
-
-
-/*   PhyML_Printf("\t"); */
-/*   For(j,cdata->crunch_len) */
-/*     PhyML_Printf("%.0f ",cdata->wght[j]); */
-/*   PhyML_Printf("\n"); */
+  /*   PhyML_Printf("\t"); */
+  /*   for(j=0;j<cdata->crunch_len;j++) */
+  /*     PhyML_Printf("%.0f ",cdata->wght[j]); */
+  /*   PhyML_Printf("\n"); */
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Print_CSeq_Select(FILE *fp, int compressed, calign *cdata, t_tree *tree)
 {
   int i,j;
@@ -2303,7 +2382,7 @@ void Print_CSeq_Select(FILE *fp, int compressed, calign *cdata, t_tree *tree)
 
   eps = 1.E-6;
   n_otu = 0;
-  For(i,cdata->n_otu)
+  for(i=0;i<cdata->n_otu;i++)
     if(tree->rates->nd_t[i] < tree->rates->time_slice_lims[slice] + eps)
       n_otu++;
 
@@ -2311,11 +2390,11 @@ void Print_CSeq_Select(FILE *fp, int compressed, calign *cdata, t_tree *tree)
 
   n_otu = cdata->n_otu;
 
-  For(i,n_otu)
+  for(i=0;i<n_otu;i++)
     {
       if(tree->rates->nd_t[i] < tree->rates->time_slice_lims[slice] + eps)
     {
-      For(j,50)
+      for(j=0;j<50;j++)
         {
           if(j<(int)strlen(cdata->c_seq[i]->name))
         fputc(cdata->c_seq[i]->name[j],fp);
@@ -2326,7 +2405,7 @@ void Print_CSeq_Select(FILE *fp, int compressed, calign *cdata, t_tree *tree)
         PhyML_Fprintf(fp,"%s",cdata->c_seq[i]->state);
       else /* Print out uncompressed sequences */
         {
-          For(j,cdata->init_len)
+          for(j=0;j<cdata->init_len;j++)
         {
           PhyML_Fprintf(fp,"%c",cdata->c_seq[i]->state[cdata->sitepatt[j]]);
         }
@@ -2343,7 +2422,7 @@ void Print_CSeq_Select(FILE *fp, int compressed, calign *cdata, t_tree *tree)
 
 
 /*   PhyML_Printf("\t"); */
-/*   For(j,cdata->crunch_len) */
+/*   for(j=0;j<cdata->crunch_len;j++) */
 /*     PhyML_Printf("%.0f ",cdata->wght[j]); */
 /*   PhyML_Printf("\n"); */
 }
@@ -2355,11 +2434,11 @@ void Print_Dist(matrix *mat)
 {
   int i,j;
 
-  For(i,mat->n_otu)
+  for(i=0;i<mat->n_otu;i++)
     {
       PhyML_Printf("%s ",mat->name[i]);
 
-      For(j,mat->n_otu)
+      for(j=0;j<mat->n_otu;j++)
     PhyML_Printf("%9.6f ",mat->dist[i][j]);
       PhyML_Printf("\n");
     }
@@ -2373,14 +2452,17 @@ void Print_Node(t_node *a, t_node *d, t_tree *tree)
   int i;
   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;",
+  for(i=0;i<3;i++) if(a->v[i] == d) {dir = i; break;}
+  PhyML_Printf("Node nums: %3d %3d  (dir:%3d) (a->anc:%3d) (d->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),
+               d->anc?d->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);
-  For(i,3) if(a->v[i] == d)
+  PhyML_Printf(" names = '%10s' '%10s' ; ",a->name,d->name);
+  for(i=0;i<3;i++) if(a->v[i] == d)
     {
       if(a->b[i])
         {
@@ -2395,7 +2477,7 @@ void Print_Node(t_node *a, t_node *d, t_tree *tree)
 
   if(d->tax) return;
   else
-    For(i,3)
+    for(i=0;i<3;i++)
       if(d->v[i] != a && d->b[i] != tree->e_root) Print_Node(d,d->v[i],tree);
 }
 
@@ -2408,14 +2490,14 @@ void Print_Node_Brief(t_node *a, t_node *d, t_tree *tree, FILE *fp)
   int dir;
 
   dir = -1;
-  For(i,3) if(a->v[i] == d) {dir = i; break;}
+  for(i=0;i<3;i++) if(a->v[i] == d) {dir = i; break;}
 
   PhyML_Fprintf(fp,"\n");
   PhyML_Fprintf(fp,"Node nums: %3d %3d  (dir:%3d)",
                a->num,d->num,dir);
 
   PhyML_Fprintf(fp,"\tnames = '%10s' '%10s' ; ",a->name,d->name);
-  For(i,3) if(a->v[i] == d)
+  for(i=0;i<3;i++) if(a->v[i] == d)
     {
       if(a->b[i])
         {
@@ -2429,7 +2511,7 @@ void Print_Node_Brief(t_node *a, t_node *d, t_tree *tree, FILE *fp)
 
   if(d->tax) return;
   else
-    For(i,3)
+    for(i=0;i<3;i++)
       if(d->v[i] != a && d->b[i] != tree->e_root) Print_Node_Brief(d,d->v[i],tree,fp);
 }
 
@@ -2440,79 +2522,79 @@ void Print_Model(t_mod *mod)
 {
   int i,j,k;
 
-  PhyML_Printf("\n. name=%s",mod->modelname->s);
-  PhyML_Printf("\n. string=%s",mod->custom_mod_string);
-  PhyML_Printf("\n. mod_num=%d",mod->mod_num);
-  PhyML_Printf("\n. ns=%d",mod->ns);
-  PhyML_Printf("\n. n_catg=%d",mod->ras->n_catg);
-  PhyML_Printf("\n. kappa=%f",mod->kappa->v);
-  PhyML_Printf("\n. alpha=%f",mod->ras->alpha->v);
-  PhyML_Printf("\n. lambda=%f",mod->lambda->v);
-  PhyML_Printf("\n. pinvar=%f",mod->ras->pinvar->v);
-  PhyML_Printf("\n. br_len_mult=%f",mod->br_len_mult->v);
-  PhyML_Printf("\n. whichmodel=%d",mod->whichmodel);
-  PhyML_Printf("\n. update_eigen=%d",mod->update_eigen);
-  PhyML_Printf("\n. bootstrap=%d",mod->bootstrap);
-  PhyML_Printf("\n. n_diff_rr=%d",mod->r_mat->n_diff_rr);
-  PhyML_Printf("\n. invar=%d",mod->ras->invar);
-  PhyML_Printf("\n. use_m4mod=%d",mod->use_m4mod);
-  PhyML_Printf("\n. gamma_median=%d",mod->ras->gamma_median);
-  PhyML_Printf("\n. state_len=%d",mod->io->state_len);
-  PhyML_Printf("\n. log_l=%d",mod->log_l);
-  PhyML_Printf("\n. l_min=%f",mod->l_min);
-  PhyML_Printf("\n. l_max=%f",mod->l_max);
-  PhyML_Printf("\n. free_mixt_rates=%d",mod->ras->free_mixt_rates);
-  PhyML_Printf("\n. gamma_mgf_bl=%d",mod->gamma_mgf_bl);
-
-  PhyML_Printf("\n. Pi\n");
-  For(i,mod->ns) PhyML_Printf(" %f ",mod->e_frq->pi->v[i]);
+  PhyML_Printf("\n\u2022 name=%s",mod->modelname->s);
+  PhyML_Printf("\n\u2022 string=%s",mod->custom_mod_string);
+  PhyML_Printf("\n\u2022 mod_num=%d",mod->mod_num);
+  PhyML_Printf("\n\u2022 ns=%d",mod->ns);
+  PhyML_Printf("\n\u2022 n_catg=%d",mod->ras->n_catg);
+  PhyML_Printf("\n\u2022 kappa=%f",mod->kappa->v);
+  PhyML_Printf("\n\u2022 alpha=%f",mod->ras->alpha->v);
+  PhyML_Printf("\n\u2022 lambda=%f",mod->lambda->v);
+  PhyML_Printf("\n\u2022 pinvar=%f",mod->ras->pinvar->v);
+  PhyML_Printf("\n\u2022 br_len_mult=%f",mod->br_len_mult->v);
+  PhyML_Printf("\n\u2022 whichmodel=%d",mod->whichmodel);
+  PhyML_Printf("\n\u2022 update_eigen=%d",mod->update_eigen);
+  PhyML_Printf("\n\u2022 bootstrap=%d",mod->bootstrap);
+  PhyML_Printf("\n\u2022 n_diff_rr=%d",mod->r_mat->n_diff_rr);
+  PhyML_Printf("\n\u2022 invar=%d",mod->ras->invar);
+  PhyML_Printf("\n\u2022 use_m4mod=%d",mod->use_m4mod);
+  PhyML_Printf("\n\u2022 gamma_median=%d",mod->ras->gamma_median);
+  PhyML_Printf("\n\u2022 state_len=%d",mod->io->state_len);
+  PhyML_Printf("\n\u2022 log_l=%d",mod->log_l);
+  PhyML_Printf("\n\u2022 l_min=%f",mod->l_min);
+  PhyML_Printf("\n\u2022 l_max=%f",mod->l_max);
+  PhyML_Printf("\n\u2022 free_mixt_rates=%d",mod->ras->free_mixt_rates);
+  PhyML_Printf("\n\u2022 gamma_mgf_bl=%d",mod->gamma_mgf_bl);
+
+  PhyML_Printf("\n\u2022 Pi\n");
+  for(i=0;i<mod->ns;i++) PhyML_Printf(" %f ",mod->e_frq->pi->v[i]);
   PhyML_Printf("\n");
-  For(i,mod->ns) PhyML_Printf(" %f ",mod->e_frq->pi_unscaled->v[i]);
+  for(i=0;i<mod->ns;i++) PhyML_Printf(" %f ",mod->e_frq->pi_unscaled->v[i]);
 
-  PhyML_Printf("\n. Rates\n");
-  For(i,mod->ras->n_catg) PhyML_Printf(" %f ",mod->ras->gamma_r_proba->v[i]);
+  PhyML_Printf("\n\u2022 Rates\n");
+  for(i=0;i<mod->ras->n_catg;i++) PhyML_Printf(" %f ",mod->ras->gamma_r_proba->v[i]);
   PhyML_Printf("\n");
-  For(i,mod->ras->n_catg) PhyML_Printf(" %f ",mod->ras->gamma_r_proba_unscaled->v[i]);
+  for(i=0;i<mod->ras->n_catg;i++) PhyML_Printf(" %f ",mod->ras->gamma_r_proba_unscaled->v[i]);
   PhyML_Printf("\n");
-  For(i,mod->ras->n_catg) PhyML_Printf(" %f ",mod->ras->gamma_rr->v[i]);
+  for(i=0;i<mod->ras->n_catg;i++) PhyML_Printf(" %f ",mod->ras->gamma_rr->v[i]);
   PhyML_Printf("\n");
-  For(i,mod->ras->n_catg) PhyML_Printf(" %f ",mod->ras->gamma_rr_unscaled->v[i]);
+  for(i=0;i<mod->ras->n_catg;i++) PhyML_Printf(" %f ",mod->ras->gamma_rr_unscaled->v[i]);
 
 
 
-  PhyML_Printf("\n. Qmat \n");
+  PhyML_Printf("\n\u2022 Qmat \n");
   if(mod->whichmodel == CUSTOM)
     {
       fflush(NULL);
-      For(i,6) {PhyML_Printf(" %12f ",mod->r_mat->rr->v[i]); fflush(NULL);}
-      For(i,6) {PhyML_Printf(" %12f ",mod->r_mat->rr_val->v[i]); fflush(NULL);}
-      For(i,6) {PhyML_Printf(" %12d ",mod->r_mat->rr_num->v[i]); fflush(NULL);}
-      For(i,6) {PhyML_Printf(" %12d ",mod->r_mat->n_rr_per_cat->v[i]); fflush(NULL);}
+      for(i=0;i<6;i++) {PhyML_Printf(" %12f ",mod->r_mat->rr->v[i]); fflush(NULL);}
+      for(i=0;i<6;i++) {PhyML_Printf(" %12f ",mod->r_mat->rr_val->v[i]); fflush(NULL);}
+      for(i=0;i<6;i++) {PhyML_Printf(" %12d ",mod->r_mat->rr_num->v[i]); fflush(NULL);}
+      for(i=0;i<6;i++) {PhyML_Printf(" %12d ",mod->r_mat->n_rr_per_cat->v[i]); fflush(NULL);}
     }
-  For(i,mod->ns)
+  for(i=0;i<mod->ns;i++)
     {
       PhyML_Printf("  ");
-      For(j,4)
+      for(j=0;j<4;j++)
         PhyML_Printf("%8.5f  ",mod->r_mat->qmat->v[i*4+j]);
       PhyML_Printf("\n");
     }
 
-  PhyML_Printf("\n. Freqs");
+  PhyML_Printf("\n\u2022 Freqs");
   PhyML_Printf("\n");
-  For(i,mod->ns) PhyML_Printf(" %12f ",mod->user_b_freq->v[i]);
+  for(i=0;i<mod->ns;i++) 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]);
+  for(i=0;i<mod->ns;i++) PhyML_Printf(" %12f ",mod->e_frq->pi->v[i]);
   PhyML_Printf("\n");
-  For(i,mod->ns) PhyML_Printf(" %12f ",mod->e_frq->pi_unscaled->v[i]);
+  for(i=0;i<mod->ns;i++) PhyML_Printf(" %12f ",mod->e_frq->pi_unscaled->v[i]);
 
-  PhyML_Printf("\n. Eigen\n");
+  PhyML_Printf("\n\u2022 Eigen\n");
   For(i,2*mod->ns)       PhyML_Printf(" %f ",mod->eigen->space[i]);
   PhyML_Printf("\n");
   For(i,2*mod->ns)       PhyML_Printf(" %f ",mod->eigen->space_int[i]);
   PhyML_Printf("\n");
-  For(i,mod->ns)         PhyML_Printf(" %f ",mod->eigen->e_val[i]);
+  for(i=0;i<mod->ns;i++)         PhyML_Printf(" %f ",mod->eigen->e_val[i]);
   PhyML_Printf("\n");
-  For(i,mod->ns)         PhyML_Printf(" %f ",mod->eigen->e_val_im[i]);
+  for(i=0;i<mod->ns;i++)         PhyML_Printf(" %f ",mod->eigen->e_val_im[i]);
   PhyML_Printf("\n");
   For(i,mod->ns*mod->ns) PhyML_Printf(" %f ",mod->eigen->r_e_vect[i]);
   PhyML_Printf("\n");
@@ -2523,15 +2605,15 @@ void Print_Model(t_mod *mod)
   For(i,mod->ns*mod->ns) PhyML_Printf(" %f ",mod->eigen->q[i]);
   PhyML_Printf("\n");
 
-  PhyML_Printf("\n. Pij");
-  For(k,mod->ras->n_catg)
+  PhyML_Printf("\n\u2022 Pij");
+  for(k=0;k<mod->ras->n_catg;k++)
     {
-      PMat(0.01*mod->ras->gamma_rr->v[k],mod,mod->ns*mod->ns*k,mod->Pij_rr->v);
-      PhyML_Printf("\n. l=%f\n",0.01*mod->ras->gamma_rr->v[k]);
-      For(i,mod->ns)
+      PMat(0.01*mod->ras->gamma_rr->v[k],mod,mod->ns*mod->ns*k,mod->Pij_rr->v,NULL);
+      PhyML_Printf("\n\u2022 l=%f\n",0.01*mod->ras->gamma_rr->v[k]);
+      for(i=0;i<mod->ns;i++)
         {
           PhyML_Printf("  ");
-          For(j,mod->ns)
+          for(j=0;j<mod->ns;j++)
             PhyML_Printf("%8.5f  ",mod->Pij_rr->v[k*mod->ns*mod->ns+i*mod->ns+j]);
           PhyML_Printf("\n");
         }
@@ -2551,23 +2633,23 @@ void Print_Mat(matrix *mat)
 
   PhyML_Printf("%d",mat->n_otu);
   PhyML_Printf("\n");
-
-  For(i,mat->n_otu)
-    {
-      For(j,13)
-    {
-      if(j>=(int)strlen(mat->name[i])) putchar(' ');
-      else putchar(mat->name[i][j]);
-    }
-
-      For(j,mat->n_otu)
+  
+  for(i=0;i<mat->n_otu;i++)
     {
-      char s[2]="-";
-      if(mat->dist[i][j] < .0)
-        PhyML_Printf("%12s",s);
-      else
-        PhyML_Printf("%12f",mat->dist[i][j]);
-    }
+      for(j=0;j<13;j++)
+        {
+          if(j>=(int)strlen(mat->name[i])) putchar(' ');
+          else putchar(mat->name[i][j]);
+        }
+      
+      for(j=0;j<mat->n_otu;j++)
+        {
+          char s[2]="-";
+          if(mat->dist[i][j] < .0)
+            PhyML_Printf("%12s",s);
+          else
+            PhyML_Printf("%12f",mat->dist[i][j]);
+        }
       PhyML_Printf("\n");
     }
 }
@@ -2577,42 +2659,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 :
+    case READ :
       {
-    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);
+        while(!(fp = (FILE *)fopen(s,"r")) && ++open_test<10)
+          {
+            PhyML_Printf("\n\u2022 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,29 +2712,27 @@ 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);
     }
 
-  PhyML_Fprintf(fp_out,"\n. Sequence filename: \t\t\t%s", Basename(io->in_align_file));
-  PhyML_Fprintf(fp_out,"\n. Data set: \t\t\t\t#%d",n_data_set);
+  PhyML_Fprintf(fp_out,"\n\u2022 Sequence filename: \t\t\t%s", Basename(io->in_align_file));
+  PhyML_Fprintf(fp_out,"\n\u2022 Data set: \t\t\t\t#%d",n_data_set);
 
-  if(io->mod->s_opt->random_input_tree) PhyML_Fprintf(fp_out,"\n. Random init tree: \t\t\t#%d",num_tree+1);
-  else if(io->n_trees > 1)              PhyML_Fprintf(fp_out,"\n. Starting tree number: \t\t#%d",num_tree+1);
+  if(io->mod->s_opt->random_input_tree) PhyML_Fprintf(fp_out,"\n\u2022 Random init tree: \t\t\t#%d",num_tree+1);
+  else if(io->n_trees > 1)              PhyML_Fprintf(fp_out,"\n\u2022 Starting tree number: \t\t#%d",num_tree+1);
 
   if(io->mod->s_opt->opt_topo)
     {
-      if(io->mod->s_opt->topo_search == NNI_MOVE) PhyML_Fprintf(fp_out,"\n. Tree topology search : \t\tNNIs");
-      else if(io->mod->s_opt->topo_search == SPR_MOVE) PhyML_Fprintf(fp_out,"\n. Tree topology search : \t\tSPRs");
-      else if(io->mod->s_opt->topo_search == BEST_OF_NNI_AND_SPR) PhyML_Fprintf(fp_out,"\n. Tree topology search : \t\tBest of NNIs and SPRs");
+      if(io->mod->s_opt->topo_search == NNI_MOVE) PhyML_Fprintf(fp_out,"\n\u2022 Tree topology search : \t\tNNIs");
+      else if(io->mod->s_opt->topo_search == SPR_MOVE) PhyML_Fprintf(fp_out,"\n\u2022 Tree topology search : \t\tSPRs");
+      else if(io->mod->s_opt->topo_search == BEST_OF_NNI_AND_SPR) PhyML_Fprintf(fp_out,"\n\u2022 Tree topology search : \t\tBest of NNIs and SPRs");
     }
   else
     {
-      PhyML_Fprintf(fp_out,"\n. Tree topology: \t\t\tfixed");
+      PhyML_Fprintf(fp_out,"\n\u2022 Tree topology: \t\t\tfixed");
     }
 
 
@@ -2668,56 +2745,52 @@ void Print_Fp_Out(FILE *fp_out, time_t t_beg, time_t t_end, t_tree *tree, option
   else
     {
       if(!io->mod->s_opt->random_input_tree)
-    {
-      if(io->in_tree == 0)
-        strcat(s,"BioNJ");
-      if(io->in_tree == 1)
-        strcat(s,"parsimony");
-    }
+        {
+          if(io->in_tree == 0) strcat(s,"BioNJ");
+          if(io->in_tree == 1) strcat(s,"parsimony");
+        }
       else
-    {
-      strcat(s,"random tree");
-    }
+        strcat(s,"random tree");
     }
 
-  PhyML_Fprintf(fp_out,"\n. Initial tree: \t\t\t%s",s);
+  PhyML_Fprintf(fp_out,"\n\u2022 Initial tree: \t\t\t%s",s);
   Free(s);
 
   if(tree->io->datatype == NT)
     {
-      PhyML_Fprintf(fp_out,"\n. Model of nucleotides substitution: \t%s",tree->mod->modelname->s);
+      PhyML_Fprintf(fp_out,"\n\u2022 Model of nucleotides substitution: \t%s",tree->mod->modelname->s);
       if(io->mod->whichmodel == CUSTOM)
       PhyML_Fprintf(fp_out," (%s)",io->mod->custom_mod_string);
     }
   else if(tree->io->datatype == AA)
     {
-      PhyML_Fprintf(fp_out,"\n. Model of amino acids substitution: \t%s",tree->mod->modelname->s);
+      PhyML_Fprintf(fp_out,"\n\u2022 Model of amino acids substitution: \t%s",tree->mod->modelname->s);
       if(io->mod->whichmodel == CUSTOMAA) PhyML_Fprintf(fp_out," (%s)",tree->mod->aa_rate_mat_file->s);
     }
   else
     {
-      fprintf(fp_out,"\n. Substitution model: \t\t\t%s",tree->mod->modelname->s);
+      fprintf(fp_out,"\n\u2022 Substitution model: \t\t\t%s",tree->mod->modelname->s);
     }
 
 
-  PhyML_Fprintf(fp_out,"\n. Number of taxa: \t\t\t%d",tree->n_otu);/*added FLT*/
+  PhyML_Fprintf(fp_out,"\n\u2022 Number of taxa: \t\t\t%d",tree->n_otu);/*added FLT*/
 
-  PhyML_Fprintf(fp_out,"\n. Log-likelihood: \t\t\t%.5f",tree->c_lnL);/*was last ; moved here FLT*/
+  PhyML_Fprintf(fp_out,"\n\u2022 Log-likelihood: \t\t\t%.5f",tree->c_lnL);/*was last ; moved here FLT*/
 
   Unconstraint_Lk(tree);
-  PhyML_Fprintf(fp_out,"\n. Unconstrained likelihood: \t\t%.5f",tree->unconstraint_lk);
+  PhyML_Fprintf(fp_out,"\n\u2022 Unconstrained likelihood: \t\t%.5f",tree->unconstraint_lk);
 
-  PhyML_Fprintf(fp_out,"\n. Parsimony: \t\t\t\t%d",tree->c_pars);
+  PhyML_Fprintf(fp_out,"\n\u2022 Parsimony: \t\t\t\t%d",tree->c_pars);
 
-  PhyML_Fprintf(fp_out,"\n. Tree size: \t\t\t\t%.5f",Get_Tree_Size(tree));
+  PhyML_Fprintf(fp_out,"\n\u2022 Tree size: \t\t\t\t%.5f",Get_Tree_Size(tree));
 
   /* if(tree->mod->ras->n_catg > 1 && tree->mod->ras->free_mixt_rates == NO) */
   if(tree->mod->ras->free_mixt_rates == NO)
     {
-      PhyML_Fprintf(fp_out,"\n. Discrete gamma model: \t\t%s","Yes");
+      PhyML_Fprintf(fp_out,"\n\u2022 Discrete gamma model: \t\t%s","Yes");
       PhyML_Fprintf(fp_out,"\n  - Number of classes: \t\t\t%d",tree->mod->ras->n_catg);
       PhyML_Fprintf(fp_out,"\n  - Gamma shape parameter: \t\t%.3f",tree->mod->ras->alpha->v);
-      For(i,tree->mod->ras->n_catg)
+      for(i=0;i<tree->mod->ras->n_catg;i++)
         {
           PhyML_Fprintf(fp_out,"\n  - Relative rate in class %d: \t\t%.5f [freq=%4f] \t\t",i+1,tree->mod->ras->gamma_rr->v[i],tree->mod->ras->gamma_r_proba->v[i]);
         }
@@ -2726,35 +2799,35 @@ void Print_Fp_Out(FILE *fp_out, time_t t_beg, time_t t_end, t_tree *tree, option
     {
       int *rk;
       rk = Ranks(tree->mod->ras->gamma_rr->v,tree->mod->ras->n_catg);
-      PhyML_Fprintf(fp_out,"\n. FreeRate model: \t\t\t%s","Yes");
+      PhyML_Fprintf(fp_out,"\n\u2022 FreeRate model: \t\t\t%s","Yes");
       PhyML_Fprintf(fp_out,"\n  - Number of classes: \t\t\t%d",tree->mod->ras->n_catg);
-      For(i,tree->mod->ras->n_catg)
+      for(i=0;i<tree->mod->ras->n_catg;i++)
         {
           PhyML_Fprintf(fp_out,"\n  - Relative rate in class %d: \t\t%.5f [freq=%4f] \t\t",i+1,tree->mod->ras->gamma_rr->v[rk[i]],tree->mod->ras->gamma_r_proba->v[rk[i]]);
         }
       Free(rk);
     }
 
-  if(tree->mod->ras->invar) PhyML_Fprintf(fp_out,"\n. Proportion of invariant: \t\t%.3f",tree->mod->ras->pinvar->v);
+  if(tree->mod->ras->invar) PhyML_Fprintf(fp_out,"\n\u2022 Proportion of invariant: \t\t%.3f",tree->mod->ras->pinvar->v);
 
-  if(tree->mod->gamma_mgf_bl == YES) PhyML_Fprintf(fp_out,"\n. Variance of branch lengths: \t\t%f",tree->mod->l_var_sigma);
+  if(tree->mod->gamma_mgf_bl == YES) PhyML_Fprintf(fp_out,"\n\u2022 Variance of branch lengths: \t\t%f",tree->mod->l_var_sigma);
 
   /*was before Discrete gamma model ; moved here FLT*/
   if((tree->mod->whichmodel == K80)   ||
      (tree->mod->whichmodel == HKY85) ||
      (tree->mod->whichmodel == F84))
-    PhyML_Fprintf(fp_out,"\n. Transition/transversion ratio: \t%.3f",tree->mod->kappa->v);
+    PhyML_Fprintf(fp_out,"\n\u2022 Transition/transversion ratio: \t%.3f",tree->mod->kappa->v);
   else if(tree->mod->whichmodel == TN93)
     {
-      PhyML_Fprintf(fp_out,"\n. Transition/transversion ratio for purines: \t\t%.3f",
+      PhyML_Fprintf(fp_out,"\n\u2022 Transition/transversion ratio for purines: \t\t%.3f",
             tree->mod->kappa->v*2.*tree->mod->lambda->v/(1.+tree->mod->lambda->v));
-      PhyML_Fprintf(fp_out,"\n. Transition/transversion ratio for pyrimidines: \t%.3f",
+      PhyML_Fprintf(fp_out,"\n\u2022 Transition/transversion ratio for pyrimidines: \t%.3f",
           tree->mod->kappa->v*2./(1.+tree->mod->lambda->v));
     }
 
   if(tree->io->datatype == NT)
     {
-      PhyML_Fprintf(fp_out,"\n. Nucleotides frequencies:");
+      PhyML_Fprintf(fp_out,"\n\u2022 Nucleotides frequencies:");
       PhyML_Fprintf(fp_out,"\n  - f(A)=%8.5f",tree->mod->e_frq->pi->v[0]);
       PhyML_Fprintf(fp_out,"\n  - f(C)=%8.5f",tree->mod->e_frq->pi->v[1]);
       PhyML_Fprintf(fp_out,"\n  - f(G)=%8.5f",tree->mod->e_frq->pi->v[2]);
@@ -2783,12 +2856,12 @@ void Print_Fp_Out(FILE *fp_out, time_t t_beg, time_t t_end, t_tree *tree, option
       PhyML_Fprintf(fp_out,"  G <-> T   %8.5f\n",tree->mod->r_mat->rr->v[5]);
 
 
-      PhyML_Fprintf(fp_out,"\n. Instantaneous rate matrix : ");
+      PhyML_Fprintf(fp_out,"\n\u2022 Instantaneous rate matrix : ");
       PhyML_Fprintf(fp_out,"\n  [A---------C---------G---------T------]\n");
-      For(i,4)
+      for(i=0;i<4;i++)
     {
       PhyML_Fprintf(fp_out,"  ");
-      For(j,4)
+      for(j=0;j<4;j++)
         PhyML_Fprintf(fp_out,"%8.5f  ",tree->mod->r_mat->qmat->v[i*4+j]);
       PhyML_Fprintf(fp_out,"\n");
     }
@@ -2808,17 +2881,17 @@ void Print_Fp_Out(FILE *fp_out, time_t t_beg, time_t t_end, t_tree *tree, option
 
 
   PhyML_Fprintf(fp_out,"\n");
-  PhyML_Fprintf(fp_out,"\n. Run ID:\t\t\t\t%s", (io->append_run_ID) ? (io->run_id_string): ("none"));
-  PhyML_Fprintf(fp_out,"\n. Random seed:\t\t\t\t%d", io->r_seed);
-  PhyML_Fprintf(fp_out,"\n. Subtree patterns aliasing:\t\t%s",io->do_alias_subpatt?"yes":"no");
-  PhyML_Fprintf(fp_out,"\n. Version:\t\t\t\t%s", VERSION);
+  PhyML_Fprintf(fp_out,"\n\u2022 Run ID:\t\t\t\t%s", (io->append_run_ID) ? (io->run_id_string): ("none"));
+  PhyML_Fprintf(fp_out,"\n\u2022 Random seed:\t\t\t\t%d", io->r_seed);
+  PhyML_Fprintf(fp_out,"\n\u2022 Subtree patterns aliasing:\t\t%s",io->do_alias_subpatt?"yes":"no");
+  PhyML_Fprintf(fp_out,"\n\u2022 Version:\t\t\t\t%s", VERSION);
 
   hour = div(t_end-t_beg,3600);
   min  = div(t_end-t_beg,60  );
 
   min.quot -= hour.quot*60;
 
-  PhyML_Fprintf(fp_out,"\n. Time used:\t\t\t\t%dh%dm%ds (%d seconds)", hour.quot,min.quot,(int)(t_end-t_beg)%60,(int)(t_end-t_beg));
+  PhyML_Fprintf(fp_out,"\n\u2022 Time used:\t\t\t\t%dh%dm%ds (%d seconds)", hour.quot,min.quot,(int)(t_end-t_beg)%60,(int)(t_end-t_beg));
 
 
   if(add_citation == YES)
@@ -3007,7 +3080,7 @@ void Print_Fp_Out_Lines(FILE *fp_out, time_t t_beg, time_t t_end, t_tree *tree,
     {
       int i,j;
 
-      For(i,4)
+      for(i=0;i<4;i++)
     {
       if (i!=0) {
         /*format*/
@@ -3015,7 +3088,7 @@ void Print_Fp_Out_Lines(FILE *fp_out, time_t t_beg, time_t t_end, t_tree *tree,
         if(tree->mod->ras->n_catg > 1) PhyML_Fprintf(fp_out,"          \t           \t");
         PhyML_Fprintf(fp_out,"             \t                                      \t");
       }
-      For(j,4)
+      for(j=0;j<4;j++)
         PhyML_Fprintf(fp_out,"%8.5f  ",tree->mod->r_mat->qmat->v[i*4+j]);
       if (i<3) PhyML_Fprintf(fp_out,"\n");
     }
@@ -3099,41 +3172,43 @@ void Print_Settings(option *io)
   PhyML_Printf("\n\n\n");
   PhyML_Printf("\n\n");
 
-  PhyML_Printf("                                 ..........................                                      \n");
-  PhyML_Printf(" ooooooooooooooooooooooooooooo        CURRENT SETTINGS        ooooooooooooooooooooooooooooooooooo\n");
-  PhyML_Printf("                                 ..........................                                      \n");
+  PhyML_Printf("\t\t\t\u205C\t SETTINGS \t\u205C  \n\n");
 
-  PhyML_Printf("\n                . Sequence filename:\t\t\t\t %s", Basename(io->in_align_file));
+  /* PhyML_Printf("                                 ..........................                                      \n"); */
+  /* PhyML_Printf(" ooooooooooooooooooooooooooooo        CURRENT SETTINGS        ooooooooooooooooooooooooooooooooooo\n"); */
+  /* PhyML_Printf("                         ..........................                      \n"); */
+
+  PhyML_Printf("\n        \u2023 Sequence filename:\t\t\t\t %s", Basename(io->in_align_file));
 
   if(io->datatype == NT) strcpy(s,"dna");
   else if(io->datatype == AA) strcpy(s,"aa");
   else strcpy(s,"generic");
 
-  PhyML_Printf("\n                . Data type:\t\t\t\t\t %s",s);
-  PhyML_Printf("\n                . Alphabet size:\t\t\t\t %d",io->mod->ns);
+  PhyML_Printf("\n        \u2023 Data type:\t\t\t\t\t %s",s);
+  PhyML_Printf("\n        \u2023 Alphabet size:\t\t\t\t %d",io->mod->ns);
 
-  PhyML_Printf("\n                . Sequence format:\t\t\t\t %s", io->interleaved ? "interleaved": "sequential");
-  PhyML_Printf("\n                . Number of data sets:\t\t\t\t %d", io->n_data_sets);
+  PhyML_Printf("\n        \u2023 Sequence format:\t\t\t\t %s", io->interleaved ? "interleaved": "sequential");
+  PhyML_Printf("\n        \u2023 Number of data sets:\t\t\t\t %d", io->n_data_sets);
 
-  PhyML_Printf("\n                . Nb of bootstrapped data sets:\t\t\t %d", io->mod->bootstrap);
+  PhyML_Printf("\n        \u2023 Nb of bootstrapped data sets:\t\t\t %d", io->mod->bootstrap);
 
   if (io->mod->bootstrap > 0)
-    PhyML_Printf("\n                . Compute approximate likelihood ratio test:\t no");
+    PhyML_Printf("\n        \u2023 Compute approximate likelihood ratio test:\t no");
   else
     {
       if(io->ratio_test == 1)
-    PhyML_Printf("\n                . Compute approximate likelihood ratio test:\t yes (aLRT statistics)");
+    PhyML_Printf("\n        \u2023 Compute approximate likelihood ratio test:\t yes (aLRT statistics)");
       else if(io->ratio_test == 2)
-    PhyML_Printf("\n                . Compute approximate likelihood ratio test:\t yes (Chi2-based parametric branch supports)");
+    PhyML_Printf("\n        \u2023 Compute approximate likelihood ratio test:\t yes (Chi2-based parametric branch supports)");
       else if(io->ratio_test == 3)
-    PhyML_Printf("\n                . Compute approximate likelihood ratio test:\t yes (Minimum of SH-like and Chi2-based branch supports)");
+    PhyML_Printf("\n        \u2023 Compute approximate likelihood ratio test:\t yes (Minimum of SH-like and Chi2-based branch supports)");
       else if(io->ratio_test == 4)
-    PhyML_Printf("\n                . Compute approximate likelihood ratio test:\t yes (SH-like branch supports)");
+    PhyML_Printf("\n        \u2023 Compute approximate likelihood ratio test:\t yes (SH-like branch supports)");
       else if(io->ratio_test == 5)
-    PhyML_Printf("\n                . Compute approximate likelihood ratio test:\t yes (aBayes branch supports)");
+    PhyML_Printf("\n        \u2023 Compute approximate likelihood ratio test:\t yes (aBayes branch supports)");
     }
 
-  PhyML_Printf("\n                . Model name:\t\t\t\t\t %s", io->mod->modelname->s);
+  PhyML_Printf("\n        \u2023 Model name:\t\t\t\t\t %s", io->mod->modelname->s);
 
   if(io->datatype == AA && io->mod->whichmodel == CUSTOMAA) PhyML_Printf(" (%s)",io->mod->aa_rate_mat_file->s);
 
@@ -3145,52 +3220,52 @@ void Print_Settings(option *io)
           (io->mod->whichmodel == TN93))
         {
           if(io->mod->s_opt && io->mod->s_opt->opt_kappa)
-            PhyML_Printf("\n                . Ts/tv ratio:\t\t\t\t\t estimated");
+            PhyML_Printf("\n        \u2023 Ts/tv ratio:\t\t\t\t\t estimated");
           else
-            PhyML_Printf("\n                . Ts/tv ratio:\t\t\t\t\t %f", io->mod->kappa->v);
+            PhyML_Printf("\n        \u2023 Ts/tv ratio:\t\t\t\t\t %f", io->mod->kappa->v);
         }
     }
 
   if(io->mod->s_opt && io->mod->s_opt->opt_pinvar)
-    PhyML_Printf("\n                . Proportion of invariable sites:\t\t estimated");
+    PhyML_Printf("\n        \u2023 Proportion of invariable sites:\t\t estimated");
   else
-    PhyML_Printf("\n                . Proportion of invariable sites:\t\t %f", io->mod->ras->pinvar->v);
+    PhyML_Printf("\n        \u2023 Proportion of invariable sites:\t\t %f", io->mod->ras->pinvar->v);
 
 
-  PhyML_Printf("\n                . Number of subst. rate categs:\t\t\t %d", io->mod->ras->n_catg);
+  PhyML_Printf("\n        \u2023 Number of subst. rate catgs:\t\t\t %d", io->mod->ras->n_catg);
   if(io->mod->ras->n_catg > 1)
     {
       if(io->mod->ras->free_mixt_rates == NO)
         {
           if(io->mod->s_opt && io->mod->s_opt->opt_alpha)
-            PhyML_Printf("\n                . Gamma distribution parameter:\t\t\t estimated");
+            PhyML_Printf("\n        \u2023 Gamma distribution parameter:\t\t\t estimated");
           else
-            PhyML_Printf("\n                . Gamma distribution parameter:\t\t\t %f", io->mod->ras->alpha->v);
-          PhyML_Printf("\n                . 'Middle' of each rate class:\t\t\t %s",(io->mod->ras->gamma_median)?("median"):("mean"));
+            PhyML_Printf("\n        \u2023 Gamma distribution parameter:\t\t\t %f", io->mod->ras->alpha->v);
+          PhyML_Printf("\n        \u2023 'Middle' of each rate class:\t\t\t %s",(io->mod->ras->gamma_median)?("median"):("mean"));
         }
     }
   
   
   if(io->datatype == AA)
-    PhyML_Printf("\n                . Amino acid equilibrium frequencies:\t\t %s", (io->mod->s_opt->opt_state_freq) ? ("empirical"):("model"));
+    PhyML_Printf("\n        \u2023 Amino acid equilibrium frequencies:\t\t %s", (io->mod->s_opt->opt_state_freq) ? ("empirical"):("model"));
   else if(io->datatype == NT)
     {
       if((io->mod->whichmodel != JC69) &&
          (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"));
+              PhyML_Printf("\n        \u2023 Nucleotide equilibrium frequencies:\t\t %s", (io->mod->s_opt->opt_state_freq) ? ("ML"):("empirical"));
             }
           else
             {
-              PhyML_Printf("\n                . Nucleotide equilibrium frequencies:\t\t %s","user-defined");
+              PhyML_Printf("\n        \u2023 Nucleotide equilibrium frequencies:\t\t %s","user-defined");
             }
         }
     }
   
-  PhyML_Printf("\n                . Optimise tree topology:\t\t\t %s", (io->mod->s_opt && io->mod->s_opt->opt_topo) ? "yes": "no");
+  PhyML_Printf("\n        \u2023 Optimise tree topology:\t\t\t %s", (io->mod->s_opt && io->mod->s_opt->opt_topo) ? "yes": "no");
   
   switch(io->in_tree)
     {
@@ -3203,21 +3278,21 @@ void Print_Settings(option *io)
   
   if(io->mod->s_opt && io->mod->s_opt->opt_topo)
     {
-      if(io->mod->s_opt->topo_search == NNI_MOVE) PhyML_Printf("\n                . Tree topology search:\t\t\t\t NNIs");
-      else if(io->mod->s_opt->topo_search == SPR_MOVE) PhyML_Printf("\n                . Tree topology search:\t\t\t\t SPRs");
-      else if(io->mod->s_opt->topo_search == BEST_OF_NNI_AND_SPR) PhyML_Printf("\n                . Tree topology search:\t\t\t\t Best of NNIs and SPRs");
+      if(io->mod->s_opt->topo_search == NNI_MOVE) PhyML_Printf("\n        \u2023 Tree topology search:\t\t\t\t NNIs");
+      else if(io->mod->s_opt->topo_search == SPR_MOVE) PhyML_Printf("\n        \u2023 Tree topology search:\t\t\t\t SPRs");
+      else if(io->mod->s_opt->topo_search == BEST_OF_NNI_AND_SPR) PhyML_Printf("\n        \u2023 Tree topology search:\t\t\t\t Best of NNIs and SPRs");
       
-      PhyML_Printf("\n                . Starting tree:\t\t\t\t %s",s);
+      PhyML_Printf("\n        \u2023 Starting tree:\t\t\t\t %s",s);
 
-      PhyML_Printf("\n                . Add random input tree:\t\t\t %s", (io->mod->s_opt->random_input_tree) ? "yes": "no");
+      PhyML_Printf("\n        \u2023 Add random input tree:\t\t\t %s", (io->mod->s_opt->random_input_tree) ? "yes": "no");
       if(io->mod->s_opt->random_input_tree)
-    PhyML_Printf("\n                . Number of random starting trees:\t\t %d", io->mod->s_opt->n_rand_starts);
+    PhyML_Printf("\n        \u2023 Number of random starting trees:\t\t %d", io->mod->s_opt->n_rand_starts);
     }
   else
     if(io->mod->s_opt && !io->mod->s_opt->random_input_tree)
-      PhyML_Printf("\n                . Evaluated tree:\t\t\t\t \"%s\"",s);
+      PhyML_Printf("\n        \u2023 Evaluated tree:\t\t\t\t \"%s\"",s);
 
-  PhyML_Printf("\n                . Optimise branch lengths:\t\t\t %s", (io->mod->s_opt && io->mod->s_opt->opt_bl) ? "yes": "no");
+  PhyML_Printf("\n        \u2023 Optimise branch lengths:\t\t\t %s", (io->mod->s_opt && io->mod->s_opt->opt_bl) ? "yes": "no");
 
   answer = 0;
   if(io->mod->s_opt &&
@@ -3227,15 +3302,30 @@ void Print_Settings(option *io)
       io->mod->s_opt->opt_pinvar ||
       io->mod->s_opt->opt_rr)) answer = 1;
 
-  PhyML_Printf("\n                . Optimise substitution model parameters:\t %s", (answer) ? "yes": "no");
+  PhyML_Printf("\n        \u2023 Optimise substitution model parameters:\t %s", (answer) ? "yes": "no");
 
-  PhyML_Printf("\n                . Run ID:\t\t\t\t\t %s", (io->append_run_ID) ? (io->run_id_string): ("none"));
-  PhyML_Printf("\n                . Random seed:\t\t\t\t\t %d", io->r_seed);
-  PhyML_Printf("\n                . Subtree patterns aliasing:\t\t\t %s",io->do_alias_subpatt?"yes":"no");
-  PhyML_Printf("\n                . Version:\t\t\t\t\t %s", VERSION);
+  PhyML_Printf("\n        \u2023 Run ID:\t\t\t\t\t %s", (io->append_run_ID) ? (io->run_id_string): ("none"));
+  PhyML_Printf("\n        \u2023 Random seed:\t\t\t\t\t %d", io->r_seed);
+  PhyML_Printf("\n        \u2023 Subtree patterns aliasing:\t\t\t %s",io->do_alias_subpatt?"yes":"no");
+  PhyML_Printf("\n        \u2023 Version:\t\t\t\t\t %s", VERSION);
+  PhyML_Printf("\n        \u2023 Byte alignment:\t\t\t\t %d",BYTE_ALIGN);
+  PhyML_Printf("\n        \u2023 AVX enabled:\t\t\t\t\t %s",
+#if defined(__AVX__)
+               "yes"
+#else
+               "no"
+#endif
+               );
+  PhyML_Printf("\n        \u2023 SSE enabled:\t\t\t\t\t %s",
+#if defined(__SSE3__)
+               "yes"
+#else
+               "no"
+#endif
+               );
 
 
-  PhyML_Printf("\n\n oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\n");
+  PhyML_Printf("\n\n                           \u205C \u205C \u205C \u205C \u205C \u205C \u205C \u205C \u205C \u205C \u205C \u205C  \n");
 
   PhyML_Printf("\n\n");
   fflush(NULL);
@@ -3298,8 +3388,8 @@ void Print_Lk(t_tree *tree, char *string)
   while(loc_tree->prev) loc_tree = loc_tree->prev;
 
   time(&(loc_tree->t_current));
-  PhyML_Printf("\n. (%5d sec) [%15.4f] %s",
-           (int)(loc_tree->t_current-loc_tree->t_beg),loc_tree->c_lnL,
+  PhyML_Printf("\n\u2022 (%5d sec) [%15.4f] %s",
+               (int)(loc_tree->t_current-loc_tree->t_beg),Get_Lk(tree),
            string);
 #ifndef QUIET
   fflush(NULL);
@@ -3309,11 +3399,27 @@ void Print_Lk(t_tree *tree, char *string)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
+void Print_List(t_ll *list)
+{
+  t_ll *ll;
+  ll = list->head;
+  do
+    {
+      t_node *n;
+      n = (t_node *)ll->v;
+      PhyML_Printf("\n\u2022 list elem: %p next: %p prev: %p [%d] %p %p",(void *)ll,(void *)ll->next,(void *)ll->prev,n->num,(void *)ll->head,(void *)ll->tail);
+      ll = ll->next;
+    }
+  while(ll != NULL);
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
 
 void Print_Pars(t_tree *tree)
 {
   time(&(tree->t_current));
-  PhyML_Printf("\n. (%5d sec) [%5d]",(int)(tree->t_current-tree->t_beg),tree->c_pars);
+  PhyML_Printf("\n\u2022 (%5d sec) [%5d]",(int)(tree->t_current-tree->t_beg),tree->c_pars);
 #ifndef QUIET
   fflush(NULL);
 #endif
@@ -3326,7 +3432,7 @@ void Print_Lk_And_Pars(t_tree *tree)
 {
   time(&(tree->t_current));
 
-  PhyML_Printf("\n. (%5d sec) [%15.4f] [%5d]",
+  PhyML_Printf("\n\u2022 (%5d sec) [%15.4f] [%5d]",
      (int)(tree->t_current-tree->t_beg),
      tree->c_lnL,tree->c_pars);
 
@@ -3349,7 +3455,7 @@ void Read_Qmat(phydbl *daa, phydbl *pi, FILE *fp)
 
   for(i=1;i<20;i++)
     {
-      For(j,19)
+      for(j=0;j<19;j++)
         {
           /* 	  if(!fscanf(fp,"%lf",&(daa[i*20+j]))) Exit("\n"); */
           if(!fscanf(fp,"%lf",&val))
@@ -3364,18 +3470,18 @@ void Read_Qmat(phydbl *daa, phydbl *pi, FILE *fp)
     }
 
 
-  For(i,20)
+  for(i=0;i<20;i++)
     {
       if(!fscanf(fp,"%lf",&val)) Exit("\n");
       pi[i] = (phydbl)val;
     }
   sum = .0;
-  For(i,20) sum += pi[i];
+  for(i=0;i<20;i++) sum += pi[i];
   if(FABS(sum - 1.) > 1.E-06)
     {
-      PhyML_Printf("\n. Sum of amino-acid frequencies: %f",sum);
-      PhyML_Printf("\n. Scaling amino-acid frequencies...\n");
-      For(i,20) pi[i] /= sum;
+      PhyML_Printf("\n\u2022 Sum of amino-acid frequencies: %f",sum);
+      PhyML_Printf("\n\u2022 Scaling amino-acid frequencies...\n");
+      for(i=0;i<20;i++) pi[i] /= sum;
     }
 }
 
@@ -3388,7 +3494,7 @@ void Print_Qmat_AA(phydbl *daa, phydbl *pi)
   int i,j,cpt;
 
   cpt = 0;
-  For(i,20)
+  for(i=0;i<20;i++)
     {
       for(j=0;j<i;j++)
     {
@@ -3400,7 +3506,7 @@ void Print_Qmat_AA(phydbl *daa, phydbl *pi)
 
   PhyML_Printf("\n\n");
   PhyML_Printf("for (i=0; i<naa; i++)  for (j=0; j<i; j++)  daa[j*naa+i] = daa[i*naa+j];\n\n");
-  For(i,20) PhyML_Printf("pi[%d] = %f; ",i,pi[i]);
+  for(i=0;i<20;i++) PhyML_Printf("pi[%d] = %f; ",i,pi[i]);
   PhyML_Printf("\n");
   PhyML_Printf("Ala\tArg\tAsn\tAsp\tCys\tGln\tGlu\tGly\tHis\tIle\tLeu\tLys\tMet\tPhe\tPro\tSer\tThr\tTrp\tTyr\tVal\n");
 }
@@ -3414,10 +3520,10 @@ void Print_Square_Matrix_Generic(int n, phydbl *mat)
   int i,j;
 
   PhyML_Printf("\n");
-  For(i,n)
+  for(i=0;i<n;i++)
     {
       PhyML_Printf("[%3d]",i);
-      For(j,n)
+      for(j=0;j<n;j++)
         {
           PhyML_Printf("%12.5f ",mat[i*n+j]);
         }
@@ -3440,12 +3546,12 @@ void Print_Diversity(FILE *fp, t_tree *tree)
               tree);
 
 /*       mean_div_left = .0; */
-/*       For(k,ns)  */
+/*       for(k=0;k<ns;k++)  */
 /* 	{ */
 /* 	  mean_div_left += (k+1) * tree->a_edges[j]->div_post_pred_left[k]; */
 /* 	} */
 /*       mean_div_rght = .0; */
-/*       For(k,ns) mean_div_rght += (k+1) * tree->a_edges[j]->div_post_pred_rght[k]; */
+/*       for(k=0;k<ns;k++) mean_div_rght += (k+1) * tree->a_edges[j]->div_post_pred_rght[k]; */
 
 /*       mean_div_left /= (phydbl)tree->data->init_len; */
 /*       mean_div_rght /= (phydbl)tree->data->init_len; */
@@ -3455,19 +3561,19 @@ void Print_Diversity(FILE *fp, t_tree *tree)
 
 
 /*       mean_div_left = .0; */
-/*       For(k,ns) mean_div_left += tree->a_edges[j]->div_post_pred_left[k]; */
+/*       for(k=0;k<ns;k++) mean_div_left += tree->a_edges[j]->div_post_pred_left[k]; */
 
 /*       mean_div_rght = .0; */
-/*       For(k,ns)  */
+/*       for(k=0;k<ns;k++)  */
 /* 	{ */
 /* 	  mean_div_rght += tree->a_edges[j]->div_post_pred_rght[k]; */
 /* 	} */
 
 /*       if((mean_div_left != tree->data->init_len) || (mean_div_rght != tree->data->init_len)) */
 /* 	{ */
-/* 	  PhyML_Printf("\n. mean_div_left = %f mean_div_rght = %f init_len = %d", */
+/* 	  PhyML_Printf("\n\u2022 mean_div_left = %f mean_div_rght = %f init_len = %d", */
 /* 		 mean_div_left,mean_div_rght,tree->data->init_len); */
-/* 	  PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); */
+/* 	  PhyML_Printf("\n\u2022 Err in file %s at line %d\n",__FILE__,__LINE__); */
 /* 	  Warn_And_Exit(""); */
 /* 	} */
 }
@@ -3488,10 +3594,10 @@ void Print_Diversity_Pre(t_node *a, t_node *d, t_edge *b, FILE *fp, t_tree *tree
       if(tree->io->datatype == NT)      ns = 4;
       else if(tree->io->datatype == AA) ns = 20;
 
-      if(d == b->left) For(k,ns) PhyML_Fprintf(fp,"%4d 0 %2d %4d\n",b->num,k,b->div_post_pred_left[k]);
-      else             For(k,ns) PhyML_Fprintf(fp,"%4d 1 %2d %4d\n",b->num,k,b->div_post_pred_rght[k]);
+      if(d == b->left) for(k=0;k<ns;k++) PhyML_Fprintf(fp,"%4d 0 %2d %4d\n",b->num,k,b->div_post_pred_left[k]);
+      else             for(k=0;k<ns;k++) PhyML_Fprintf(fp,"%4d 1 %2d %4d\n",b->num,k,b->div_post_pred_rght[k]);
 
-      For(k,3) if(d->v[k] != a) Print_Diversity_Pre(d,d->v[k],d->b[k],fp,tree);
+      for(k=0;k<3;k++) if(d->v[k] != a) Print_Diversity_Pre(d,d->v[k],d->b[k],fp,tree);
     }
 
 }
@@ -3593,7 +3699,7 @@ void Print_Edge_Likelihoods(t_tree* tree, t_edge* b, bool scientific/*Print in s
         fprintf(stdout,"Likelihoods on LEFT tip of Branch %d [site,state]:\n",b->num);
         for(site=0;site<tree->n_pattern;++site)
             for(j=0;j<tree->mod->ns;++j)
-                fprintf(stdout,"[%d,%d]%d ",site,j,b->p_lk_tip_l[site*tree->mod->ns + j]);
+              fprintf(stdout,"[%d,%d]%.1f ",site,j,b->p_lk_tip_l[site*tree->mod->ns + j]);
         fflush(stdout);
     }
     fprintf(stdout,"\n");fflush(stdout);
@@ -3615,7 +3721,7 @@ void Print_Edge_Likelihoods(t_tree* tree, t_edge* b, bool scientific/*Print in s
         fprintf(stdout,"Likelihoods on RIGHT tip of Branch %d [site,state]:\n",b->num);
         for(site=0;site<tree->n_pattern;++site)
             for(j=0;j<tree->mod->ns;++j)
-                fprintf(stdout,"[%d,%d]%d ",site,j,b->p_lk_tip_r[site*tree->mod->ns + j]);
+                fprintf(stdout,"[%d,%d]%.1f ",site,j,b->p_lk_tip_r[site*tree->mod->ns + j]);
         fflush(stdout);
     }
 }
@@ -3716,12 +3822,14 @@ t_tree *Read_User_Tree(calign *cdata, t_mod *mod, option *io)
   t_tree *tree;
 
 
-  PhyML_Printf("\n. Reading tree..."); fflush(NULL);
+  PhyML_Printf("\n\u2022 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);
+  if(tree->has_branch_lengths == NO) Add_BioNJ_Branch_Lengths(tree,cdata,mod,NULL);
   return tree;
 }
 
@@ -3737,7 +3845,7 @@ void Print_Time_Info(time_t t_beg, time_t t_end)
   min  = div(t_end-t_beg,60  );
   min.quot -= hour.quot*60;
 
-  PhyML_Printf("\n\n. Time used %dh%dm%ds\n", hour.quot,min.quot,(int)(t_end-t_beg)%60);
+  PhyML_Printf("\n\n\u2022 Time used %dh%dm%ds\n", hour.quot,min.quot,(int)(t_end-t_beg)%60);
   PhyML_Printf("\noooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\n");
 }
 
@@ -3748,7 +3856,7 @@ void PhyML_Printf(char *format, ...)
 {
   va_list ptr;
 
- #ifdef MPI
+#ifdef MPI
   if(Global_myRank == 0)
     {
       va_start (ptr, format);
@@ -3761,7 +3869,7 @@ void PhyML_Printf(char *format, ...)
       va_end(ptr);
 #endif
 
-  /* fflush (NULL); */
+  fflush (NULL);
 }
 
 //////////////////////////////////////////////////////////////
@@ -3806,13 +3914,13 @@ void Read_Clade_Priors(char *file_name, t_tree *tree)
   int node_num;
 
   PhyML_Printf("\n");
-  PhyML_Printf("\n. Reading prior on node ages.\n");
+  PhyML_Printf("\n\u2022 Reading prior on node ages.\n");
 
   line = (char *)mCalloc(T_MAX_LINE,sizeof(char));
   s    = (char *)mCalloc(T_MAX_LINE,sizeof(char));
 
   clade_list = (char **)mCalloc(tree->n_otu,sizeof(char *));
-  For(i,tree->n_otu) clade_list[i] = (char *)mCalloc(T_MAX_NAME,sizeof(char));
+  for(i=0;i<tree->n_otu;i++) clade_list[i] = (char *)mCalloc(T_MAX_NAME,sizeof(char));
 
   fp = Openfile(file_name,0);
 
@@ -3837,7 +3945,7 @@ void Read_Clade_Priors(char *file_name, t_tree *tree)
         }
       s[i] = '\0';
 
-      /* PhyML_Printf("\n. s = %s\n",s); */
+      /* PhyML_Printf("\n\u2022 s = %s\n",s); */
 
       if(line[pos] == '\n' || line[pos] == '#') break;
       pos++;
@@ -3870,10 +3978,10 @@ void Read_Clade_Priors(char *file_name, t_tree *tree)
         {
           PhyML_Printf("\n");
           PhyML_Printf("\n");
-          PhyML_Printf("\n. .................................................................");
-          PhyML_Printf("\n. WARNING: could not find any clade in the tree referred to with the following taxon names:");
-          For(i,clade_size) PhyML_Printf("\n. \"%s\"",clade_list[i]);
-          PhyML_Printf("\n. .................................................................");
+          PhyML_Printf("\n\u2022 .................................................................");
+          PhyML_Printf("\n\u2022 WARNING: could not find any clade in the tree referred to with the following taxon names:");
+          for(i=0;i<clade_size;i++) PhyML_Printf("\n\u2022 \"%s\"",clade_list[i]);
+          PhyML_Printf("\n\u2022 .................................................................");
           /* sleep(3); */
         }
       else
@@ -3890,19 +3998,19 @@ void Read_Clade_Priors(char *file_name, t_tree *tree)
         tree->rates->nd_t[node_num] = prior_low;
 
           PhyML_Printf("\n");
-          PhyML_Printf("\n. [%3d]..................................................................",n_clade_priors);
-          PhyML_Printf("\n. Node %4d matches the clade referred to with the following taxon names:",node_num);
-          For(i,clade_size) PhyML_Printf("\n. - \"%s\"",clade_list[i]);
-          PhyML_Printf("\n. Lower bound set to: %15f time units.",MIN(prior_low,prior_up));
-          PhyML_Printf("\n. Upper bound set to: %15f time units.",MAX(prior_low,prior_up));
-          PhyML_Printf("\n. .......................................................................");
+          PhyML_Printf("\n\u2022 [%3d]..................................................................",n_clade_priors);
+          PhyML_Printf("\n\u2022 Node %4d matches the clade referred to with the following taxon names:",node_num);
+          for(i=0;i<clade_size;i++) PhyML_Printf("\n\u2022 - \"%s\"",clade_list[i]);
+          PhyML_Printf("\n\u2022 Lower bound set to: %15f time units.",MIN(prior_low,prior_up));
+          PhyML_Printf("\n\u2022 Upper bound set to: %15f time units.",MAX(prior_low,prior_up));
+          PhyML_Printf("\n\u2022 .......................................................................");
         }
     }
     }
   while(1);
 
 
-  PhyML_Printf("\n. Read prior information on %d %s.",n_clade_priors,n_clade_priors > 1 ? "clades":"clade");
+  PhyML_Printf("\n\u2022 Read prior information on %d %s.",n_clade_priors,n_clade_priors > 1 ? "clades":"clade");
 
   if(!n_clade_priors)
     {
@@ -3916,7 +4024,7 @@ void Read_Clade_Priors(char *file_name, t_tree *tree)
       Warn_And_Exit("");
     }
 
-  For(i,tree->n_otu) Free(clade_list[i]);
+  for(i=0;i<tree->n_otu;i++) Free(clade_list[i]);
   Free(clade_list);
   Free(line);
   Free(s);
@@ -4139,10 +4247,10 @@ void Print_Data_Structure(int final, FILE *fp, t_tree *mixt_tree)
   phydbl r_mat_weight_sum, e_frq_weight_sum;
 
 
-  PhyML_Fprintf(fp,"\n. Starting tree: %s",
+  PhyML_Fprintf(fp,"\n\u2022 Starting tree: %s",
            mixt_tree->io->in_tree == 2?mixt_tree->io->in_tree_file:"BioNJ");
 
-  PhyML_Fprintf(fp,"\n. Tree topology search: %s",
+  PhyML_Fprintf(fp,"\n\u2022 Tree topology search: %s",
            mixt_tree->io->mod->s_opt->opt_topo==YES?
            mixt_tree->io->mod->s_opt->topo_search==SPR_MOVE?"spr":
            mixt_tree->io->mod->s_opt->topo_search==NNI_MOVE?"nni":
@@ -4176,12 +4284,12 @@ void Print_Data_Structure(int final, FILE *fp, t_tree *mixt_tree)
   s[(int)strlen(s)-2]=' ';
   s[(int)strlen(s)-1]='\0';
 
-  if(final == NO)  PhyML_Fprintf(fp,"\n. Processing %d data %s (%s)",n_partition_elem,n_partition_elem>1?"sets":"set",s);
-  if(final == YES) PhyML_Fprintf(fp,"\n. Processed %d data %s (%s)",n_partition_elem,n_partition_elem>1?"sets":"set",s);
+  if(final == NO)  PhyML_Fprintf(fp,"\n\u2022 Processing %d data %s (%s)",n_partition_elem,n_partition_elem>1?"sets":"set",s);
+  if(final == YES) PhyML_Fprintf(fp,"\n\u2022 Processed %d data %s (%s)",n_partition_elem,n_partition_elem>1?"sets":"set",s);
   Free(s);
 
   if(final == YES)
-    PhyML_Fprintf(fp,"\n. Final log-likelihood: %f",mixt_tree->c_lnL);
+    PhyML_Fprintf(fp,"\n\u2022 Final log-likelihood: %f",mixt_tree->c_lnL);
 
   r_mat_weight_sum = MIXT_Get_Sum_Chained_Scalar_Dbl(mixt_tree->next->mod->r_mat_weight);
   e_frq_weight_sum = MIXT_Get_Sum_Chained_Scalar_Dbl(mixt_tree->next->mod->e_frq_weight);
@@ -4197,24 +4305,24 @@ void Print_Data_Structure(int final, FILE *fp, t_tree *mixt_tree)
       PhyML_Fprintf(fp,"\n|_______________________________________________________________________|");
       PhyML_Fprintf(fp,"\n");
 
-      PhyML_Fprintf(fp,"\n. Number of rate classes:\t\t%12d",mixt_tree->mod->ras->n_catg+(mixt_tree->mod->ras->invar ?1:0));
+      PhyML_Fprintf(fp,"\n\u2022 Number of rate classes:\t\t%12d",mixt_tree->mod->ras->n_catg+(mixt_tree->mod->ras->invar ?1:0));
       if(mixt_tree->mod->ras->n_catg > 1)
         {
-          PhyML_Fprintf(fp,"\n. Model of rate variation:\t\t%12s",
+          PhyML_Fprintf(fp,"\n\u2022 Model of rate variation:\t\t%12s",
                         mixt_tree->mod->ras->free_mixt_rates?"FreeRates":
                         mixt_tree->mod->ras->invar?"Gamma+Inv":"Gamma");
           if(mixt_tree->mod->ras->free_mixt_rates == NO)
             {
-              PhyML_Fprintf(fp,"\n. Gamma shape parameter value:\t\t%12.2f",mixt_tree->mod->ras->alpha->v);
+              PhyML_Fprintf(fp,"\n\u2022 Gamma shape parameter value:\t\t%12.2f",mixt_tree->mod->ras->alpha->v);
               PhyML_Fprintf(fp,"\n   Optimise: \t\t\t\t%12s",mixt_tree->mod->s_opt->opt_alpha==YES?"yes":"no");
             }
           if(mixt_tree->mod->ras->invar == YES)
             {
-              PhyML_Fprintf(fp,"\n. Proportion of invariable sites:\t%12.2f",mixt_tree->mod->ras->pinvar->v);
+              PhyML_Fprintf(fp,"\n\u2022 Proportion of invariable sites:\t%12.2f",mixt_tree->mod->ras->pinvar->v);
               PhyML_Fprintf(fp,"\n   Optimise: \t\t\t\t%12s",mixt_tree->mod->s_opt->opt_pinvar==YES?"yes":"no");
             }
         }
-      PhyML_Fprintf(fp,"\n. Relative average rate:\t\t%12f",mixt_tree->mod->br_len_mult->v);
+      PhyML_Fprintf(fp,"\n\u2022 Relative average rate:\t\t%12f",mixt_tree->mod->br_len_mult->v);
 
      
       tree = mixt_tree;
@@ -4223,7 +4331,7 @@ void Print_Data_Structure(int final, FILE *fp, t_tree *mixt_tree)
           if(tree->is_mixt_tree) tree = tree->next;
 
           PhyML_Fprintf(fp,"\n");
-          PhyML_Fprintf(fp,"\n. Mixture class %d",class+1);
+          PhyML_Fprintf(fp,"\n\u2022 Mixture class %d",class+1);
           
           if(mixt_tree->mod->ras->n_catg > 1)
             {
@@ -4252,7 +4360,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 ||
@@ -4545,7 +4653,7 @@ void Print_Data_Structure(int final, FILE *fp, t_tree *mixt_tree)
       do
         {
           PhyML_Fprintf(fp,"\n");
-          PhyML_Fprintf(fp,"\n. Tree estimated from data partition %d",c++);
+          PhyML_Fprintf(fp,"\n\u2022 Tree estimated from data partition %d",c++);
           Br_Len_Involving_Invar(tree->next);
           Rescale_Br_Len_Multiplier_Tree(tree->next);
           s = Write_Tree(tree->next,NO); /*! tree->next is not a mixt_tree so edge lengths
@@ -4572,1201 +4680,54 @@ 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)
+  for(num_rand_tree=0;num_rand_tree<io->mod->s_opt->n_rand_starts;num_rand_tree++)
     {
-      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);
-        }
-    }
-  
+      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);
   
-  s = XML_Get_Attribute_Value(p_elem,"branch.test");
-  if(s)
-    {
-      if(!strcmp(s,"aLRT"))
+      if(mixt_tree->io->mod->s_opt->random_input_tree)
         {
-          io->ratio_test = ALRTSTAT;
+          PhyML_Printf("\n\n\u2022 [%3d/%3d]",num_rand_tree+1,mixt_tree->io->mod->s_opt->n_rand_starts);
+          Random_Tree(mixt_tree);
         }
-      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);
-
+      MIXT_Connect_Cseqs_To_Nodes(mixt_tree);
+      MIXT_Init_T_Beg(mixt_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_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);
-
+      Br_Len_Not_Involving_Invar(mixt_tree);
+      Unscale_Br_Len_Multiplier_Tree(mixt_tree);
       Set_Both_Sides(YES,mixt_tree);
-
+            
+      Switch_Eigen(YES,mixt_tree->mod);                 
+      Lk(NULL,mixt_tree);
+      Switch_Eigen(NO,mixt_tree->mod);
+      
       if(mixt_tree->mod->s_opt->opt_topo)
         {
           if(mixt_tree->mod->s_opt->topo_search      == NNI_MOVE) Simu_Loop(mixt_tree);
@@ -5775,21 +4736,12 @@ option *PhyML_XML(char *xml_filename)
         }
       else
         {
-          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
-            {
-              Lk(NULL,mixt_tree);
-            }
+          Round_Optimize(mixt_tree,ROUND_MAX);
         }
 
 
-      PhyML_Printf("\n\n. Log-likelihood = %f",mixt_tree->c_lnL);
-
+      PhyML_Printf("\n\n\u2022 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 +4767,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);
@@ -5833,12 +4785,11 @@ 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));
+  if(!mixt_tree->io->quiet) PhyML_Printf("\n\n\u2022 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 +4798,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 +4815,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);
 }
@@ -5893,7 +4842,7 @@ void Check_Taxa_Sets(t_tree *mixt_tree)
     {
       if(tree->next)
         {
-          For(i,tree->n_otu)
+          for(i=0;i<tree->n_otu;i++)
             {
               if(strcmp(tree->a_nodes[i]->name,tree->next->a_nodes[i]->name))
                 {
@@ -5914,7 +4863,7 @@ void Check_Taxa_Sets(t_tree *mixt_tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-void Make_Ratematrice_From_XML_Node(xml_node *instance, option *io, t_mod *mod)
+void Make_Ratematrix_From_XML_Node(xml_node *instance, option *io, t_mod *mod)
 {
   char *model = NULL;
   int select;
@@ -5958,10 +4907,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 +4917,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 +4924,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);
 
@@ -6011,11 +4955,13 @@ void Make_Ratematrice_From_XML_Node(xml_node *instance, option *io, t_mod *mod)
         {
           if(!strcmp(opt_tstv,"true") || !strcmp(opt_tstv,"yes"))
             {
-              mod->s_opt->opt_kappa = YES;
+              mod->s_opt->opt_kappa       = YES;
+              mod->s_opt->opt_subst_param = YES;
             }
           else
             {
-              mod->s_opt->opt_kappa = NO;
+              mod->s_opt->opt_kappa       = NO;
+              mod->s_opt->opt_subst_param = NO;
             }
         }
     }
@@ -6034,7 +4980,13 @@ void Make_Ratematrice_From_XML_Node(xml_node *instance, option *io, t_mod *mod)
         {
           if(!strcmp(opt_rr,"yes") || !strcmp(opt_rr,"true"))
             {
-              mod->s_opt->opt_rr = YES;
+              mod->s_opt->opt_rr          = YES;
+              mod->s_opt->opt_subst_param = YES;
+            }
+          else
+            {
+              mod->s_opt->opt_rr          = NO;
+              mod->s_opt->opt_subst_param = NO;
             }
         }
     }
@@ -6075,7 +5027,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 +5054,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");
 
@@ -6119,7 +5070,6 @@ void Make_Efrq_From_XML_Node(xml_node *instance, option *io, t_mod *mod)
             }
           mod->s_opt->opt_state_freq = YES;
         }
-      Free(buff);
     }
 
   buff = XML_Get_Attribute_Value(instance,"aa.freqs");
@@ -6130,16 +5080,16 @@ 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); */
     }
-
+  
 
   buff = XML_Get_Attribute_Value(instance,"base.freqs");
 
@@ -6154,11 +5104,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 +5264,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 +5273,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 +5418,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");
           }
@@ -6495,17 +5456,428 @@ void Make_RAS_From_XML_Node(xml_node *parent, t_mod *mod)
 
 void Generic_Exit(const char *file, int line, const char *function)
 {
-  PhyML_Printf("\n== Err. in file '%s' (line %d), function '%s'",file,line,function);
+  PhyML_Printf("\n== Err. in file '%s' (line %d)",file,line);
+  if(function != NULL) PhyML_Printf(", function '%s'",function);
   Exit("\n");
+}
+
+/*////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////*/
 
+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 *mixt_tree)
+{
+  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",mixt_tree->json_num);
+  mixt_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-mixt_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(mixt_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",mixt_tree->c_lnL);
+
+  sv->next = NULL;
+
+
+
+  // TsTv
+  {
+    int n_tstv,i;
+    scalar_dbl **tstv;
+
+    n_tstv = 0;
+    tstv   = NULL;
+    tree   = mixt_tree;
+    
+    do
+      {
+        if(tree->is_mixt_tree == YES) tree = tree->next;
+        
+        for(i=0;i<n_tstv;i++) if(tree->mod->kappa == tstv[i]) break;
+        
+        if(i == n_tstv)
+          {
+            if(!tstv) tstv = (scalar_dbl **)mCalloc(1,sizeof(scalar_dbl *));
+            else      tstv = (scalar_dbl **)mRealloc(tstv,n_tstv+1,sizeof(scalar_dbl *));
+            tstv[n_tstv] = tree->mod->kappa;
+            n_tstv++;
+            
+            if(tree->mod->s_opt->opt_kappa == YES)
+              {
+                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,"tstv");
+                sprintf(sv->value+strlen(sv->value),"%d",n_tstv);
+                
+                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->mod->kappa->v);
+                
+                sv->next = NULL;
+      
+              }
+          }
+        tree = tree->next;
+      }
+    while(tree);
+
+    if(tstv) Free(tstv);
+  }
+
+
+
+  // Alpha
+  {
+    int n_alpha,i;
+    scalar_dbl **alpha;
+
+    n_alpha = 0;
+    alpha   = NULL;
+    tree    = mixt_tree;
+    
+    do
+      {
+        
+        for(i=0;i<n_alpha;i++) if(tree->mod->ras->alpha == alpha[i]) break;
+        
+        if(i == n_alpha)
+          {
+            if(!alpha) alpha = (scalar_dbl **)mCalloc(1,sizeof(scalar_dbl *));
+            else      alpha = (scalar_dbl **)mRealloc(alpha,n_alpha+1,sizeof(scalar_dbl *));
+            alpha[n_alpha] = tree->mod->ras->alpha;
+            n_alpha++;
+            
+            if(tree->mod->s_opt->opt_alpha == YES)
+              {
+                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,"alpha");
+                sprintf(sv->value+strlen(sv->value),"%d",n_alpha);
+                
+                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->mod->ras->alpha->v);
+                
+                sv->next = NULL;
+      
+              }
+          }
+        tree = tree->next_mixt;
+      }
+    while(tree);
+
+    if(alpha) Free(alpha);
+  }
+
+
+
+
+
+  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..cc768bb 100644
--- a/src/io.h
+++ b/src/io.h
@@ -25,6 +25,7 @@ void Read_Node_Name(t_node *d,char *s_tree_d,t_tree *tree);
 void Clean_Multifurcation(char **subtrees,int current_deg,int end_deg);
 char **Sub_Trees(char *tree,int *degree);
 int Next_Par(char *s,int pos);
+void Print_List(t_ll *list);
 void Print_Tree(FILE *fp,t_tree *tree);
 char *Write_Tree(t_tree *tree,int custom);
 void R_wtree(t_node *pere,t_node *fils,int *available,char **s_tree,t_tree *tree);
@@ -44,7 +45,7 @@ char *Return_Tree_String_Phylip(FILE *fp_input_tree);
 t_tree *Read_Tree_File_Phylip(FILE *fp_input_tree);
 void Print_Site_Lk(t_tree *tree,FILE *fp);
 void Print_Seq(FILE *fp, align **data, int n_otu);
-void Print_CSeq(FILE *fp,int compressed,calign *cdata);
+void Print_CSeq(FILE *fp,int compressed,calign *cdata,t_tree *tree);
 void Print_CSeq_Select(FILE *fp,int compressed,calign *cdata,t_tree *tree);
 void Print_Dist(matrix *mat);
 void Print_Node(t_node *a,t_node *d,t_tree *tree);
@@ -77,7 +78,7 @@ int Set_Whichmodel(int select);
 void Print_Site(calign *cdata, int num, int n_otu, char *sep, int stepsize, FILE *fp);
 option *PhyML_XML(char *xml_filename);
 void Check_Taxa_Sets(t_tree *mixt_tree);
-void Make_Ratematrice_From_XML_Node(xml_node *instance, option *io, t_mod *mod);
+void Make_Ratematrix_From_XML_Node(xml_node *instance, option *io, t_mod *mod);
 void Make_Efrq_From_XML_Node(xml_node *instance, option *io, t_mod *mod);
 void Make_Topology_From_XML_Node(xml_node *instance, option *io, t_mod *mod);
 void Make_RAS_From_XML_Node(xml_node *parent, t_mod *mod);
@@ -94,4 +95,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..1a1029e 100644
--- a/src/lk.c
+++ b/src/lk.c
@@ -15,11 +15,11 @@ the GNU public licence. See http://www.opensource.org for details.
 #ifdef BEAGLE
 #include "beagle_utils.h"
 #endif
+#include <stdint.h>
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Init_Tips_At_One_Site_Nucleotides_Float(char state, int pos, phydbl *p_lk)
 {
   switch(state)
@@ -116,12 +116,11 @@ void Init_Tips_At_One_Site_Nucleotides_Int(char state, int pos, short int *p_par
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Init_Tips_At_One_Site_AA_Float(char aa, int pos, phydbl *p_lk)
 {
   int i;
 
-  For(i,20) p_lk[pos+i] = .0;
+  for(i=0;i<20;i++) p_lk[pos+i] = .0;
 
   switch(aa){
   case 'A' : p_lk[pos+0]= 1.; break;/* Alanine */
@@ -148,7 +147,7 @@ void Init_Tips_At_One_Site_AA_Float(char aa, int pos, phydbl *p_lk)
   case 'B' : p_lk[pos+2]= 1.; break;/* Asparagine */
   case 'Z' : p_lk[pos+5]= 1.; break;/* Glutamine */
 
-  case 'X' : case '?' : case '-' : For(i,20) p_lk[pos+i] = 1.; break;
+  case 'X' : case '?' : case '-' : for(i=0;i<20;i++) p_lk[pos+i] = 1.; break;
   default :
     {
       PhyML_Printf("\n. Unknown character state : %c\n",aa);
@@ -161,12 +160,11 @@ void Init_Tips_At_One_Site_AA_Float(char aa, int pos, phydbl *p_lk)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Init_Tips_At_One_Site_AA_Int(char aa, int pos, short int *p_pars)
 {
   int i;
 
-  For(i,20) p_pars[pos+i] = .0;
+  for(i=0;i<20;i++) p_pars[pos+i] = .0;
 
   switch(aa){
   case 'A' : p_pars[pos+0]  = 1; break;/* Alanine */
@@ -193,7 +191,7 @@ void Init_Tips_At_One_Site_AA_Int(char aa, int pos, short int *p_pars)
   case 'B' : p_pars[pos+2]  = 1; break;/* Asparagine */
   case 'Z' : p_pars[pos+5]  = 1; break;/* Glutamine */
 
-  case 'X' : case '?' : case '-' : For(i,20) p_pars[pos+i] = 1; break;
+  case 'X' : case '?' : case '-' : for(i=0;i<20;i++) p_pars[pos+i] = 1; break;
   default :
     {
       PhyML_Printf("\n. Unknown character state : %c\n",aa);
@@ -206,15 +204,14 @@ void Init_Tips_At_One_Site_AA_Int(char aa, int pos, short int *p_pars)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Init_Tips_At_One_Site_Generic_Float(char *state, int ns, int state_len, int pos, phydbl *p_lk)
 {
   int i;
   int state_int;
 
-  For(i,ns) p_lk[pos+i] = 0.;
+  for(i=0;i<ns;i++) p_lk[pos+i] = 0.;
 
-  if(Is_Ambigu(state,GENERIC,state_len)) For(i,ns) p_lk[pos+i] = 1.;
+  if(Is_Ambigu(state,GENERIC,state_len)) for(i=0;i<ns;i++) p_lk[pos+i] = 1.;
   else
     {
       char format[6];
@@ -239,15 +236,14 @@ void Init_Tips_At_One_Site_Generic_Float(char *state, int ns, int state_len, int
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Init_Tips_At_One_Site_Generic_Int(char *state, int ns, int state_len, int pos, short int *p_pars)
 {
   int i;
   int state_int;
 
-  For(i,ns) p_pars[pos+i] = 0;
+  for(i=0;i<ns;i++) p_pars[pos+i] = 0;
 
-  if(Is_Ambigu(state,GENERIC,state_len)) For(i,ns) p_pars[pos+i] = 1;
+  if(Is_Ambigu(state,GENERIC,state_len)) for(i=0;i<ns;i++) p_pars[pos+i] = 1;
   else
     {
       char format[6];
@@ -272,53 +268,20 @@ void Init_Tips_At_One_Site_Generic_Int(char *state, int ns, int state_len, int p
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Get_All_Partial_Lk_Scale(t_tree *tree, t_edge *b_fcus, t_node *a, t_node *d)
 {
-  Update_P_Lk(tree,b_fcus,d);
+  Update_Partial_Lk(tree,b_fcus,d);
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-/* void Post_Order_Lk(t_node *a, t_node *d, t_tree *tree) */
-/* { */
-/*   int i,dir; */
-
-/*   if(tree->is_mixt_tree == YES) */
-/*     { */
-/*       MIXT_Post_Order_Lk(a,d,tree); */
-/*       return; */
-/*     } */
-
-/*   dir = -1; */
-
-/*   if(d->tax)  */
-/*     { */
-/*       Get_All_Partial_Lk_Scale(tree,d->b[0],a,d); */
-/*       return; */
-/*     } */
-/*   else */
-/*     { */
-/*       For(i,3) */
-/* 	{ */
-/* 	  if(d->v[i] != a) */
-/* 	    Post_Order_Lk(d,d->v[i],tree); */
-/* 	  else dir = i; */
-/* 	}       */
-/*       Get_All_Partial_Lk_Scale(tree,d->b[dir],a,d); */
-/*     } */
-/* } */
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
 void Post_Order_Lk(t_node *a, t_node *d, t_tree *tree)
 {
   int i,dir;
 
   dir = -1;
-
+  
   if(d->tax) return;
   else
     {
@@ -330,7 +293,7 @@ void Post_Order_Lk(t_node *a, t_node *d, t_tree *tree)
 
       if(tree->n_root)
         {
-          For(i,3)
+          for(i=0;i<3;i++)
             {
               if(d->v[i] != a && d->b[i] != tree->e_root)
                 Post_Order_Lk(d,d->v[i],tree);
@@ -339,22 +302,37 @@ void Post_Order_Lk(t_node *a, t_node *d, t_tree *tree)
         }
       else
         {
-          For(i,3)
+          for(i=0;i<3;i++)
             {
               if(d->v[i] != a)
                 Post_Order_Lk(d,d->v[i],tree);
               else dir = i;
             }
         }
-      
+
+      if(dir < 0)
+        {
+          PhyML_Printf("\n== a: %d d: %d [%d %d %d] [%d %d %d]",
+                       a->num,
+                       d->num,
+                       d->v[0] ? d->v[0]->num : -1,
+                       d->v[1] ? d->v[1]->num : -1,
+                       d->v[2] ? d->v[2]->num : -1,
+                       d->b[0] ? d->b[0]->num : -1,
+                       d->b[1] ? d->b[1]->num : -1,
+                       d->b[2] ? d->b[2]->num : -1);
+          fflush(NULL);
+        }
+      assert(dir > -1);
+
       if(tree->ignore_root == NO && d->b[dir] == tree->e_root)
         {
-          if(d == tree->n_root->v[1]) Get_All_Partial_Lk_Scale(tree,tree->n_root->b[1],tree->n_root,d);
-          else                        Get_All_Partial_Lk_Scale(tree,tree->n_root->b[2],tree->n_root,d);
+          if(d == tree->n_root->v[1]) Update_Partial_Lk(tree,tree->n_root->b[1],d);
+          else                        Update_Partial_Lk(tree,tree->n_root->b[2],d);
         }
       else
         {
-          Get_All_Partial_Lk_Scale(tree,d->b[dir],a,d);
+          Update_Partial_Lk(tree,d->b[dir],d);
         }
     }
 }
@@ -377,22 +355,22 @@ void Pre_Order_Lk(t_node *a, t_node *d, t_tree *tree)
 
       if(tree->n_root)
         {
-          For(i,3)
+          for(i=0;i<3;++i)
             {
               if(d->v[i] != a && d->b[i] != tree->e_root)
                 {
-                  Get_All_Partial_Lk_Scale(tree,d->b[i],d->v[i],d);
+                  Update_Partial_Lk(tree,d->b[i],d);
                   Pre_Order_Lk(d,d->v[i],tree);
                 }
             }
         }
       else
         {
-          For(i,3)
+          for(i=0;i<3;++i)
             {
               if(d->v[i] != a)
                 {
-                  Get_All_Partial_Lk_Scale(tree,d->b[i],d->v[i],d);
+                  Update_Partial_Lk(tree,d->b[i],d);
                   Pre_Order_Lk(d,d->v[i],tree);
                 }
             }
@@ -403,10 +381,62 @@ void Pre_Order_Lk(t_node *a, t_node *d, t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
+// Updates all partial likelihood vectors. Depending on whether 
+// both_sides = YES or NO, only 'up' or 'up'&'down' partials will
+// be updates
+void Update_All_Partial_Lk(t_tree *tree)
+{
+  if(tree->n_root)
+    {
+      if(tree->ignore_root == NO)
+        {          
+          Post_Order_Lk(tree->n_root,tree->n_root->v[1],tree);
+          Post_Order_Lk(tree->n_root,tree->n_root->v[2],tree);
+          
+          Update_Partial_Lk(tree,tree->n_root->b[1],tree->n_root);
+          Update_Partial_Lk(tree,tree->n_root->b[2],tree->n_root);
+          
+          if(tree->both_sides == YES)
+            {
+              Pre_Order_Lk(tree->n_root,tree->n_root->v[2],tree);
+              Pre_Order_Lk(tree->n_root,tree->n_root->v[1],tree);
+            }
+        }
+      else
+        {
+
+          Post_Order_Lk(tree->e_root->rght,tree->e_root->left,tree);
+          Post_Order_Lk(tree->e_root->left,tree->e_root->rght,tree);
+          
+          if(tree->both_sides == YES)
+            {
+              Pre_Order_Lk(tree->e_root->rght,tree->e_root->left,tree);
+              Pre_Order_Lk(tree->e_root->left,tree->e_root->rght,tree);
+            }
+        }
+    }
+  else
+    {
+      Post_Order_Lk(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree);
+      if(tree->both_sides == YES)
+        Pre_Order_Lk(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree);
+    }
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
 phydbl Lk(t_edge *b, t_tree *tree)
 {
-  int br;
+  unsigned int br,catg,state,ambiguity_check,site;
+  phydbl len,*expl,*dot_prod;
+  const unsigned int ns = tree->mod->ns;
+  const unsigned int ncatg = tree->mod->ras->n_catg;
+  const unsigned int npatterns = tree->n_pattern;
+
   
+  if(tree->eval_alnL == NO) return UNLIKELY;
+
   if(b == NULL && tree->mod->s_opt->curr_opt_free_rates == YES)
     {
       tree->mod->s_opt->curr_opt_free_rates = NO;
@@ -415,25 +445,26 @@ phydbl Lk(t_edge *b, t_tree *tree)
     }
   
   
-  if(tree->is_mixt_tree) {
+  if(tree->is_mixt_tree == YES) 
+    {
 #ifdef BEAGLE
-    Warn_And_Exit(TODO_BEAGLE);
+      Warn_And_Exit(TODO_BEAGLE);
 #endif
-    return MIXT_Lk(b,tree);
-  }
+      return MIXT_Lk(b,tree);
+    }
   
   tree->old_lnL = tree->c_lnL;
-
   
 #ifdef PHYREX
   PHYREX_Ldsk_To_Tree(tree);
 #endif
 
+
 #if (defined PHYTIME || defined INVITEE || defined PHYREX)
   if((tree->rates) && (tree->rates->bl_from_rt)) RATES_Update_Cur_Bl(tree);
 #endif
 
-  if(tree->rates && tree->io->lk_approx == NORMAL)
+if(tree->rates && tree->io->lk_approx == NORMAL)
     {
 #ifdef BEAGLE
       Warn_And_Exit(TODO_BEAGLE);
@@ -442,40 +473,45 @@ phydbl Lk(t_edge *b, t_tree *tree)
       return tree->c_lnL;
     }
   
-  if(!b) Set_Model_Parameters(tree->mod);
+ expl     = tree->expl;
+ dot_prod = tree->dot_prod;
+ 
+ 
+ if(b == NULL)
+   {
+     Update_Boundaries(tree->mod);
+     Update_RAS(tree->mod);
+     Update_Efrq(tree->mod);
+     Update_Eigen(tree->mod);
+   }
   
-  Set_Br_Len_Var(tree);
-  
-  if(tree->mod->s_opt->skip_tree_traversal == NO)
+ if(tree->mod->s_opt->skip_tree_traversal == NO)
     {
-      if(!b)//Update the PMat for all edges
+      if(!b) //Update PMat for all edges
         {
-          For(br,2*tree->n_otu-3)
-            {
-              Update_PMat_At_Given_Edge(tree->a_edges[br],tree);
-            }
+          for(br=0;br<2*tree->n_otu-3;++br) Update_PMat_At_Given_Edge(tree->a_edges[br],tree);
           if(tree->n_root && tree->ignore_root == NO)
             {
               Update_PMat_At_Given_Edge(tree->n_root->b[1],tree);
               Update_PMat_At_Given_Edge(tree->n_root->b[2],tree);
             }
         }
-      else//Update the PMat for a specific edge
+      else//Update PMat for a specific edge
         {
-          Update_PMat_At_Given_Edge(b,tree);
+          if(tree->use_eigen_lr == NO) Update_PMat_At_Given_Edge(b,tree);
         }
       
       if(!b)
         {
-          if(tree->n_root)
+          if(tree->n_root != NULL)
             {
               if(tree->ignore_root == NO)
                 {
                   Post_Order_Lk(tree->n_root,tree->n_root->v[1],tree);
                   Post_Order_Lk(tree->n_root,tree->n_root->v[2],tree);
                   
-                  Update_P_Lk(tree,tree->n_root->b[1],tree->n_root);
-                  Update_P_Lk(tree,tree->n_root->b[2],tree->n_root);
+                  Update_Partial_Lk(tree,tree->n_root->b[1],tree->n_root);
+                  Update_Partial_Lk(tree,tree->n_root->b[2],tree->n_root);
                   
                   if(tree->both_sides == YES)
                     {
@@ -524,13 +560,28 @@ phydbl Lk(t_edge *b, t_tree *tree)
   calc_edgelks_beagle(b, tree);
 #else
 
-  int n_patterns,ambiguity_check,state;
-  n_patterns = tree->n_pattern;
-  For(tree->curr_site,n_patterns)
+  if(tree->update_eigen_lr == YES) Update_Eigen_Lr(b,tree);
+  
+  if(tree->use_eigen_lr == YES)
+    {  
+      for(catg=0;catg<ncatg;++catg)
+        {
+          len = MAX(0.0,b->l->v)*tree->mod->ras->gamma_rr->v[catg];
+          len *= tree->mod->br_len_mult->v;
+          if(tree->mixt_tree != NULL)     len *= tree->mixt_tree->mod->ras->gamma_rr->v[tree->mod->ras->parent_class_number];
+          if(len < tree->mod->l_min)      len = tree->mod->l_min;
+          else if(len > tree->mod->l_max) len = tree->mod->l_max;
+          for(state=0;state<ns;++state) expl[catg*ns+state] = (phydbl)POW(tree->mod->eigen->e_val[state],len);
+        }
+    }
+
+
+  for(site=0;site<npatterns;++site)
     {
       ambiguity_check = -1;
       state           = -1;
-
+      tree->curr_site = site;
+      
       if(tree->data->wght[tree->curr_site] > SMALL)
         {
           if((b->rght->tax) && (tree->mod->s_opt->greedy == NO))
@@ -543,390 +594,562 @@ phydbl Lk(t_edge *b, t_tree *tree)
             }
 
           if(tree->mod->use_m4mod) ambiguity_check = YES;
-
-          Lk_Core(state,ambiguity_check,b,tree);
-
-          /* fprintf(stdout,"site %d lnL: %g:%d %g\n",tree->curr_site,tree->c_lnL_sorted[tree->curr_site],tree->data->wght[tree->curr_site],tree->c_lnL); */
-          /* fflush(stdout); */
+          
+          if(tree->use_eigen_lr == YES)
+            {
+              Lk_Core_Eigen_Lr(expl,dot_prod + site*ns*ncatg,NO,b,tree);
+            }
+          else
+            {
+              if(b->rght->tax == YES)
+                Lk_Core(state,ambiguity_check,NO,
+                        b->p_lk_left + site*ns*ncatg,
+                        b->p_lk_tip_r + site*ns,
+                        b->Pij_rr,b,tree);
+              else
+                Lk_Core(state,ambiguity_check,NO,
+                        b->p_lk_left + site*ns*ncatg,
+                        b->p_lk_rght  + site*ns*ncatg,
+                        b->Pij_rr,b,tree);                
+            }
         }
     }
 #endif
 
-/*   Qksort(tree->c_lnL_sorted,NULL,0,n_patterns-1); */
-
-/*   tree->c_lnL = .0; */
-/*   For(tree->curr_site,n_patterns) */
-/*     { */
-/*       tree->c_lnL += tree->c_lnL_sorted[tree->curr_site]; */
-/*     } */
-
-
-  Adjust_Min_Diff_Lk(tree);
-
-//  Print_All_Edge_PMats(tree);
-//  Print_All_Edge_Likelihoods(tree);
-//  DUMP_D(tree->c_lnL);
-
   return tree->c_lnL;
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
-
-/* Core of the likelihood calculcation. Assume that the partial likelihoods on both
-   sides of t_edge *b are up-to-date. Calculate the log-likelihood at one site.
-*/
-
-phydbl Lk_Core(int state, int ambiguity_check, t_edge *b, t_tree *tree)
+// First and second derivative of the log-likelihood with respect
+// to the length of edge b
+phydbl dLk(phydbl *l, t_edge *b, t_tree *tree)
 {
-  phydbl log_site_lk;
-  phydbl site_lk_cat/*rate specific site lk*/, site_lk, inv_site_lk;
-  int fact_sum_scale;
-  phydbl sum;
-  int catg/*Index of the current rate classes*/,ns/*size of the state-space*/,k,l,site/*index of the current site in the MSA*/;
-  int dim1,dim2,dim3;
-  int exponent;
-  int num_prec_issue;
-
-#ifdef BEAGLE
-  dim1 = tree->n_pattern * tree->mod->ns;
-#else
-  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
-#endif
-  dim2 = tree->mod->ns;
-  dim3 = tree->mod->ns * tree->mod->ns;//Dimensions of the transition prob. matrix
-  
-  log_site_lk     = .0;
-  site_lk         = .0;
-  site_lk_cat     = .0;
-  site            = tree->curr_site;
-  ns              = tree->mod->ns;
-  
+  unsigned int catg,state,site;
+  phydbl len,rr;
+  phydbl lk,dlk,d2lk,dlnlk,d2lnlk;
+  phydbl ev,expevlen;
+   
+  const unsigned int ns = tree->mod->ns;
+  const unsigned int ncatg = tree->mod->ras->n_catg;
+  const unsigned int npattern = tree->n_pattern;
+
+  phydbl *dot_prod = tree->dot_prod;
+  phydbl *expl = tree->expl;
+  phydbl *expld = expl + 1*ncatg*ns;
+  phydbl *expld2 = expl + 2*ncatg*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)
-    {
-      /* Actual likelihood calculation */
-      /* For all classes of rates */
-      For(catg,tree->mod->ras->n_catg)
-        {
-          site_lk_cat = .0;
-
-          /* b is an external edge */
-          if((b->rght->tax) && (!tree->mod->s_opt->greedy)) /* By convention, tips are always on the right of an external edge */
-            {
-              if(!ambiguity_check)/* If the character observed at the tip is NOT ambiguous: ns x 1 terms to consider */
-                {
-                  sum = .0;
-                  For(l,ns)
-                    {
-                      sum +=
-                        b->Pij_rr[(catg*dim3)+(state*dim2)+l] *
-                        b->p_lk_left[(site*dim1)+(catg*dim2)+l];
-                    }
-                  
-                  site_lk_cat += sum * tree->mod->e_frq->pi->v[state];
-                }
-              else /* If the character observed at the tip is ambiguous: ns x ns terms to consider */
-                {
-                  For(k,ns)
-                    {
-                      sum = .0;
-                      if(b->p_lk_tip_r[site*dim2+k] > .0) /* Only bother ascending into the subtrees if the likelihood of state k, at site "site*dim2" is > 0 */
-                        {
-                          For(l,ns)
-                            {
-                              sum +=
-                                b->Pij_rr[(catg*dim3)+(k*dim2)+l] *
-                                b->p_lk_left[(site*dim1)+(catg*dim2)+l];
-                            }
-                          
-                          site_lk_cat +=
-                            sum *
-                            tree->mod->e_frq->pi->v[k] *
-                            b->p_lk_tip_r[site*dim2+k];
-                        }
-                    }
-                }
-            }
-          else /* b is an internal edge: ns x ns terms to consider */
-            {
-              For(k,ns)
-                {
-                  sum = .0;
-                  if(b->p_lk_rght[(site*dim1)+(catg*dim2)+k] > .0) //Only bother descending into the subtrees if the likelihood of state k, at site "site*dim2" is > 0
-                    {
-                      For(l,ns)
-                        {
-                          sum +=
-                            b->Pij_rr[(catg*dim3)+(k*dim2)+l] *     //"catg*dim3" offsets into a rate-specific flat 4*4 DNA matrix P. Then, P[i,j] is given by "k*4+l"
-                            b->p_lk_left[(site*dim1)+(catg*dim2)+l];//"site*dim1" offsets into a rate-specific flat num_rates*4 matrix L. Then, L[i,j] is given by "catg*dim2+l"
-                        }
-                      
-                      site_lk_cat +=
-                        sum *
-                        tree->mod->e_frq->pi->v[k] *
-                        b->p_lk_rght[(site*dim1)+(catg*dim2)+k];
-                    }
-                }
-            }
-          
-          tree->site_lk_cat[catg] = site_lk_cat;
-          
-        } /* site likelihood for all rate classes */
-      Pull_Scaling_Factors(site,b,tree);
-    }
+  assert(isnan(*l) == FALSE);
 
-  fact_sum_scale = tree->fact_sum_scale[site];
+  if(*l < tree->mod->l_min)      *l = tree->mod->l_min;
+  else if(*l > tree->mod->l_max) *l = tree->mod->l_max;      
 
 
-  //Likelihood of the site; is the sum of the individual rate specific likelihoods
-  site_lk = .0;
-  For(catg,tree->mod->ras->n_catg)
-    {
-      site_lk +=
-        tree->unscaled_site_lk_cat[catg*tree->n_pattern + site]* 
-        tree->mod->ras->gamma_r_proba->v[catg]; //density
-    }
+  assert(b != NULL);
   
-  if(tree->mod->ras->invar == YES)
+  if(tree->is_mixt_tree == YES)
     {
-      num_prec_issue = NO;
-      inv_site_lk = Invariant_Lk(fact_sum_scale,site,&num_prec_issue,tree);
-      
-      if(num_prec_issue == YES) // inv_site_lk >> site_lk
-        {
-          site_lk = inv_site_lk * tree->mod->ras->pinvar->v;
-        }
-      else
-        {
-          site_lk = site_lk * (1. - tree->mod->ras->pinvar->v) + inv_site_lk * tree->mod->ras->pinvar->v;
-        }          
+#ifdef BEAGLE
+      Warn_And_Exit(TODO_BEAGLE);
+#endif
+      return MIXT_dLk(l,b,tree);
     }
+    
+  if(tree->update_eigen_lr == YES) Update_Eigen_Lr(b,tree);
   
-  log_site_lk = LOG(site_lk) - (phydbl)LOG2 * fact_sum_scale; // log_site_lk =  log(site_lk_scaled / 2^(left_subtree+right_subtree))      
-  
-  // Calculation of the site likelihood (using scaling factors)...
-  int piecewise_exponent;
-  phydbl multiplier;
-  if(fact_sum_scale >= 0)
+  for(catg=0;catg<ncatg;catg++)
     {
-      tree->cur_site_lk[site] = site_lk;
-      exponent = -fact_sum_scale;
-      do
+      rr = tree->mod->ras->gamma_rr->v[catg];
+      rr *=  tree->mod->br_len_mult->v;      
+
+      len = (*l) * rr;
+            
+      if(isinf(len) || isnan(len)) 
         {
-          piecewise_exponent = MAX(exponent,-63);
-          multiplier = 1. / (phydbl)((unsigned long long)(1) << -piecewise_exponent);
-          tree->cur_site_lk[site] *= multiplier;
-          exponent -= piecewise_exponent;
+          PhyML_Printf("\n== len=%f rr=%f l=%f",len,rr,*l);
+          Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
         }
-      while(exponent != 0);
-    }
-  else
-    {
-      //In some cases fact_sum_scale can be negative. If you rescale the partials of two independent subtrees and make some of
-      //these numbers large in order to avoid underflow, then there is a chance that when multiplied them together you will
-      //get an overflow, in which case fact_sum_scale can become negative.
+
+      if(len < tree->mod->l_min)      len = tree->mod->l_min;
+      else if(len > tree->mod->l_max) len = tree->mod->l_max;      
+      // value of rr should be corrected too if any of these two conditions
+      // is true. Leads to numerical precision issues though...
       
-      tree->cur_site_lk[site] = site_lk;
-      exponent = fact_sum_scale;
-      do
+      
+      for(state=0;state<ns;++state) 
         {
-          piecewise_exponent = MIN(exponent,63);
-          multiplier = (phydbl)((unsigned long long)(1) << piecewise_exponent);
-          tree->cur_site_lk[site] *= multiplier;
-          exponent -= piecewise_exponent;
+          ev = log(tree->mod->eigen->e_val[state]);
+          expevlen = exp(ev*len);
+
+          expl[0*ncatg*ns + catg*ns + state] = expevlen;
+          expl[1*ncatg*ns + catg*ns + state] = expevlen*ev*rr;
+          expl[2*ncatg*ns + catg*ns + state] = expevlen*ev*ev*rr*rr;
         }
-      while(exponent != 0);
     }
   
-  // ... or using the log-likelihood
-  if(isinf(site_lk) || isnan(site_lk))
-    {
-      tree->cur_site_lk[site] = EXP(log_site_lk);
-    }
+
+  dlnlk       = 0.0;
+  d2lnlk      = 0.0;
+  tree->c_lnL = .0;
   
-  if(isinf(log_site_lk) || isnan(log_site_lk))
-    {
-      PhyML_Printf("\n== Site = %d",site);
-      PhyML_Printf("\n== Invar = %d",tree->data->invar[site]);
-      PhyML_Printf("\n== Mixt = %d",tree->is_mixt_tree);
-      PhyML_Printf("\n== Lk = %G log(Lk) = %f < %G",site_lk,log_site_lk,-BIG);
-      For(catg,tree->mod->ras->n_catg) PhyML_Printf("\n== rr=%f p=%f",tree->mod->ras->gamma_rr->v[catg],tree->mod->ras->gamma_r_proba->v[catg]);
-      PhyML_Printf("\n== Pinv = %G",tree->mod->ras->pinvar->v);
-      PhyML_Printf("\n== Bl mult = %G",tree->mod->br_len_mult->v);
-      PhyML_Printf("\n== fact_sum_scale = %d",fact_sum_scale);
-      PhyML_Printf("\n== n_catg: %d",tree->mod->ras->n_catg);
+  for(site=0;site<npattern;++site)
+    {
+      tree->curr_site = site;
+      
+      dlk   = Lk_Core_Eigen_Lr(expld ,dot_prod + site*ns*ncatg,YES,b,tree);
+      d2lk  = Lk_Core_Eigen_Lr(expld2,dot_prod + site*ns*ncatg,YES,b,tree);
+      lk    = Lk_Core_Eigen_Lr(expl  ,dot_prod + site*ns*ncatg,NO ,b,tree);
+
+      /* printf("\n. site: %4d l:%15G lk:%15G dlk:%15G d2lk:%15G",site,b->l->v,lk,dlk,d2lk); */
       
-      if(tree->mod->whichmodel == GTR || tree->mod->whichmodel == CUSTOM)
+      if(!(lk > 0.0))
         {
+          /* PhyML_Printf("\n== dlk: %G d2lk: %G lk: %G",dlk,d2lk,lk); */
+          int l;
           int i,j;
-          PhyML_Printf("\n== Rate matrix\n");
-          For(i,tree->mod->ns)
+          phydbl *U,*V,*Q;
+          printf("\n== l: %G dlk: %G d2lk: %G lk: %G",b->l->v,dlk,d2lk,lk);
+          lk = 0.0;
+          for(l=0;l<ns;++l)
             {
-              For(j,tree->mod->ns)
-                {
-                  PhyML_Printf("%12G ",i,tree->mod->r_mat->qmat->v[i*4+j]); 
-                }
-              PhyML_Printf("\n");
+              lk += dot_prod[site*ns*ncatg+l] * expl[l];
+              printf("\n== lk: %12G dot_prod: %12G expl: %12G left: %12G rght: %12G",
+                     lk,dot_prod[site*ns*ncatg+l],expl[l],
+                     b->p_lk_left[site*ns*ncatg + catg*ns + l],
+                     b->rght->tax ? b->p_lk_tip_r[site*ns + l] : b->p_lk_rght[site*ns*ncatg + catg*ns + l]);
             }
-          fflush(NULL);
+          printf("\n== U\n");
+          U = tree->mod->eigen->r_e_vect;
+          for(i=0;i<ns;i++) { for(j=0;j<ns;j++) printf("%12G ",U[i*ns+j]); printf("\n"); }
+          printf("\n");
+          printf("\n== V\n");
+          V = tree->mod->eigen->l_e_vect;
+          for(i=0;i<ns;i++) { for(j=0;j<ns;j++) printf("%12G ",V[i*ns+j]); printf("\n"); }
+          printf("\n");
+          printf("\n== exp(D)\n");
+          for(i=0;i<ns;i++) printf("%12G\n",tree->mod->eigen->e_val[i]);
+          printf("\n");
+          printf("\n== Q\n");
+          Q = tree->mod->r_mat->qmat->v;
+          for(i=0;i<ns;i++) { for(j=0;j<ns;j++) printf("%12G ",Q[i*ns+j]); printf("\n"); }
+          printf("\n");
+          printf("\n== F\n");
+          for(i=0;i<ns;i++) printf("f(%3d)=%12G\n",i,tree->mod->e_frq->pi->v[i]); 
+          printf("\n\n. tstv : %G",tree->mod->kappa->v);
           
-          PhyML_Printf("\n== Relative rates\n");
-          For(i,tree->mod->ns*(tree->mod->ns-1)/2)
+          for(catg=0;catg<ncatg;++catg)
             {
-              PhyML_Printf("\n== rr[%3d]: %12G %12G",i,tree->mod->r_mat->rr->v[i],tree->mod->r_mat->rr_val->v[i]); 
+              for(state=0;state<ns;++state) 
+                {
+                  printf("\n== catg: %3d state: %3d -- expl: %12G expld: %12G expld2: %12G dot_prod: %12G",
+                         catg,
+                         state,
+                         expl[0*ncatg*ns + catg*ns + state], 
+                         expl[1*ncatg*ns + catg*ns + state], 
+                         expl[2*ncatg*ns + catg*ns + state],
+                         dot_prod[site*ns*ncatg]);
+                }
             }
-          fflush(NULL);
           
+          fflush(NULL);
+          assert(FALSE);
         }
-      
-      /* int i; */
-      /* For(i,2*tree->n_otu-3) */
-      /* 	{ */
-      /* 	  PhyML_Printf("\n. b%3d->l->v = %f %f [%G] %f %f %f %f [%s]",i, */
-      /* 		       tree->a_edges[i]->l->v, */
-      /* 		       tree->a_edges[i]->gamma_prior_mean, */
-      /* 		       tree->a_edges[i]->gamma_prior_var, */
-      /* 		       tree->rates->nd_t[tree->a_edges[i]->left->num], */
-      /* 		       tree->rates->nd_t[tree->a_edges[i]->rght->num], */
-      /* 		       tree->rates->br_r[tree->a_edges[i]->left->num], */
-      /* 		       tree->rates->br_r[tree->a_edges[i]->rght->num], */
-      /* 		       tree->a_edges[i] == tree->e_root ? "YES" : "NO"); */
-      /* 	  fflush(NULL); */
-      
-      /* 	} */
-      
-      Print_Site(tree->data,site,tree->n_otu,"\n",tree->mod->io->state_len,stdout);
-      PhyML_Printf("\n== Err. in file %s at line %d (function '%s')",__FILE__,__LINE__,__FUNCTION__);
-      Exit("\n");
-    }
 
-/* Multiply log likelihood by the number of times this site pattern is found in the data */
-  tree->c_lnL_sorted[site] = tree->data->wght[site]*log_site_lk;
-  
-  tree->c_lnL += tree->data->wght[site]*log_site_lk;
+      dlk /= lk;
+      d2lk /= lk;
+
+      dlnlk  += tree->data->wght[site] * dlk;
+      d2lnlk += tree->data->wght[site] * d2lk - dlk*dlk;     
+    }
 
+  tree->c_dlnL  = dlnlk;
+  tree->c_d2lnL = d2lnlk;
 
-  return log_site_lk;
+  return tree->c_lnL;
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-/* phydbl Lk_At_Given_Edge(t_edge *b_fcus, t_tree *tree) */
-/* { */
-/*   int n_patterns; */
-
-/*   if(tree->is_mixt_tree) return MIXT_Lk_At_Given_Edge(tree); */
-
-/*   n_patterns = tree->n_pattern; */
-
-/* #ifdef PHYTIME */
-/*   if((tree->rates) && (tree->rates->bl_from_rt)) RATES_Update_Cur_Bl(tree); */
-/* #endif */
-
-/*   Check_Br_Len_Bounds(tree); */
-
-/*   if(tree->rates && tree->io->lk_approx == NORMAL) */
-/*     { */
-/*       tree->c_lnL = Lk_Normal_Approx(tree); */
-/*       return tree->c_lnL; */
-/*     } */
-
-/*   Update_PMat_At_Given_Edge(b_fcus,tree); */
-
-/*   if(b_fcus->left->tax) */
-/*     { */
-/*       PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); */
-/*       Warn_And_Exit(""); */
-/*     } */
-
-/*   tree->c_lnL             = .0; */
-/*   tree->sum_min_sum_scale = .0; */
-/*   For(tree->curr_site,n_patterns) */
-/*     if(tree->data->wght[tree->curr_site] > SMALL)  */
-/*       Lk_Core(b_fcus,tree); */
+/* Core of the likelihood calculation. Assume that the partial likelihoods on both
+   sides of t_edge *b are up-to-date. Calculate the log-likelihood at one site.
+   Note: this function can be used to evaluate first or second derivative of the 
+   likelihood function with respect to the length of b, at a given site. Hence, be
+   careful with the meaning of 'site_lk'. If 'derivative=TRUE', then site_lk is 
+   either the first or second derivative of the likelihood at that site, given the
+   length of edge 'b'.
+*/
 
-/* /\*   Qksort(tree->c_lnL_sorted,NULL,0,n_patterns-1); *\/ */
+phydbl Lk_Core(int state, int ambiguity_check, short int derivative,
+               phydbl *p_lk_left, phydbl *p_lk_rght,
+               phydbl *Pij_rr,
+               t_edge *b,
+               t_tree *tree)
+{
+  phydbl site_lk,res,*pi;
+  unsigned int catg;
+  int num_prec_issue;
+  
+  const unsigned int ns    = tree->mod->ns;
+  const unsigned int ncatg = tree->mod->ras->n_catg;
+  const unsigned int site  = tree->curr_site;  
+  const unsigned nsns      = ns*ns;
 
-/* /\*   tree->c_lnL = .0; *\/ */
-/* /\*   For(tree->curr_site,n_patterns) *\/ */
-/* /\*     { *\/ */
-/* /\*       tree->c_lnL += tree->c_lnL_sorted[tree->curr_site]; *\/ */
-/* /\*     } *\/ */
+  pi = tree->mod->e_frq->pi->v;
+  
+  if(tree->mod->s_opt->skip_tree_traversal == NO)
+    {
+      for(catg=0;catg<ncatg;++catg)
+        {
+#if (defined(__AVX__))
+          tree->site_lk_cat[catg] = AVX_Lk_Core_One_Class_No_Eigen_Lr(p_lk_left + catg*ns,
+                                                                      (b->rght->tax) ? (p_lk_rght) : (p_lk_rght + catg*ns),
+                                                                      Pij_rr + catg*nsns,
+                                                                      pi,ns, ambiguity_check, state);
+          
+#elif (defined(__SSE3__))
+          tree->site_lk_cat[catg] = SSE_Lk_Core_One_Class_No_Eigen_Lr(p_lk_left + catg*ns,
+                                                                      (b->rght->tax) ? (p_lk_rght) : (p_lk_rght + catg*ns),
+                                                                      Pij_rr + catg*nsns,
+                                                                      pi,ns, ambiguity_check, state);
+#else
+          tree->site_lk_cat[catg] = Lk_Core_One_Class_No_Eigen_Lr(p_lk_left + catg*ns,
+                                                                  (b->rght->tax) ? (p_lk_rght) : (p_lk_rght + catg*ns),
+                                                                  Pij_rr + catg*nsns,
+                                                                  pi,ns, ambiguity_check, state);
+#endif
 
 
-/*   Adjust_Min_Diff_Lk(tree); */
+          /* printf("\n\u2022 site: %4d lk: %15G class: %3d", */
+          /*        site, */
+          /*        tree->site_lk_cat[catg], */
+          /*        catg); */
 
-/*   return tree->c_lnL; */
-/* } */
+        }
 
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
+      Pull_Scaling_Factors(site,b,tree);
 
-/////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
+    }
 
-void Rate_Correction(int exponent, phydbl *site_lk_cat, t_tree *tree)
-{
-  int piecewise_exponent;
-  phydbl multiplier;
+  site_lk = .0;
+  for(catg=0;catg<ncatg;++catg) site_lk += tree->unscaled_site_lk_cat[site*ncatg + catg] * tree->mod->ras->gamma_r_proba->v[catg];
 
-  if(exponent >= 0)
-    {
-      /*! Multiply by 2^exponent */
-      do
-        {
-          piecewise_exponent = MIN(exponent,63);
-          multiplier = (phydbl)((unsigned long long)(1) << piecewise_exponent);
-          (*site_lk_cat) *= multiplier;
-          exponent -= piecewise_exponent;
-        }
-      while(exponent != 0);
-    }
-  else
+  if(tree->mod->ras->invar == YES && derivative == NO)
     {
-      do
+      num_prec_issue = NO;
+      phydbl inv_site_lk = Invariant_Lk(tree->fact_sum_scale[site],site,&num_prec_issue,tree);
+
+      switch(num_prec_issue)
         {
-          piecewise_exponent = MAX(exponent,-63);
-          multiplier = 1. / (phydbl)((unsigned long long)(1) << -piecewise_exponent);
-          (*site_lk_cat) *= multiplier;
-          exponent -= piecewise_exponent;
+        case YES :         
+          {
+            site_lk = inv_site_lk * tree->mod->ras->pinvar->v;
+            break;
+          }
+        case NO : 
+          {
+            site_lk = site_lk * (1. - tree->mod->ras->pinvar->v) + inv_site_lk * tree->mod->ras->pinvar->v;
+            break;
+          }
         }
-      while(exponent != 0);
-    }
-
-  if(isinf(*site_lk_cat))
-    {
-      PhyML_Printf("\n== Numerical precision issue alert.");
-      PhyML_Printf("\n== exponent: %d site_lk_cat: %f", exponent,*site_lk_cat);
-      PhyML_Printf("\n== File %s at line %d\n\n",__FILE__,__LINE__);
-      (*site_lk_cat) = BIG / 10;
     }
   
-  if(*site_lk_cat < SMALL)
+  // likelihood (or 1st, 2nd derivative) not rescaled here. Valid only if all partial likelihoods
+  // were scaled using the same factor, i.e., when scaling_method == SCALE_FAST. In this case, the
+  // scaling factors will cancel out in dlk/lk and d2lk/lk
+  res = site_lk;
+  
+  if(derivative == NO)
     {
-      if(tree->mod->ras->n_catg == 1)
-        {
-          PhyML_Printf("\n== site_lk_cat = %G",*site_lk_cat);
-          PhyML_Printf("\n== exponent: %d", exponent);
-          PhyML_Printf("\n== Numerical precision issue alert.");
-          PhyML_Printf("\n== File %s at line %d (funtction '%s')\n",__FILE__,__LINE__,__FUNCTION__);
-	  PhyML_Printf("\n== %s",Write_Tree(tree,NO));
-          Exit("\n");
-        }
-      (*site_lk_cat) = .0;
+      phydbl log_site_lk;
+      log_site_lk = log(site_lk) - (phydbl)LOG2 * tree->fact_sum_scale[site]; // log_site_lk =  log(site_lk_scaled / 2^(left_subtree+right_subtree))
+      tree->c_lnL_sorted[site] = tree->data->wght[site] * log_site_lk;
+      tree->c_lnL += tree->data->wght[site] * log_site_lk;
+      tree->cur_site_lk[site] = exp(log_site_lk); // note to self : add opt out option to avoid calculating this if not necessary
     }
+
+  /* printf("\n. clnL: %f",tree->c_lnL); */
+  return res;
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-// Returns the scaled likelihood for invariable sites
-phydbl Invariant_Lk(int fact_sum_scale, int site, int *num_prec_issue, t_tree *tree)
+phydbl Lk_Core_Eigen_Lr(phydbl *expl, phydbl *dot_prod, short int derivative, t_edge *b, t_tree *tree)
 {
-  int exponent,piecewise_exponent;
+  phydbl site_lk,res;
+  unsigned int catg;
+  int num_prec_issue;
+  
+  const unsigned int ns    = tree->mod->ns;
+  const unsigned int ncatg = tree->mod->ras->n_catg;
+  const unsigned int site  = tree->curr_site;
+  
+  if(tree->mod->s_opt->skip_tree_traversal == NO)
+    {
+      for(catg=0;catg<ncatg;++catg)
+        {
+#if (defined(__AVX__))
+          tree->site_lk_cat[catg] = AVX_Lk_Core_One_Class_Eigen_Lr(dot_prod + catg*ns,
+                                                                   expl ? (expl + catg*ns) : NULL,
+                                                                   ns);
+#elif (defined(__SSE3__))
+          tree->site_lk_cat[catg] = SSE_Lk_Core_One_Class_Eigen_Lr(dot_prod + catg*ns,
+                                                       expl ? (expl + catg*ns) : NULL,
+                                                       ns);
+#else
+          tree->site_lk_cat[catg] = Lk_Core_One_Class_Eigen_Lr(dot_prod + catg*ns,
+                                                               expl ? (expl + catg*ns) : NULL,
+                                                               ns);
+#endif
+        }
+
+      Pull_Scaling_Factors(site,b,tree);
+
+    }
+  
+  
+  site_lk = .0;
+  for(catg=0;catg<ncatg;++catg) site_lk += tree->unscaled_site_lk_cat[site*ncatg+catg] * tree->mod->ras->gamma_r_proba->v[catg];
+  
+  if(tree->mod->ras->invar == YES && derivative == NO)
+    {
+      num_prec_issue = NO;
+      phydbl inv_site_lk = Invariant_Lk(tree->fact_sum_scale[site],site,&num_prec_issue,tree);
+
+      switch(num_prec_issue)
+        {
+        case YES :
+          {
+            site_lk = inv_site_lk * tree->mod->ras->pinvar->v;
+            break;
+          }
+        case NO :
+          {
+            site_lk = site_lk * (1. - tree->mod->ras->pinvar->v) + inv_site_lk * tree->mod->ras->pinvar->v;
+            break;
+          }
+        }
+    }
+
+  // likelihood (or 1st, 2nd derivative) not rescaled here. Valid only if all partial likelihoods
+  // were scaled using the same factor, i.e., when scaling_method == SCALE_FAST. In this case, the
+  // scaling factors will cancel out in dlk/lk and d2lk/lk
+  res = site_lk;
+  
+  if(derivative == NO)
+    {
+      phydbl log_site_lk;
+      log_site_lk = log(site_lk) - (phydbl)LOG2 * tree->fact_sum_scale[site]; // log_site_lk =  log(site_lk_scaled / 2^(left_subtree+right_subtree))
+      tree->c_lnL_sorted[site] = tree->data->wght[site] * log_site_lk;
+      tree->c_lnL += tree->data->wght[site] * log_site_lk;
+      tree->cur_site_lk[site] = exp(log_site_lk); // note to self : add opt out option to avoid calculating this if not necessary
+    }
+  
+  return res;
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+// Multiply matrices of eigenvectors with partial likelihoods
+// to the left and right of edge b and take the dot-product of
+// the two resulting vectors
+
+void Update_Eigen_Lr(t_edge *b, t_tree *tree)
+{
+  unsigned int site,catg,state,i;
+  int is_ambigu,observed_state;
+  phydbl *dum,*dumdum;
+
+  const unsigned int npattern = tree->n_pattern;
+  const unsigned int ns = tree->mod->ns;
+  const unsigned int ncatg = tree->mod->ras->n_catg;
+
+  const unsigned int dim1 = ncatg * ns;
+  const unsigned int dim2 = ns;
+
+  if(tree->is_mixt_tree == YES)
+    {      
+      MIXT_Update_Eigen_Lr(b,tree);
+      return;
+    }
+
+#if (defined(__AVX__))
+  AVX_Update_Eigen_Lr(b,tree);
+  return;
+#elif (defined(__SSE3__))
+  SSE_Update_Eigen_Lr(b,tree);
+  return;
+#endif
+
+  dum    = (phydbl *)mCalloc(tree->mod->ns,sizeof(phydbl));
+  dumdum = (phydbl *)mCalloc(tree->mod->ns,sizeof(phydbl));
+  
+  assert(tree->update_eigen_lr == YES);
+  
+  observed_state = -1;
+
+  for(site=0;site<npattern;++site)
+    {
+      is_ambigu = YES;
+      if(b->rght->tax == YES) is_ambigu = b->rght->c_seq->is_ambigu[site];
+      if(is_ambigu == NO) observed_state = b->rght->c_seq->d_state[site];
+
+      for(catg=0;catg<ncatg;++catg)
+        {
+          // Dot product left partial likelihood with equilibrium freqs
+          for(state=0;state<ns;++state) dum[state] = b->p_lk_left[site*dim1 + catg*dim2 + state] * tree->mod->e_frq->pi->v[state];
+
+          // Multiply by matrix of right eigen vectors
+          for(state=0;state<ns;++state)
+            {
+              dumdum[state] = 0.0;
+              for(i=0;i<ns;++i)
+                {
+                  dumdum[state] += 
+                    dum[i] * 
+                    tree->mod->eigen->r_e_vect[i*dim2 + state];
+                }
+            }
+
+          for(state=0;state<ns;++state) tree->eigen_lr_left[catg*dim2 + state] = dumdum[state];
+
+          if(b->rght->tax == YES)
+            for(state=0;state<ns;++state) dum[state] = (phydbl)b->p_lk_tip_r[site*dim2 + state]; 
+          else
+            for(state=0;state<ns;++state) dum[state] = b->p_lk_rght[site*dim1 + catg*dim2 + state]; 
+
+          
+          if(is_ambigu == YES)
+            {
+              /* Multiply  matrix of left eigen vectors by vector of partial likelihoods on  */
+              /* the righthand side of b */
+              for(state=0;state<ns;++state)
+                {
+                  dumdum[state] = 0.0;
+                  for(i=0;i<ns;i++)
+                    {
+                      dumdum[state] += 
+                        tree->mod->eigen->l_e_vect[state*dim2 + i] *
+                        dum[i];
+                    }
+                }
+            }
+          else
+            {
+              for(state=0;state<ns;++state)
+                {
+                  dumdum[state] = tree->mod->eigen->l_e_vect[state*dim2 + observed_state] * dum[observed_state];
+                }
+            }
+
+          for(state=0;state<ns;++state) tree->eigen_lr_rght[catg*dim2 + state] = dumdum[state];
+          
+          for(state=0;state<ns;++state)
+            {
+              tree->dot_prod[site*dim1 + catg*dim2 + state] =
+                tree->eigen_lr_rght[catg*dim2 + state] *
+                tree->eigen_lr_left[catg*dim2 + state];
+            }
+        }
+    }
+  Free(dum);
+  Free(dumdum);
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void Rate_Correction(int exponent, phydbl *site_lk_cat)
+{
+  int piecewise_exponent;
+  phydbl multiplier,dum;
+  unsigned long long int one = 1;
+  
+  dum = *site_lk_cat;
+  if(exponent >= 0)
+    {
+      /* Multiply by 2^exponent */
+      do
+        {
+          piecewise_exponent = MIN(exponent,63);
+          multiplier = (phydbl)(one << piecewise_exponent);
+          dum = dum * multiplier;
+          exponent = exponent - piecewise_exponent;
+        }
+      while(exponent != 0);
+    }
+  else
+    {
+      /* Divide by 2^exponent */
+      do
+        {
+          piecewise_exponent = MAX(exponent,-63);
+          multiplier = 1. / (phydbl)(one << -piecewise_exponent);
+          dum = dum * multiplier;
+          exponent = exponent - piecewise_exponent;
+        }
+      while(exponent != 0);
+    }
+
+  *site_lk_cat = dum;
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+phydbl Lk_Core_One_Class_Eigen_Lr(phydbl *dot_prod, phydbl *expl, int ns)
+{
+  unsigned int l;
+  phydbl lk = 0.0;
+  if(expl != NULL) for(l=0;l<ns;++l) lk += dot_prod[l] * expl[l]; 
+  else for(l=0;l<ns;++l) lk += dot_prod[l];
+  return lk;
+}
+
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+phydbl Lk_Core_One_Class_No_Eigen_Lr(phydbl *p_lk_left, phydbl *p_lk_rght, phydbl *Pij,phydbl *pi, int ns, int ambiguity_check, int state)
+{
+  unsigned int l,k;
+  phydbl lk = 0.0;
+  phydbl sum;
+
+    
+  if(ambiguity_check == NO)/* tip case */
+    {      
+      sum = .0;
+      for(l=0;l<ns;++l) sum += Pij[state*ns+l] * p_lk_left[l];               
+      lk += sum * pi[state];
+    }
+  else /* If the character observed at the tip is ambiguous: ns x ns terms to consider */
+    {
+      for(k=0;k<ns;++k)
+        {
+          if(p_lk_rght[k] > .0) /* Only bother ascending into the subtrees if the likelihood of state k, at site "site*dim2" is > 0 */
+            {
+              sum = .0;
+              for(l=0;l<ns;l++) sum += Pij[k*ns+l] * p_lk_left[l];                       
+              lk += sum * pi[k] * p_lk_rght[k];
+            }
+        }
+    } 
+
+  return lk;
+}
+
+/* #endif */
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+// Returns the scaled likelihood for invariable sites
+phydbl Invariant_Lk(int fact_sum_scale, int site, int *num_prec_issue, t_tree *tree)
+{
+  int exponent,piecewise_exponent;
   phydbl multiplier;
   phydbl inv_site_lk = 0.;
   
@@ -944,7 +1167,7 @@ phydbl Invariant_Lk(int fact_sum_scale, int site, int *num_prec_issue, t_tree *t
 
           if(tree->apply_lk_scaling == YES)
             {
-              exponent = fact_sum_scale;
+              exponent = fact_sum_scale;              
               do
                 {
                   piecewise_exponent = MIN(exponent,63);
@@ -961,7 +1184,7 @@ phydbl Invariant_Lk(int fact_sum_scale, int site, int *num_prec_issue, t_tree *t
               int i;
               PhyML_Printf("\n== fact_sum_scale: %d",fact_sum_scale);              
               PhyML_Printf("\n== pi: %f",tree->mod->e_frq->pi->v[tree->data->invar[site]]);              
-              For(i,tree->mod->ns) PhyML_Printf("\n== pi %d: %f",i,tree->mod->e_frq->pi->v[i]);
+              for(i=0;i<tree->mod->ns;i++) PhyML_Printf("\n== pi %d: %f",i,tree->mod->e_frq->pi->v[i]);
               PhyML_Printf("\n== Numerical precision issue alert.");
               PhyML_Printf("\n== File %s at line %d (function '%s')\n",__FILE__,__LINE__,__FUNCTION__);
               (*num_prec_issue) = YES;
@@ -973,22 +1196,20 @@ 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.
 */
 
-void Update_P_Lk(t_tree *tree, t_edge *b, t_node *d)
+void Update_Partial_Lk(t_tree *tree, t_edge *b, t_node *d)
 {
-
+  if(tree->eval_alnL == NO) return;
+  
   if(tree->is_mixt_tree)
     {
-      MIXT_Update_P_Lk(tree,b,d);
+      MIXT_Update_Partial_Lk(tree,b,d);
       return;
     }
   
@@ -1003,32 +1224,38 @@ void Update_P_Lk(t_tree *tree, t_edge *b, t_node *d)
 #else
   if(tree->mod->use_m4mod == NO)
     {
-      if(tree->io->datatype == NT)
-        {
-          Update_P_Lk_Nucl(tree,b,d);
-        }
-      else if(tree->io->datatype == AA)
+      if(tree->io->datatype == NT ||
+         tree->io->datatype == AA)
         {
-          Update_P_Lk_AA(tree,b,d);
+#if (defined(__AVX__))
+          AVX_Update_Partial_Lk(tree,b,d);
+#elif (defined(__SSE3__))
+          SSE_Update_Partial_Lk(tree,b,d);
+#else
+          Default_Update_Partial_Lk(tree,b,d);
+#endif
         }
       else
         {
-          Update_P_Lk_Generic(tree,b,d);
+          Update_Partial_Lk_Generic(tree,b,d);
         }
     }
   else
     {
-      Update_P_Lk_Generic(tree,b,d);
+      Update_Partial_Lk_Generic(tree,b,d);
     }
 #endif
-//  Print_Edge_Likelihoods(tree, b, false);
+
+
+  //  Print_Edge_Likelihoods(tree, b, false);
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
 #ifndef BEAGLE
-void Update_P_Lk_Generic(t_tree *tree, t_edge *b, t_node *d)
+
+void Update_Partial_Lk_Generic(t_tree *tree, t_edge *b, t_node *d)
 {
 /*
            |
@@ -1044,6 +1271,7 @@ void Update_P_Lk_Generic(t_tree *tree, t_edge *b, t_node *d)
   phydbl p1_lk1,p2_lk2;
   phydbl *p_lk,*p_lk_v1,*p_lk_v2;
   phydbl *Pij1,*Pij2;
+  phydbl *tPij1,*tPij2;
   int *sum_scale, *sum_scale_v1, *sum_scale_v2;
   int sum_scale_v1_val, sum_scale_v2_val;
   int i,j;
@@ -1051,18 +1279,22 @@ void Update_P_Lk_Generic(t_tree *tree, t_edge *b, t_node *d)
   int n_patterns;
   short int ambiguity_check_v1,ambiguity_check_v2;
   int state_v1,state_v2;
-  int NsNg, Ns, NsNs;
-  phydbl curr_scaler;
-  int curr_scaler_pow, piecewise_scaler_pow;
-  phydbl p_lk_lim_inf;
-  phydbl smallest_p_lk;
+  phydbl smallest_p_lk,largest_p_lk;
   int *p_lk_loc;
 
-  p_lk_lim_inf = (phydbl)P_LK_LIM_INF;
+  unsigned const int ncatg = tree->mod->ras->n_catg;
+  unsigned const int ns = tree->mod->ns;
+  unsigned const int ncatgns = ncatg * ns;
+  unsigned const int nsns = ns * ns;
+  
+
+  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);
+    }
 
-  NsNg = tree->mod->ras->n_catg * tree->mod->ns;
-  Ns = tree->mod->ns;
-  NsNs = tree->mod->ns * tree->mod->ns;
 
   state_v1 = state_v2 = -1;
   ambiguity_check_v1 = ambiguity_check_v2 = NO;
@@ -1081,17 +1313,18 @@ void Update_P_Lk_Generic(t_tree *tree, t_edge *b, t_node *d)
   n_v1 = n_v2                 = NULL;
   p_lk = p_lk_v1 = p_lk_v2    = NULL;
   Pij1 = Pij2                 = NULL;
+  tPij1 = tPij2               = NULL;
   sum_scale_v1 = sum_scale_v2 = NULL;
   p_lk_loc                    = NULL;
 
-  Set_All_P_Lk(&n_v1,&n_v2,
-               &p_lk,&sum_scale,&p_lk_loc,
-               &Pij1,&p_lk_v1,&sum_scale_v1,
-               &Pij2,&p_lk_v2,&sum_scale_v2,
-               d,b,tree);
+  Set_All_Partial_Lk(&n_v1,&n_v2,
+                     &p_lk,&sum_scale,&p_lk_loc,
+                     &Pij1,&tPij1,&p_lk_v1,&sum_scale_v1,
+                     &Pij2,&tPij2,&p_lk_v2,&sum_scale_v2,
+                     d,b,tree);
 
   /* For every site in the alignment */
-  For(site,n_patterns)
+  for(site=0;site<n_patterns;site++)
     {
       state_v1 = state_v2 = -1;
       ambiguity_check_v1 = ambiguity_check_v2 = NO;
@@ -1103,7 +1336,7 @@ void Update_P_Lk_Generic(t_tree *tree, t_edge *b, t_node *d)
             {
               /* 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*Ns,tree); */
+              /* if(ambiguity_check_v1 == NO) state_v1 = Get_State_From_Partial_Pars(n_v1->b[0]->p_lk_tip_r,site*ns,tree); */
               if(ambiguity_check_v1 == NO) state_v1 = n_v1->c_seq->d_state[site];
             }
 
@@ -1112,7 +1345,7 @@ void Update_P_Lk_Generic(t_tree *tree, t_edge *b, t_node *d)
               /* Is the state at this tip ambiguous? */
               ambiguity_check_v2 = n_v2->c_seq->is_ambigu[site];
               /* ambiguity_check_v2 = tree->data->c_seq[n_v2->num]->is_ambigu[site]; */
-              /* if(ambiguity_check_v2 == NO) state_v2 = Get_State_From_P_Pars(n_v2->b[0]->p_lk_tip_r,site*Ns,tree); */
+              /* if(ambiguity_check_v2 == NO) state_v2 = Get_State_From_Partial_Pars(n_v2->b[0]->p_lk_tip_r,site*ns,tree); */
               if(ambiguity_check_v2 == NO) state_v2 = n_v2->c_seq->d_state[site];
             }
         }
@@ -1123,157 +1356,153 @@ void Update_P_Lk_Generic(t_tree *tree, t_edge *b, t_node *d)
           ambiguity_check_v2 = YES;
         }
 
-      if(p_lk_loc[site] < site) /* Have we seen this pattern before? */
-        {
-          Copy_P_Lk(p_lk,p_lk_loc[site],site,tree);
-          Copy_Scale(sum_scale,p_lk_loc[site],site,tree);
-        }
-      else
+      /* For all the rate classes */
+      for(catg=0;catg<ncatg;catg++)
         {
-          /* For all the rate classes */
-          For(catg,tree->mod->ras->n_catg)
+          if(tree->mod->ras->skip_rate_cat[catg] == YES) continue;
+          
+          smallest_p_lk  =  BIG;
+          
+          /* For all the states at node d */
+          for(i=0;i<tree->mod->ns;i++)
             {
-              if(tree->mod->ras->skip_rate_cat[catg] == YES) continue;
-
-              smallest_p_lk  =  BIG;
-
-              /* For all the states at node d */
-              For(i,tree->mod->ns)
+              p1_lk1 = .0;
+              
+              if(n_v1)
                 {
-                  p1_lk1 = .0;
-
-                  if(n_v1)
+                  /* n_v1 is a tip */
+                  if((n_v1->tax) && (!tree->mod->s_opt->greedy))
                     {
-                      /* n_v1 is a tip */
-                      if((n_v1->tax) && (!tree->mod->s_opt->greedy))
+                      if(ambiguity_check_v1 == NO)
                         {
-                          if(ambiguity_check_v1 == NO)
-                            {
-                              /* For the (non-ambiguous) state at node n_v1 */
-                              p1_lk1 = Pij1[catg*NsNs+i*Ns+state_v1];
-                            }
-                          else
-                            {
-                              /* For all the states at node n_v1 */
-                              For(j,tree->mod->ns)
-                                {
-                                  p1_lk1 += Pij1[catg*NsNs+i*Ns+j] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*Ns+j];
-                                }
-                            }
+                          /* For the (non-ambiguous) state at node n_v1 */
+                          p1_lk1 = Pij1[catg*nsns+i*ns+state_v1];
                         }
-                      /* n_v1 is an internal node */
                       else
                         {
-                          /* For the states at node n_v1 */
-                          For(j,tree->mod->ns)
+                          /* For all the states at node n_v1 */
+                          for(j=0;j<tree->mod->ns;j++)
                             {
-                              p1_lk1 += Pij1[catg*NsNs+i*Ns+j] * p_lk_v1[site*NsNg+catg*Ns+j];
+                              p1_lk1 += Pij1[catg*nsns+i*ns+j] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*ns+j];
                             }
                         }
                     }
+                  /* n_v1 is an internal node */
                   else
                     {
-                      p1_lk1 = 1.0;
+                      /* For the states at node n_v1 */
+                      for(j=0;j<tree->mod->ns;j++)
+                        {
+                          p1_lk1 += Pij1[catg*nsns+i*ns+j] * p_lk_v1[site*ncatgns+catg*ns+j];
+                        }
                     }
-
-                  p2_lk2 = .0;
-
-                  /* We do exactly the same as for node n_v1 but for node n_v2 this time.*/
-                  if(n_v2)
+                }
+              else
+                {
+                  p1_lk1 = 1.0;
+                }
+              
+              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))
                     {
-                      /* n_v2 is a tip */
-                      if((n_v2->tax) && (!tree->mod->s_opt->greedy))
+                      if(ambiguity_check_v2 == NO)
                         {
-                          if(ambiguity_check_v2 == NO)
-                            {
-                              /* For the (non-ambiguous) state at node n_v2 */
-                              p2_lk2 = Pij2[catg*NsNs+i*Ns+state_v2];
-                            }
-                          else
-                            {
-                              /* For all the states at node n_v2 */
-                              For(j,tree->mod->ns)
-                                {
-                                  p2_lk2 += Pij2[catg*NsNs+i*Ns+j] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*Ns+j];
-                                }
-                            }
+                          /* For the (non-ambiguous) state at node n_v2 */
+                          p2_lk2 = Pij2[catg*nsns+i*ns+state_v2];
                         }
-                      /* n_v2 is an internal node */
                       else
                         {
                           /* For all the states at node n_v2 */
-                          For(j,tree->mod->ns)
+                          for(j=0;j<tree->mod->ns;j++)
                             {
-                              p2_lk2 += Pij2[catg*NsNs+i*Ns+j] * p_lk_v2[site*NsNg+catg*Ns+j];
+                              p2_lk2 += Pij2[catg*nsns+i*ns+j] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*ns+j];
                             }
                         }
                     }
+                  /* n_v2 is an internal node */
                   else
                     {
-                      p2_lk2 = 1.0;
+                      /* For all the states at node n_v2 */
+                      for(j=0;j<tree->mod->ns;j++)
+                        {
+                          p2_lk2 += Pij2[catg*nsns+i*ns+j] * p_lk_v2[site*ncatgns+catg*ns+j];
+                        }
                     }
-
-                  p_lk[site*NsNg+catg*Ns+i] = p1_lk1 * p2_lk2;
-
-                  /* 	      PhyML_Printf("\n+ %G",p_lk[site*NsNg+catg*Ns+i]); */
-
-                  if(p_lk[site*NsNg+catg*Ns+i] < smallest_p_lk) smallest_p_lk = p_lk[site*NsNg+catg*Ns+i] ;
                 }
-
+              else
+                {
+                  p2_lk2 = 1.0;
+                }
+              
+              p_lk[site*ncatgns+catg*ns+i] = p1_lk1 * p2_lk2;
+              
+              /* 	      PhyML_Printf("\n+ %G",p_lk[site*ncatgns+catg*ns+i]); */
+              
+            }
+          
+          if(tree->scaling_method == SCALE_RATE_SPECIFIC)
+            {
+              smallest_p_lk = BIG;
+              for(i=0;i<ns;++i)
+                if(p_lk[site*ncatgns+catg*ns+i] < smallest_p_lk)
+                  smallest_p_lk = p_lk[site*ncatgns+catg*ns+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;
-
-              /* 	  PhyML_Printf("\n@ %d",sum_scale[catg*n_patterns+site]); */
-
-              /* Scaling. For details read utilities.h */
-              if(smallest_p_lk < p_lk_lim_inf)
+              sum_scale_v1_val = (sum_scale_v1)?(sum_scale_v1[site*ncatg+catg]):(0);
+              sum_scale_v2_val = (sum_scale_v2)?(sum_scale_v2[site*ncatg+catg]):(0);
+              
+              sum_scale[site*ncatg+catg] = sum_scale_v1_val + sum_scale_v2_val;
+              
+              /* Scaling. We have p_lk_lim_inf = 2^-500. Consider for instance that 
+                 smallest_p_lk = 2^-600, then curr_scaler_pow will be equal to 100, and
+                 each element in the partial likelihood vector will be multiplied by
+                 2^100. */
+              if(smallest_p_lk < (phydbl)P_LK_LIM_INF &&
+                 tree->mod->augmented == NO &&
+                 tree->apply_lk_scaling == YES &&
+                 (n_v1->tax == NO || n_v2->tax == NO))
+                
                 {
-                  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*NsNg+catg*Ns+i] *= curr_scaler;
-
-                          if(p_lk[site*NsNg+catg*Ns+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 (function '%s').",__FILE__,__LINE__,__FUNCTION__);
-                              Warn_And_Exit("\n");
-                            }
-                        }
-                      curr_scaler_pow -= piecewise_scaler_pow;
-                    }
-                  while(curr_scaler_pow != 0);
+                  int curr_scaler_pow;
+                  curr_scaler_pow = (int)(-500.*LOG2-log(smallest_p_lk))/LOG2;
+                  sum_scale[site*ncatg+catg] += curr_scaler_pow;
+                  for(i=0;i<ns;++i) Rate_Correction(curr_scaler_pow, p_lk + site*nsns + catg*ns + i);
+                  
                 }
             }
         }
+      
+      if(tree->scaling_method == SCALE_FAST)
+        {
+          sum_scale_v1_val = (sum_scale_v1)?(sum_scale_v1[site]):(0);
+          sum_scale_v2_val = (sum_scale_v2)?(sum_scale_v2[site]):(0);              
+          sum_scale[site] = sum_scale_v1_val + sum_scale_v2_val;
+          
+          largest_p_lk = -BIG; 
+          for(i=0;i<ns*ncatg;++i)
+            if(p_lk[site*ncatgns+i] > largest_p_lk)
+              largest_p_lk = p_lk[site*ncatgns+i] ;
+          
+          if(largest_p_lk < INV_TWO_TO_THE_LARGE &&
+             tree->mod->augmented == NO &&
+             tree->apply_lk_scaling == YES)
+            {
+              for(i=0;i<ns*ncatg;++i) p_lk[site*ncatgns + i] *= TWO_TO_THE_LARGE;
+              sum_scale[site] += LARGE;
+            }
+        }     
     }
 }
 
-
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-void Update_P_Lk_Nucl(t_tree *tree, t_edge *b, t_node *d)
+void Default_Update_Partial_Lk(t_tree *tree, t_edge *b, t_node *d)
 {
 /*
            |
@@ -1287,37 +1516,40 @@ void Update_P_Lk_Nucl(t_tree *tree, t_edge *b, t_node *d)
 */
   t_node *n_v1, *n_v2;//d's "left" and "right" neighbor nodes
   phydbl p1_lk1,p2_lk2;//Partial likelihood at d's "left" neighbor, d's "right" neighbor
-  phydbl *p_lk,*p_lk_v1,*p_lk_v2;//Partial likelihood vector of node d, d's "left" neighbor, d's "right" neighbor. We fill *p_lk, and assume *p_lk_v1 and *p_lk_v2 are already filled.
+  phydbl *p_lk;
+  phydbl *p_lk_v1,*p_lk_v2;//Partial likelihood vector of node d, d's "left" neighbor, d's "right" neighbor. We fill *p_lk, and assume *p_lk_v1 and *p_lk_v2 are already filled.
   phydbl *Pij1,*Pij2;
+  phydbl *tPij1,*tPij2;
   int *sum_scale, *sum_scale_v1, *sum_scale_v2;
   int sum_scale_v1_val, sum_scale_v2_val;
-  int i;//index over the number of states
-  int catg/*index over the number of rate categories*/,site;
-  int n_patterns;//Number of distinct site patterns
-  short int ambiguity_check_v1,ambiguity_check_v2;
+  unsigned int i,j;
+  unsigned int catg;
+  unsigned int site;
+  int ambiguity_check_v1,ambiguity_check_v2;
   int state_v1,state_v2;
-  int dim1, dim2, dim3;
-  phydbl curr_scaler;
-  int curr_scaler_pow, piecewise_scaler_pow;
+  phydbl smallest_p_lk,largest_p_lk;
   phydbl p_lk_lim_inf;
-  phydbl smallest_p_lk;
-  phydbl p0,p1,p2,p3;
   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
+  
+  const unsigned int ncatg = tree->mod->ras->n_catg;
+  const unsigned int ns = tree->mod->ns;
+  const unsigned int ncatgns = ncatg * 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
+  const unsigned int nsns = ns * ns;//Dimensions of the transition prob. matrix
+  const unsigned int n_patterns = tree->n_pattern;
 
 
-  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
-  dim2 = tree->mod->ns;
-  dim3 = tree->mod->ns * tree->mod->ns;//Dimensions of the transition prob. matrix
+  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);
+    }
 
   state_v1 = state_v2 = -1;
   ambiguity_check_v1 = ambiguity_check_v2 = NO;
   sum_scale_v1_val = sum_scale_v2_val = 0;
   p1_lk1 = p2_lk2 = .0;
-  curr_scaler = .0;
-  curr_scaler_pow = piecewise_scaler_pow = 0;
-
+  
   if(d->tax)
     {
       PhyML_Printf("\n== t_node %d is a leaf...",d->num);
@@ -1325,22 +1557,23 @@ void Update_P_Lk_Nucl(t_tree *tree, t_edge *b, t_node *d)
       Exit("\n");
     }
 
-  n_patterns = tree->n_pattern;
 
+  p_lk_lim_inf                = (phydbl)P_LK_LIM_INF;
   n_v1 = n_v2                 = NULL;
   p_lk = p_lk_v1 = p_lk_v2    = NULL;
   Pij1 = Pij2                 = NULL;
+  tPij1 = tPij2               = NULL;
   sum_scale_v1 = sum_scale_v2 = NULL;
   p_lk_loc                    = NULL;
-  Set_All_P_Lk(&n_v1,&n_v2,
+  Set_All_Partial_Lk(&n_v1,&n_v2,
                &p_lk,&sum_scale,&p_lk_loc,
-               &Pij1,&p_lk_v1,&sum_scale_v1,
-               &Pij2,&p_lk_v2,&sum_scale_v2,
+               &Pij1,&tPij1,&p_lk_v1,&sum_scale_v1,
+               &Pij2,&tPij2,&p_lk_v2,&sum_scale_v2,
                d,b,tree);
 
 
   /* For every site in the alignment */
-  For(site,n_patterns)
+  for(site=0;site<n_patterns;site++)
     {
       state_v1 = state_v2 = -1;
       ambiguity_check_v1 = ambiguity_check_v2 = NO;
@@ -1384,541 +1617,166 @@ void Update_P_Lk_Nucl(t_tree *tree, t_edge *b, t_node *d)
         }
 
 
-      if(p_lk_loc[site] < site)
-        {
-          Copy_P_Lk(p_lk,p_lk_loc[site],site,tree);
-          Copy_Scale(sum_scale,p_lk_loc[site],site,tree);
-        }
-      else
+      /* For all the rate classes */
+      for(catg=0;catg<ncatg;++catg)
         {
-          /* For all the rate classes */
-          For(catg,tree->mod->ras->n_catg)
+          smallest_p_lk  =  BIG;
+          
+          /* For all states at node d */
+          for(i=0;i<ns;++i)
             {
-              smallest_p_lk  =  BIG;
-
-              /* For all states at node d */
-              For(i,tree->mod->ns)
+              if(tree->mod->augmented == YES)
                 {
-                  if(tree->mod->augmented == YES)
-                    {
-                      For(i,tree->mod->ns) p_lk[site*dim1+catg*dim2+i] = 0.0;
-                      i = Assign_State(d->c_seq_anc->state+site*tree->mod->io->state_len,
-                                       tree->io->datatype,
-                                       tree->mod->io->state_len);
-                    }
-
-                  p1_lk1 = .0;
-
-                  if(n_v1)
+                  for(i=0;i<tree->mod->ns;i++) p_lk[site*ncatgns+catg*ns+i] = 0.0;
+                  i = Assign_State(d->c_seq_anc->state+site*tree->mod->io->state_len,
+                                   tree->io->datatype,
+                                   tree->mod->io->state_len);
+                }
+              
+              p1_lk1 = .0;
+              
+              if(n_v1)
+                {
+                  /* n_v1 is a tip */
+                  if((n_v1->tax) && (!tree->mod->s_opt->greedy))
                     {
-                      /* n_v1 is a tip */
-                      if((n_v1->tax) && (!tree->mod->s_opt->greedy))
+                      if(ambiguity_check_v1 == NO)
                         {
-                          if(ambiguity_check_v1 == NO)
-                            {
-                              /* For the (non-ambiguous) state at node n_v1 */
-                              p1_lk1 = Pij1[catg*dim3+i*dim2+state_v1];
-
-                              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__); */
-                              /*   } */
-                            }
-                          else
-                            {
-                              /* For all the states at node n_v1 */
-                              p0=Pij1[catg*dim3+i*dim2+0] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+0];
-                              p1=Pij1[catg*dim3+i*dim2+1] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+1];
-                              p2=Pij1[catg*dim3+i*dim2+2] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+2];
-                              p3=Pij1[catg*dim3+i*dim2+3] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+3];
-                              p1_lk1 = p0+p1+p2+p3;
-
-                              assert(!isnan(p1_lk1));
-
-                              /* if(isnan(p1_lk1)) */
-                              /*   { */
-                              /*     PhyML_Printf("\n== p0=%f p1=%f p2=%f p3=%f",p0,p1,p2,p3); */
-                              /*     PhyML_Printf("\n== Err. in file %s at line %d (function '%s').",__FILE__,__LINE__,__FUNCTION__); */
-                              /*     Exit("\n"); */
-                              /*   } */
-                            }
+                          /* For the (non-ambiguous) state at node n_v1 */
+                          p1_lk1 = Pij1[catg*nsns+i*ns+state_v1];
                         }
-                      /* n_v1 is an internal node */
                       else
                         {
-                          //"catg*dim3" offsets into a rate-specific flat 4*4 DNA matrix P. Then, P[i,j] is given by "i*4+l"
-                          //"site*dim1" offsets into a rate-specific flat num_rates*4 matrix L. Then, L[i,j] is given by "catg*dim2+l"
-                          if(tree->mod->augmented == YES)
-                            {
-                              p1_lk1 = Pij1[catg*dim3+i*dim2+state_v1] * p_lk_v1[site*dim1+catg*dim2+state_v1];
-                            }
-                          else
-                            {
-                              p0=Pij1[catg*dim3+i*dim2+0] * p_lk_v1[site*dim1+catg*dim2+0];
-                              p1=Pij1[catg*dim3+i*dim2+1] * p_lk_v1[site*dim1+catg*dim2+1];
-                              p2=Pij1[catg*dim3+i*dim2+2] * p_lk_v1[site*dim1+catg*dim2+2];
-                              p3=Pij1[catg*dim3+i*dim2+3] * p_lk_v1[site*dim1+catg*dim2+3];
-                              p1_lk1 = p0+p1+p2+p3;
-                            }
-                          if(isnan(p1_lk1))
-                            {
-                              /* PhyML_Printf("\n== p0=%f p1=%f p2=%f p3=%f",p0,p1,p2,p3); */
-                              PhyML_Printf("\n== Err. in file %s at line %d.",__FILE__,__LINE__);
-                              Warn_And_Exit("\n");
-                            }
+                          /* For all the states at node n_v1 */
+                          p1_lk1 = .0;
+                          for(j=0;j<ns;++j) p1_lk1 += Pij1[catg*nsns+i*ns+j] * p_lk_v1[site*ns+j];
                         }
                     }
+                  /* n_v1 is an internal node */
                   else
                     {
-                      p1_lk1 = 1.0;
-                    }
-                  
-                  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))
+                      //"catg*nsns" offsets into a rate-specific flat 4*4 DNA matrix P. Then, P[i,j] is given by "i*4+l"
+                      //"site*ncatgns" offsets into a rate-specific flat num_rates*4 matrix L. Then, L[i,j] is given by "catg*ns+l"
+                      if(tree->mod->augmented == YES)
                         {
-                          if(ambiguity_check_v2 == NO)
-                            {
-                              /* For the (non-ambiguous) state at node n_v2 */
-                              p2_lk2 = Pij2[catg*dim3+i*dim2+state_v2];
-
-                              assert(!isnan(p2_lk2));
-
-                              /* if(isnan(p2_lk2)) */
-                              /*   { */
-                              /*     PhyML_Printf("\n== Tree %d",tree->tree_num); */
-                              /*     PhyML_Printf("\n== catg=%d dim3=%d dim2=%d i=%d state_v2=%d",catg,dim3,dim2,i,state_v2); */
-                              /*     PhyML_Printf("\n== Pij2[0] = %G l = %G",Pij2[0],b->l->v); */
-                              /*     Print_Model(tree->mod); */
-                              /*     Generic_Exit(__FILE__,__LINE__,__FUNCTION__); */
-                              /*   } */
-                            }
-                          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];
-                              p2_lk2 = p0+p1+p2+p3;
-
-                              assert(!isnan(p2_lk2));
-
-                              /* if(isnan(p2_lk2)) */
-                              /*   { */
-                              /*     PhyML_Printf("\n== p0=%f p1=%f p2=%f p3=%f",p0,p1,p2,p3); */
-                              /*     PhyML_Printf("\n== Err. in file %s at line %d.",__FILE__,__LINE__); */
-                              /*     Warn_And_Exit("\n"); */
-                              /*   }                              */
-                            }
+                          p1_lk1 = Pij1[catg*nsns+i*ns+state_v1] * p_lk_v1[site*ncatgns+catg*ns+state_v1];
                         }
-                      /* n_v2 is an internal node */
                       else
                         {
-                          if(tree->mod->augmented == YES)
-                            {
-                              p2_lk2 = Pij2[catg*dim3+i*dim2+state_v2] * p_lk_v2[site*dim1+catg*dim2+state_v2];
-                            }
-                          else
-                            {
-                              /* For all the states at node n_v2 */
-                              p0=Pij2[catg*dim3+i*dim2+0] * p_lk_v2[site*dim1+catg*dim2+0];
-                              p1=Pij2[catg*dim3+i*dim2+1] * p_lk_v2[site*dim1+catg*dim2+1];
-                              p2=Pij2[catg*dim3+i*dim2+2] * p_lk_v2[site*dim1+catg*dim2+2];
-                              p3=Pij2[catg*dim3+i*dim2+3] * p_lk_v2[site*dim1+catg*dim2+3];
-                              p2_lk2 = p0+p1+p2+p3;
-                            }
-
-                          if(isnan(p2_lk2))
-                            {
-                              PhyML_Printf("\n== %f %f",b->l->v,b->l->v*b->l->v*tree->mod->l_var_sigma);
-                              /* PhyML_Printf("\n== p0=%f p1=%f p2=%f p3=%f",p0,p1,p2,p3); */
-                              PhyML_Printf("\n== Pij2[0]=%f Pij2[1]=%f Pij2[2]=%f Pij2[3]=%f",Pij2[catg*dim3+i*dim2+0],Pij2[catg*dim3+i*dim2+1],Pij2[catg*dim3+i*dim2+2],Pij2[catg*dim3+i*dim2+3]);
-                              PhyML_Printf("\n== Err. in file %s at line %d (function '%s').",__FILE__,__LINE__,__FUNCTION__);
-                              Warn_And_Exit("\n");
-                            }
+                          p1_lk1 = 0.0;
+                          for(j=0;j<ns;++j) p1_lk1 += Pij1[catg*nsns+i*ns+j] * p_lk_v1[site*ncatgns+catg*ns+j];
                         }
                     }
-                  else
-                    {
-                      p2_lk2 = 1.0;
-                    }
-                  
-                  /* Partial likelihood of character "i" at site "site" under rate "catg" */
-                  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] ;
-
-                  if(tree->mod->augmented == YES) break;
-
                 }
-              
-              /* 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 && tree->mod->augmented == NO)
+              else
                 {
-                  curr_scaler_pow = (int)(LOG(p_lk_lim_inf)-LOG(smallest_p_lk))/LOG2;
-                  curr_scaler     = (phydbl)((unsigned long long)(1) << curr_scaler_pow);
-                  
-                  sum_scale[catg*n_patterns+site] += curr_scaler_pow;
-                  //                  fprintf(stderr,"\n%d",sum_scale[catg*n_patterns+site]);
-                                        
-                  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] *= 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 (function '%s').",__FILE__,__LINE__,__FUNCTION__);
-                              Exit("\n");
-                            }
-//                              fprintf(stderr,"\n%e",p_lk[site*dim1+catg*dim2+i]);
-                        }
-                      curr_scaler_pow -= piecewise_scaler_pow;
-                    }
-                  while(curr_scaler_pow != 0);
+                  p1_lk1 = 1.0;
                 }
-            }
-        }
-    }
-
-//  fprintf(stdout, "Updated partials:");fflush(stdout);
-//  Dump_Arr_D(p_lk, tree->mod->ras->n_catg*tree->mod->ns*tree->n_pattern);
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-void Update_P_Lk_AA(t_tree *tree, t_edge *b, t_node *d)
-{
-/*
-           |
-           |<- b
-           |
-           d
-          / \
-         /   \
-        /     \
-    n_v1   n_v2
-*/
-  t_node *n_v1, *n_v2;
-  phydbl p1_lk1,p2_lk2;
-  phydbl *p_lk,*p_lk_v1,*p_lk_v2;
-  phydbl *Pij1,*Pij2;
-  int *sum_scale, *sum_scale_v1, *sum_scale_v2;
-  int sum_scale_v1_val, sum_scale_v2_val;
-  int i;
-  int catg,site;
-  int n_patterns;
-  short int ambiguity_check_v1,ambiguity_check_v2;
-  int state_v1,state_v2;
-  int dim1, dim2, dim3;
-  phydbl curr_scaler;
-  int curr_scaler_pow, piecewise_scaler_pow;
-  phydbl p_lk_lim_inf;
-  phydbl smallest_p_lk;
-  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;
-
-  p_lk_lim_inf = (phydbl)P_LK_LIM_INF;
-
-  dim1 = tree->mod->ras->n_catg * tree->mod->ns;
-  dim2 = tree->mod->ns;
-  dim3 = tree->mod->ns * tree->mod->ns;
-
-  state_v1 = state_v2 = -1;
-  ambiguity_check_v1 = ambiguity_check_v2 = NO;
-  sum_scale_v1_val = sum_scale_v2_val = 0;
-  p1_lk1 = p2_lk2 = .0;
-
-  if(d->tax)
-    {
-      PhyML_Printf("\n== t_node %d is a leaf...",d->num);
-      PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__);
-      Warn_And_Exit("\n");
-    }
-
-  n_patterns = tree->n_pattern;
-
-  n_v1 = n_v2                 = NULL;
-  p_lk = p_lk_v1 = p_lk_v2    = NULL;
-  Pij1 = Pij2                 = NULL;
-  sum_scale_v1 = sum_scale_v2 = NULL;
-  p_lk_loc                    = NULL;
-
-  Set_All_P_Lk(&n_v1,&n_v2,
-               &p_lk,&sum_scale,&p_lk_loc,
-               &Pij1,&p_lk_v1,&sum_scale_v1,
-               &Pij2,&p_lk_v2,&sum_scale_v2,
-               d,b,tree);
-
-
-  /* For every site in the alignment */
-  For(site,n_patterns)
-    {
-      state_v1 = state_v2 = -1;
-      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); */
-              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(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);
-          Copy_Scale(sum_scale,p_lk_loc[site],site,tree);
-        }
-      else
-        {
-          /* For all the rate classes */
-          For(catg,tree->mod->ras->n_catg)
-            {
-              smallest_p_lk  =  BIG;
               
-              /* For all the state at node d */
-              For(i,tree->mod->ns)
+              p2_lk2 = .0;
+              
+              /* We do exactly the same as for node n_v1 but for node n_v2 this time.*/
+              if(n_v2)
                 {
-                  p1_lk1 = .0;
-                  
-                  if(n_v1)
+                  /* n_v2 is a tip */
+                  if((n_v2->tax) && (!tree->mod->s_opt->greedy))
                     {
-                      /* n_v1 is a tip */
-                      if((n_v1->tax) && (!tree->mod->s_opt->greedy))
+                      if(ambiguity_check_v2 == NO)
                         {
-                          if(ambiguity_check_v1 == NO)
-                            {
-                              /* For the (non-ambiguous) state at node n_v1 */
-                              p1_lk1 = Pij1[catg*dim3+i*dim2+state_v1];
-                            }
-                          else
-                            {
-                              /* For all the states at node n_v1 */
-                              p0  = Pij1[catg*dim3+i*dim2+ 0] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+ 0];
-                              p1  = Pij1[catg*dim3+i*dim2+ 1] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+ 1];
-                              p2  = Pij1[catg*dim3+i*dim2+ 2] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+ 2];
-                              p3  = Pij1[catg*dim3+i*dim2+ 3] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+ 3];
-                              p4  = Pij1[catg*dim3+i*dim2+ 4] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+ 4];
-                              p5  = Pij1[catg*dim3+i*dim2+ 5] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+ 5];
-                              p6  = Pij1[catg*dim3+i*dim2+ 6] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+ 6];
-                              p7  = Pij1[catg*dim3+i*dim2+ 7] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+ 7];
-                              p8  = Pij1[catg*dim3+i*dim2+ 8] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+ 8];
-                              p9  = Pij1[catg*dim3+i*dim2+ 9] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+ 9];
-                              p10 = Pij1[catg*dim3+i*dim2+10] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+10];
-                              p11 = Pij1[catg*dim3+i*dim2+11] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+11];
-                              p12 = Pij1[catg*dim3+i*dim2+12] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+12];
-                              p13 = Pij1[catg*dim3+i*dim2+13] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+13];
-                              p14 = Pij1[catg*dim3+i*dim2+14] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+14];
-                              p15 = Pij1[catg*dim3+i*dim2+15] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+15];
-                              p16 = Pij1[catg*dim3+i*dim2+16] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+16];
-                              p17 = Pij1[catg*dim3+i*dim2+17] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+17];
-                              p18 = Pij1[catg*dim3+i*dim2+18] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+18];
-                              p19 = Pij1[catg*dim3+i*dim2+19] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+19];
-                              p1_lk1 = p0+p1+p2+p3+p4+p5+p6+p7+p8+p9+p10+p11+p12+p13+p14+p15+p16+p17+p18+p19;
-                            }
+                          /* For the (non-ambiguous) state at node n_v2 */
+                          p2_lk2 = Pij2[catg*nsns+i*ns+state_v2];
                         }
-                      /* n_v1 is an internal node */
                       else
                         {
-                          /* For the states at node n_v1 */
-                          p0  = Pij1[catg*dim3+i*dim2+ 0] * (phydbl)p_lk_v1[site*dim1+catg*dim2+ 0];
-                          p1  = Pij1[catg*dim3+i*dim2+ 1] * (phydbl)p_lk_v1[site*dim1+catg*dim2+ 1];
-                          p2  = Pij1[catg*dim3+i*dim2+ 2] * (phydbl)p_lk_v1[site*dim1+catg*dim2+ 2];
-                          p3  = Pij1[catg*dim3+i*dim2+ 3] * (phydbl)p_lk_v1[site*dim1+catg*dim2+ 3];
-                          p4  = Pij1[catg*dim3+i*dim2+ 4] * (phydbl)p_lk_v1[site*dim1+catg*dim2+ 4];
-                          p5  = Pij1[catg*dim3+i*dim2+ 5] * (phydbl)p_lk_v1[site*dim1+catg*dim2+ 5];
-                          p6  = Pij1[catg*dim3+i*dim2+ 6] * (phydbl)p_lk_v1[site*dim1+catg*dim2+ 6];
-                          p7  = Pij1[catg*dim3+i*dim2+ 7] * (phydbl)p_lk_v1[site*dim1+catg*dim2+ 7];
-                          p8  = Pij1[catg*dim3+i*dim2+ 8] * (phydbl)p_lk_v1[site*dim1+catg*dim2+ 8];
-                          p9  = Pij1[catg*dim3+i*dim2+ 9] * (phydbl)p_lk_v1[site*dim1+catg*dim2+ 9];
-                          p10 = Pij1[catg*dim3+i*dim2+10] * (phydbl)p_lk_v1[site*dim1+catg*dim2+10];
-                          p11 = Pij1[catg*dim3+i*dim2+11] * (phydbl)p_lk_v1[site*dim1+catg*dim2+11];
-                          p12 = Pij1[catg*dim3+i*dim2+12] * (phydbl)p_lk_v1[site*dim1+catg*dim2+12];
-                          p13 = Pij1[catg*dim3+i*dim2+13] * (phydbl)p_lk_v1[site*dim1+catg*dim2+13];
-                          p14 = Pij1[catg*dim3+i*dim2+14] * (phydbl)p_lk_v1[site*dim1+catg*dim2+14];
-                          p15 = Pij1[catg*dim3+i*dim2+15] * (phydbl)p_lk_v1[site*dim1+catg*dim2+15];
-                          p16 = Pij1[catg*dim3+i*dim2+16] * (phydbl)p_lk_v1[site*dim1+catg*dim2+16];
-                          p17 = Pij1[catg*dim3+i*dim2+17] * (phydbl)p_lk_v1[site*dim1+catg*dim2+17];
-                          p18 = Pij1[catg*dim3+i*dim2+18] * (phydbl)p_lk_v1[site*dim1+catg*dim2+18];
-                          p19 = Pij1[catg*dim3+i*dim2+19] * (phydbl)p_lk_v1[site*dim1+catg*dim2+19];
-                          p1_lk1 = p0+p1+p2+p3+p4+p5+p6+p7+p8+p9+p10+p11+p12+p13+p14+p15+p16+p17+p18+p19;
+                          /* For all the states at node n_v2 */
+                          p2_lk2 = 0.0;
+                          for(j=0;j<ns;++j) p2_lk2 += Pij2[catg*nsns+i*ns+j] * p_lk_v2[site*ns+j];
                         }
                     }
+                  /* n_v2 is an internal node */
                   else
                     {
-                      p1_lk1 = 1.0;
-                    }
-
-          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;
+                      if(tree->mod->augmented == YES)
+                        {
+                          p2_lk2 = Pij2[catg*nsns+i*ns+state_v2] * p_lk_v2[site*ncatgns+catg*ns+state_v2];
+                        }
+                      else
+                        {
+                          /* For all the states at node n_v2 */
+                          p2_lk2 = 0.0;
+                          for(j=0;j<ns;j++) p2_lk2 += Pij2[catg*nsns+i*ns+j] * p_lk_v2[site*ncatgns+catg*ns+j];
                         }
                     }
-                  else
-                    {
-                      p2_lk2 = 1.0;
+                }
+              else
+                {
+                  p2_lk2 = 1.0;
+                }
+              
+              /* Partial likelihood of character "i" at site "site" under rate "catg" */
+              p_lk[site*ncatgns+catg*ns+i] = p1_lk1 * p2_lk2;
+              
+              if(tree->mod->augmented == YES) break;
             }
-
-          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)
+          
+          if(tree->scaling_method == SCALE_RATE_SPECIFIC)
             {
-              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)
+              smallest_p_lk = BIG;
+              for(i=0;i<ns;++i)
+                if(p_lk[site*ncatgns+catg*ns+i] < smallest_p_lk)
+                  smallest_p_lk = p_lk[site*ncatgns+catg*ns+i];
+              
+              /* Current scaling values at that site */
+              sum_scale_v1_val = (sum_scale_v1)?(sum_scale_v1[site*ncatg+catg]):(0);
+              sum_scale_v2_val = (sum_scale_v2)?(sum_scale_v2[site*ncatg+catg]):(0);
+              
+              sum_scale[catg*n_patterns+site] = sum_scale_v1_val + sum_scale_v2_val;
+              
+              
+              /* Scaling. We have p_lk_lim_inf = 2^-500. Consider for instance that
+                 smallest_p_lk = 2^-600, then curr_scaler_pow will be equal to 100, and
+                 each element in the partial likelihood vector will be multiplied by
+                 2^100. */
+              if(smallest_p_lk < p_lk_lim_inf &&
+                 tree->mod->augmented == NO &&
+                 tree->apply_lk_scaling == YES &&
+                 (n_v1->tax == NO || n_v2->tax == NO))
                 {
-                  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;
+                  int curr_scaler_pow;
+                  curr_scaler_pow = (int)(-500.*LOG2-log(smallest_p_lk))/LOG2;
+                  sum_scale[site*ncatg+catg] += curr_scaler_pow;
+                  for(i=0;i<ns;++i) Rate_Correction(curr_scaler_pow, p_lk + site*nsns + catg*ns + i);
                 }
-              while(curr_scaler_pow != 0);
             }
         }
-    }
+      
+      if(tree->scaling_method == SCALE_FAST)
+        {
+          sum_scale_v1_val = (sum_scale_v1)?(sum_scale_v1[site]):(0);
+          sum_scale_v2_val = (sum_scale_v2)?(sum_scale_v2[site]):(0);              
+          sum_scale[site] = sum_scale_v1_val + sum_scale_v2_val;
+          
+          largest_p_lk = -BIG; 
+          for(i=0;i<ns*ncatg;++i)
+            if(p_lk[site*ncatgns+i] > largest_p_lk)
+              largest_p_lk = p_lk[site*ncatgns+i] ;
+          
+          if(largest_p_lk < INV_TWO_TO_THE_LARGE &&
+             tree->mod->augmented == NO &&
+             tree->apply_lk_scaling == YES)
+            {
+              for(i=0;i<ns*ncatg;++i) p_lk[site*ncatgns + i] *= TWO_TO_THE_LARGE;
+              sum_scale[site] += LARGE;
+            }
+        }      
     }
 }
+
 #endif
+
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 phydbl Return_Abs_Lk(t_tree *tree)
 {
   Lk(NULL,tree);
@@ -1936,8 +1794,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));
@@ -1957,7 +1815,7 @@ matrix *ML_Dist(calign *data, t_mod *mod)
   else if(mod->io->datatype == AA)      mat = JC69_Dist(data,mod);
   else if(mod->io->datatype == GENERIC) mat = JC69_Dist(data,mod);
 
-  For(i,mod->ras->n_catg) /* Don't use the discrete gamma distribution */
+  for(i=0;i<mod->ras->n_catg;i++) /* Don't use the discrete gamma distribution */
     {
       mod->ras->gamma_rr->v[i]      = 1.0;
       mod->ras->gamma_r_proba->v[i] = 1.0;
@@ -1966,16 +1824,14 @@ matrix *ML_Dist(calign *data, t_mod *mod)
   n_catg = mod->ras->n_catg;
   mod->ras->n_catg = 1;
 
-  For(j,data->n_otu-1)
+  for(j=0;j<data->n_otu-1;j++)
     {
       tmpdata->c_seq[0]       = data->c_seq[j];
       tmpdata->c_seq[0]->name = data->c_seq[j]->name;
       tmpdata->wght           = data->wght;
 
-
       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 +1848,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 +1857,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 +1887,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);
         }
     }
   
@@ -2073,88 +1932,88 @@ phydbl Lk_Given_Two_Seq(calign *data, int numseq1, int numseq2, phydbl dist, t_m
   p_lk_r = (phydbl *)mCalloc(data->c_seq[0]->len * mod->ns,sizeof(phydbl));
 
 
-  For(i,mod->ras->n_catg)
+  for(i=0;i<mod->ras->n_catg;i++)
     {
       len = dist*mod->ras->gamma_rr->v[i];
       if(len < mod->l_min) len = mod->l_min;
       else if(len > mod->l_max) len = mod->l_max;
-      PMat(len,mod,dim2*i,mod->Pij_rr->v);
+      PMat(len,mod,dim2*i,mod->Pij_rr->v,NULL);
     }
-
+  
   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=0;k<mod->ns;k++) {if(p_lk_l[i*mod->ns+k] > .0001) break;}
+              for(l=0;l<mod->ns;l++) {if(p_lk_r[i*mod->ns+l] > .0001) break;}
+              for(j=0;j<mod->ras->n_catg;j++)
+                {
+                  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=0;j<mod->ras->n_catg;j++)
+                {
+                  for(k=0;k<mod->ns;k++) /*sort sum terms ? No global effect*/
+                    {
+                      for(l=0;l<mod->ns;l++)
+                        {
+                          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*/
     }
     }
 
@@ -2171,34 +2030,26 @@ phydbl Lk_Given_Two_Seq(calign *data, int numseq1, int numseq2, phydbl dist, t_m
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 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=0;i<tree->data->crunch_len;i++) 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);
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-void Init_P_Lk_Tips_Double(t_tree *tree)
+void Init_Partial_Lk_Tips_Double(t_tree *tree)
 {
-  int curr_site,i,j,k,dim1,dim2;
+  unsigned int curr_site,i,dim1;
 
-  dim1 = tree->mod->ras->n_catg * tree->mod->ns;
-  dim2 = tree->mod->ns;
+  dim1 = tree->mod->ns;
 
 
-  For(i,tree->n_otu)
+  for(i=0;i<tree->n_otu;i++)
     {
       if(!tree->a_nodes[i]->c_seq || 
 	 strcmp(tree->a_nodes[i]->c_seq->name,tree->a_nodes[i]->name))
@@ -2208,65 +2059,45 @@ void Init_P_Lk_Tips_Double(t_tree *tree)
         }
     }
 
-  For(curr_site,tree->data->crunch_len)
+  for(curr_site=0;curr_site<tree->data->crunch_len;curr_site++)
     {
-      For(i,tree->n_otu)
+      for(i=0;i<tree->n_otu;i++)
         {
           if (tree->io->datatype == NT)
-        /* Init_Tips_At_One_Site_Nucleotides_Float(tree->data->c_seq[i]->state[curr_site], */
-        /* 					    curr_site*dim1+0*dim2, */
-        /* 					    tree->a_nodes[i]->b[0]->p_lk_rght); */
             Init_Tips_At_One_Site_Nucleotides_Float(tree->a_nodes[i]->c_seq->state[curr_site],
-                                                    curr_site*dim1+0*dim2,
-                                                    tree->a_nodes[i]->b[0]->p_lk_rght);
+                                                    curr_site*dim1,
+                                                    tree->a_nodes[i]->b[0]->p_lk_tip_r);
 
           else if(tree->io->datatype == AA)
             Init_Tips_At_One_Site_AA_Float(tree->a_nodes[i]->c_seq->state[curr_site],
-                                           curr_site*dim1+0*dim2,
-                                           tree->a_nodes[i]->b[0]->p_lk_rght);
-        /* Init_Tips_At_One_Site_AA_Float(tree->data->c_seq[i]->state[curr_site], */
-        /* 				   curr_site*dim1+0*dim2, */
-        /* 				   tree->a_nodes[i]->b[0]->p_lk_rght); */
+                                           curr_site*dim1,
+                                           tree->a_nodes[i]->b[0]->p_lk_tip_r);
 
           else if(tree->io->datatype == GENERIC)
             Init_Tips_At_One_Site_Generic_Float(tree->a_nodes[i]->c_seq->state+curr_site*tree->mod->io->state_len,
                                                 tree->mod->ns,
                                                 tree->mod->io->state_len,
-                                                curr_site*dim1+0*dim2,
-                                                tree->a_nodes[i]->b[0]->p_lk_rght);
-        /* Init_Tips_At_One_Site_Generic_Float(tree->data->c_seq[i]->state+curr_site*tree->mod->io->state_len, */
-        /* 					tree->mod->ns, */
-        /* 					tree->mod->io->state_len, */
-        /* 					curr_site*dim1+0*dim2, */
-        /* 					tree->a_nodes[i]->b[0]->p_lk_rght); */
-
-          for(j=1;j<tree->mod->ras->n_catg;j++)
-            {
-              For(k,tree->mod->ns)
-                {
-                  tree->a_nodes[i]->b[0]->p_lk_rght[curr_site*dim1+j*dim2+k] =
-                    tree->a_nodes[i]->b[0]->p_lk_rght[curr_site*dim1+0*dim2+k];
-                }
-            }
+                                                curr_site*dim1,
+                                                tree->a_nodes[i]->b[0]->p_lk_tip_r);
         }
     }
 
   if(tree->mod->use_m4mod)
     {
-      M4_Init_P_Lk_Tips_Double(tree);
+      M4_Init_Partial_Lk_Tips_Double(tree);
     }
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-void Init_P_Lk_Tips_Int(t_tree *tree)
+void Init_Partial_Lk_Tips_Int(t_tree *tree)
 {
   int curr_site,i,dim1;
 
   dim1 = tree->mod->ns;
 
-  For(i,tree->n_otu)
+  for(i=0;i<tree->n_otu;i++)
     {
       if(!tree->a_nodes[i]->c_seq || 
 	 strcmp(tree->a_nodes[i]->c_seq->name,tree->a_nodes[i]->name))
@@ -2276,42 +2107,42 @@ void Init_P_Lk_Tips_Int(t_tree *tree)
         }
     }
 
-  For(curr_site,tree->data->crunch_len)
+  for(curr_site=0;curr_site<tree->data->crunch_len;curr_site++)
     {
-      For(i,tree->n_otu)
+      for(i=0;i<tree->n_otu;i++)
         {
           /* printf("\n. site: %3d %c",curr_site,tree->a_nodes[i]->c_seq->state[curr_site]); */
           /* printf("\n. init at %s %p",tree->a_nodes[i]->name,tree->a_nodes[i]->b[0]->p_lk_tip_r); fflush(NULL); */
           if(tree->io->datatype == NT)
             {
-              Init_Tips_At_One_Site_Nucleotides_Int(tree->a_nodes[i]->c_seq->state[curr_site],
+              Init_Tips_At_One_Site_Nucleotides_Float(tree->a_nodes[i]->c_seq->state[curr_site],
                                                     curr_site*dim1,
                                                     tree->a_nodes[i]->b[0]->p_lk_tip_r);
-          /* Init_Tips_At_One_Site_Nucleotides_Int(tree->data->c_seq[i]->state[curr_site], */
-          /* 					    curr_site*dim1, */
-          /* 					    tree->a_nodes[i]->b[0]->p_lk_tip_r); */
+              /* Init_Tips_At_One_Site_Nucleotides_Int(tree->data->c_seq[i]->state[curr_site], */
+              /* 					    curr_site*dim1, */
+              /* 					    tree->a_nodes[i]->b[0]->p_lk_tip_r); */
             }
           else if(tree->io->datatype == AA)
-            Init_Tips_At_One_Site_AA_Int(tree->a_nodes[i]->c_seq->state[curr_site],
-                         curr_site*dim1,
-                         tree->a_nodes[i]->b[0]->p_lk_tip_r);
-        /* Init_Tips_At_One_Site_AA_Int(tree->data->c_seq[i]->state[curr_site], */
-        /* 				 curr_site*dim1,					    */
-        /* 				 tree->a_nodes[i]->b[0]->p_lk_tip_r); */
-
+            Init_Tips_At_One_Site_AA_Float(tree->a_nodes[i]->c_seq->state[curr_site],
+                                           curr_site*dim1,
+                                           tree->a_nodes[i]->b[0]->p_lk_tip_r);
+          /* Init_Tips_At_One_Site_AA_Int(tree->data->c_seq[i]->state[curr_site], */
+          /* 				 curr_site*dim1,					    */
+          /* 				 tree->a_nodes[i]->b[0]->p_lk_tip_r); */
+          
           else if(tree->io->datatype == GENERIC)
             {
-              Init_Tips_At_One_Site_Generic_Int(tree->a_nodes[i]->c_seq->state+curr_site*tree->mod->io->state_len,
-                            tree->mod->ns,
-                            tree->mod->io->state_len,
-                            curr_site*dim1,
-                            tree->a_nodes[i]->b[0]->p_lk_tip_r);
-
-          /* Init_Tips_At_One_Site_Generic_Int(tree->data->c_seq[i]->state+curr_site*tree->mod->io->state_len, */
-          /* 					tree->mod->ns, */
-          /* 					tree->mod->io->state_len, */
-          /* 					curr_site*dim1, */
-          /* 					tree->a_nodes[i]->b[0]->p_lk_tip_r); */
+              Init_Tips_At_One_Site_Generic_Float(tree->a_nodes[i]->c_seq->state+curr_site*tree->mod->io->state_len,
+                                                  tree->mod->ns,
+                                                  tree->mod->io->state_len,
+                                                  curr_site*dim1,
+                                                  tree->a_nodes[i]->b[0]->p_lk_tip_r);
+              
+              /* Init_Tips_At_One_Site_Generic_Int(tree->data->c_seq[i]->state+curr_site*tree->mod->io->state_len, */
+              /* 					tree->mod->ns, */
+              /* 					tree->mod->io->state_len, */
+              /* 					curr_site*dim1, */
+              /* 					tree->a_nodes[i]->b[0]->p_lk_tip_r); */
             }
 #ifdef BEAGLE
           //Recall that tip partials are stored on the branch leading
@@ -2325,7 +2156,7 @@ void Init_P_Lk_Tips_Int(t_tree *tree)
     }
    if(tree->mod->use_m4mod)
      {
-       M4_Init_P_Lk_Tips_Int(tree);
+       M4_Init_Partial_Lk_Tips_Int(tree);
      }
 }
 
@@ -2339,20 +2170,29 @@ void Update_PMat_At_Given_Edge(t_edge *b_fcus, t_tree *tree)
   phydbl l_min, l_max;
   phydbl shape, scale, mean, var;
 
-  if(tree->is_mixt_tree)
+  assert(b_fcus);
+  assert(tree);
+
+  
+  if(tree->is_mixt_tree == YES)
     {
       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);
+
+  if(b_fcus->l->v < l_min) b_fcus->l->v = l_min;
+  if(b_fcus->l->v > l_max) b_fcus->l->v = l_max;
 
-  For(i,tree->mod->ras->n_catg)
+  for(i=0;i<tree->mod->ras->n_catg;i++)
     {
       if(tree->mod->ras->skip_rate_cat[i] == YES) continue;
       
@@ -2376,7 +2216,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;
@@ -2388,7 +2230,8 @@ void Update_PMat_At_Given_Edge(t_edge *b_fcus, t_tree *tree)
 #ifdef BEAGLE
             assert(UNINITIALIZED != tree->mod->b_inst);
 #endif
-            PMat(len,tree->mod,i*tree->mod->ns*tree->mod->ns,b_fcus->Pij_rr);
+                   
+            PMat(len,tree->mod,i*tree->mod->ns*tree->mod->ns,b_fcus->Pij_rr,b_fcus->tPij_rr);
           }
       else
           {
@@ -2398,7 +2241,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 +2250,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);
@@ -2453,7 +2298,7 @@ void Update_PMat_At_Given_Edge(t_edge *b_fcus, t_tree *tree)
 //////////////////////////////////////////////////////////////
 
 
-/* void Update_P_Lk_On_A_Path(t_node *a, t_node *d, t_edge *b, t_node *target_one_side, t_node *target_other_side, t_tree *tree) */
+/* void Update_Partial_Lk_On_A_Path(t_node *a, t_node *d, t_edge *b, t_node *target_one_side, t_node *target_other_side, t_tree *tree) */
 /* { */
 
 
@@ -2476,12 +2321,12 @@ void Update_PMat_At_Given_Edge(t_edge *b_fcus, t_tree *tree)
 /* /\* 	 target_one_side->num, *\/ */
 /* /\* 	 target_other_side->num); *\/ */
 
-/*   Update_P_Lk(tree,b,a); */
+/*   Update_Partial_Lk(tree,b,a); */
 /*   if((a == target_one_side) && (d == target_other_side))  */
 /*     return; */
 /*   else */
 /*     { */
-/*       Update_P_Lk_On_A_Path(d, */
+/*       Update_Partial_Lk_On_A_Path(d, */
 /* 			    d->v[tree->t_dir[d->num][target_other_side->num]], */
 /* 			    d->b[tree->t_dir[d->num][target_other_side->num]], */
 /* 			    target_one_side, */
@@ -2490,36 +2335,36 @@ 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)
+void Update_Partial_Lk_Along_A_Path(t_node **path, int path_length, t_tree *tree)
 {
   int i,j;
-
-  For(i,path_length-1)
+  
+  for(i=0;i<path_length-1;++i)
     {
-      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)
-          {
-        Update_P_Lk(tree,path[i]->b[j],path[i]->b[j]->rght);
-          }
-        else
+      for(j=0;j<3;++j)
+        if(path[i]->v[j] == path[i+1])
           {
-        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_Partial_Lk(tree,path[i]->b[j],path[i]->b[j]->left);
+              }
+            else if(path[i] == path[i]->b[j]->rght)
+              {
+                Update_Partial_Lk(tree,path[i]->b[j],path[i]->b[j]->rght);
+              }
+            else
+              {
+                PhyML_Printf("\n== Err. in file %s at line %d. \n",__FILE__,__LINE__);
+                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.\n",__FILE__,__LINE__);
+          Exit("");
+        }
 #endif
     }
 }
@@ -2527,70 +2372,81 @@ void Update_P_Lk_Along_A_Path(t_node **path, int path_length, t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 phydbl Lk_Dist(phydbl *F, phydbl dist, t_mod *mod)
 {
   int i,j,k;
   phydbl lnL,len;
   int dim1,dim2;
+  phydbl pi, pijk;
+
+  // 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);
+  if(mod->log_l == YES) dist = exp(dist);
 
-  For(k,mod->ras->n_catg)
+  for(k=0;k<mod->ras->n_catg;k++)
     {
       len = dist*mod->ras->gamma_rr->v[k];
       if(len < mod->l_min)      len = mod->l_min;
       else if(len > mod->l_max) len = mod->l_max;
-      PMat(len,mod,mod->ns*mod->ns*k,mod->Pij_rr->v);
+      PMat(len,mod,mod->ns*mod->ns*k,mod->Pij_rr->v,NULL);
     }
 
   dim1 = mod->ns*mod->ns;
   dim2 = mod->ns;
-  lnL = .0;
+  lnL  = .0;
+  pi   = -1.;
+  pijk = -1.;
 
-/*   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(i=0;i<mod->ns-1;i++)
     {
+      pi = mod->e_frq->pi->v[i];
+
       for(j=i+1;j<mod->ns;j++)
         {
-          For(k,mod->ras->n_catg)
+          for(k=0;k<mod->ras->n_catg;k++)
             {
-              lnL +=
-                (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],  */
+              pijk = mod->Pij_rr->v[dim1*k+dim2*i+j];              
+              lnL += (F[dim1*k+dim2*i+j] + F[dim1*k+dim2*j+i]) * log(pi * pijk);
+
+              /* printf("\nXXXXXX i: %d j: %d f: %G Pij:%G F:%G %G %G", */
+              /*        i,j,mod->e_frq->pi->v[i], */
               /*        mod->Pij_rr->v[dim1*k+dim2*i+j], */
-              /*        F[dim1*k+dim2*j+i]); */
+              /*        F[dim1*k+dim2*j+i],lnL, */
+              /*        (F[dim1*k+dim2*i+j] + F[dim1*k+dim2*j+i])*log(pi * pijk)); */
             }
         }
     }
   
-  For(i,mod->ns) For(k,mod->ras->n_catg) lnL += F[dim1*k+dim2*i+i]* LOG(mod->e_frq->pi->v[i] * mod->Pij_rr->v[dim1*k+dim2*i+i]);
-  
+  for(i=0;i<mod->ns;i++) 
+    {
+      pi = mod->e_frq->pi->v[i];
+      
+      for(k=0;k<mod->ras->n_catg;k++) 
+        {
+          pijk = mod->Pij_rr->v[dim1*k+dim2*i+i];
+          lnL += F[dim1*k+dim2*i+i]* log(pi * pijk);
+
+          /* printf("\nYYYYYY i: %d j: %d f: %G Pij:%G F:%G lnL:%G pi:%G pijk:%G", */
+          /*        i,j,mod->e_frq->pi->v[i], */
+          /*        mod->Pij_rr->v[dim1*k+dim2*i+j], */
+          /*        F[dim1*k+dim2*j+i],lnL, */
+          /*        pi,pijk); */
+        }
+    }
+
   return lnL;
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 phydbl Update_Lk_At_Given_Edge(t_edge *b_fcus, t_tree *tree)
 {
-  Update_P_Lk(tree,b_fcus,b_fcus->left);
-  Update_P_Lk(tree,b_fcus,b_fcus->rght);
+  Update_Partial_Lk(tree,b_fcus,b_fcus->left);
+  Update_Partial_Lk(tree,b_fcus,b_fcus->rght);
   tree->c_lnL = Lk(b_fcus,tree);
   return tree->c_lnL;
 }
@@ -2611,7 +2467,7 @@ void Print_Lk_Given_Edge_Recurr(t_node *a, t_node *d, t_edge *b, t_tree *tree)
   else
     {
       int i;
-      For(i,3)
+      for(i=0;i<3;i++)
     if(d->v[i] != a)
       Print_Lk_Given_Edge_Recurr(d,d->v[i],d->b[i],tree);
     }
@@ -2620,37 +2476,6 @@ void Print_Lk_Given_Edge_Recurr(t_node *a, t_node *d, t_edge *b, t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
 
 void Alias_Subpatt(t_tree *tree)
 {
@@ -2690,9 +2515,9 @@ void Alias_One_Subpatt(t_node *a, t_node *d, t_tree *tree)
       patt_id_d  = (d == d->b[0]->left)?(d->b[0]->patt_id_left):(d->b[0]->patt_id_rght);
       p_lk_loc_d = (d == d->b[0]->left)?(d->b[0]->p_lk_loc_left):(d->b[0]->p_lk_loc_rght);
 
-      For(i,tree->n_pattern)
+      for(i=0;i<tree->n_pattern;i++)
     {
-      For(j,tree->n_pattern)
+      for(j=0;j<tree->n_pattern;j++)
         {
           if(patt_id_d[i] == patt_id_d[j])
         {
@@ -2711,7 +2536,7 @@ void Alias_One_Subpatt(t_node *a, t_node *d, t_tree *tree)
   else
     {
       v1 = v2 = NULL;
-      For(i,3)
+      for(i=0;i<3;i++)
     {
       if(d->v[i] != a && d->b[i] != tree->e_root)
         {
@@ -2733,7 +2558,7 @@ void Alias_One_Subpatt(t_node *a, t_node *d, t_tree *tree)
       p_lk_loc_v2 = (v2 == b2->left)?(b2->p_lk_loc_left):(b2->p_lk_loc_rght);
 
       num_subpatt = 0;
-      For(i,tree->n_pattern)
+      for(i=0;i<tree->n_pattern;i++)
     {
       curr_patt_id_v1  = patt_id_v1[i];
       curr_patt_id_v2  = patt_id_v2[i];
@@ -2794,7 +2619,7 @@ void Alias_Subpatt_Post(t_node *a, t_node *d, t_tree *tree)
     {
       int i;
 
-      For(i,3)
+      for(i=0;i<3;i++)
     {
       if(d->v[i] != a && d->b[i] != tree->e_root)
         {
@@ -2808,65 +2633,28 @@ void Alias_Subpatt_Post(t_node *a, t_node *d, t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Alias_Subpatt_Pre(t_node *a, t_node *d, t_tree *tree)
 {
   if(d->tax) return;
   else
     {
       int i;
-
-      For(i,3)
-    {
-      if(d->v[i] != a && d->b[i] != tree->e_root)
+      
+      for(i=0;i<3;++i)
         {
-          Alias_One_Subpatt(d->v[i],d,tree);
-          Alias_Subpatt_Pre(d,d->v[i],tree);
+          if(d->v[i] != a && d->b[i] != tree->e_root)
+            {
+              Alias_One_Subpatt(d->v[i],d,tree);
+              Alias_Subpatt_Pre(d,d->v[i],tree);
+            }
         }
     }
-    }
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-void Copy_P_Lk(phydbl *p_lk, int site_from, int site_to, t_tree *tree)
-{
-  int i,j;
-  int dim1,dim2;
-
-
-  dim1 = tree->mod->ras->n_catg * tree->mod->ns;
-  dim2 = tree->mod->ns;
-
-/*   PhyML_Printf("\n# %d %d",site_to,site_from); */
-
-  For(i,tree->mod->ns) For(j,tree->mod->ras->n_catg)
-    {
-      p_lk[site_to*dim1+j*dim2+i] = p_lk[site_from*dim1+j*dim2+i];
-    }
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-void Copy_Scale(int *scale, int site_from, int site_to, t_tree *tree)
-{
-  int i;
-
-  For(i,tree->mod->ras->n_catg)
-    {
-      scale[i*tree->n_pattern+site_to] = scale[i*tree->n_pattern+site_from];
-/*       PhyML_Printf("\n. %d",scale[i*tree->n_pattern+site_to]); */
-    }
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
-void Init_P_Lk_Loc(t_tree *tree)
+void Init_Partial_Lk_Loc(t_tree *tree)
 {
   int i,j;
   t_node *d;
@@ -2874,22 +2662,21 @@ void Init_P_Lk_Loc(t_tree *tree)
 
   For(i,2*tree->n_otu-1)
     {
-      For(j,tree->n_pattern)
+      for(j=0;j<tree->n_pattern;j++)
         {
           tree->a_edges[i]->p_lk_loc_left[j] = j;
           tree->a_edges[i]->p_lk_loc_rght[j] = j;
         }
     }
   
-  For(i,tree->n_otu)
+  for(i=0;i<tree->n_otu;i++)
     {
       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]; */
-    }
+      for(j=0;j<tree->n_pattern;j++)
+        {
+          patt_id_d[j] = (int)tree->a_nodes[d->num]->c_seq->state[j];
+        }
     }
 }
 
@@ -2913,18 +2700,18 @@ phydbl Lk_Normal_Approx(t_tree *tree)
                      2*tree->n_otu-3,YES);
 
   first_order = 0.0;
-  For(i,dim) first_order += (tree->rates->u_cur_l[i] - tree->rates->mean_l[i]) * tree->rates->grad_l[i];
+  for(i=0;i<dim;i++) first_order += (tree->rates->u_cur_l[i] - tree->rates->mean_l[i]) * tree->rates->grad_l[i];
 
   lnL += first_order;
 
   /* printf("\n"); */
-  /* For(i,dim) printf("%f\t",tree->rates->u_cur_l[i]); */
+  /* for(i=0;i<dim;i++) printf("%f\t",tree->rates->u_cur_l[i]); */
   /* printf("\n. Lk=%f %f",lnL,tree->mod->l_min); */
 
 
 /*   err = NO; */
 /*   dim = 2*tree->n_otu-3; */
-/*   For(i,dim) */
+/*   for(i=0;i<dim;i++) */
 /*     { */
 /*       if((tree->rates->mean_l[i] / tree->mod->l_min < 1.1) &&  */
 /* 	 (tree->rates->mean_l[i] / tree->mod->l_min > 0.9)) */
@@ -2936,8 +2723,8 @@ phydbl Lk_Normal_Approx(t_tree *tree)
 /* 	      Warn_And_Exit(""); */
 /* 	    } */
 /* 	  lambda = 1./SQRT(tree->rates->cov_l[i*dim+i]); */
-/* 	  l = (tree->mod->log_l == YES)?(EXP(tree->a_edges[i]->l->v)):(tree->a_edges[i]->l->v); */
-/* 	  lnL += LOG(Dexp(l,lambda)); */
+/* 	  l = (tree->mod->log_l == YES)?(exp(tree->a_edges[i]->l->v)):(tree->a_edges[i]->l->v); */
+/* 	  lnL += log(Dexp(l,lambda)); */
 /* /\* 	  printf("\n. lambda = %f",lambda); *\/ */
 /* 	} */
 /*     } */
@@ -2952,16 +2739,17 @@ 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);; */
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 phydbl Wrap_Part_Lk(t_edge *b, t_tree *tree, supert_tree *stree)
 {
-  return PART_Lk(stree);
+  return -1.0;
+  /* return PART_Lk(stree); */
 }
 
 //////////////////////////////////////////////////////////////
@@ -3009,15 +2797,13 @@ phydbl Wrap_Lk_Rates(t_edge *b, t_tree *tree, supert_tree *stree)
 
 phydbl Wrap_Lk_Times(t_edge *b, t_tree *tree, supert_tree *stree)
 {
-  TIMES_Lk_Times(tree);
+  TIMES_Lk_Times(NO,tree);
   return tree->rates->c_lnL_times;
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
-
 phydbl Wrap_Lk_Linreg(t_edge *b, t_tree *tree, supert_tree *stree)
 {
   /* RATES_Lk_Linreg(tree); */
@@ -3081,14 +2867,14 @@ void Sample_Ancestral_Seq(int mutmap, int fromprior, t_tree *tree)
       Lk(NULL,tree);
     }
 
-  For(i,tree->n_pattern)
+  for(i=0;i<tree->n_pattern;i++)
     {
       /* Sample the rate class from its posterior density */
-      For(j,tree->mod->ras->n_catg)
+      for(j=0;j<tree->mod->ras->n_catg;j++)
         {
           if(fromprior == NO)
             probs[j] =
-              tree->unscaled_site_lk_cat[j*tree->n_pattern+i]*
+              tree->unscaled_site_lk_cat[i*tree->mod->ras->n_catg+j]*
               tree->mod->ras->gamma_r_proba->v[j];
           else
             probs[j] = tree->mod->ras->gamma_r_proba->v[j];
@@ -3097,8 +2883,8 @@ void Sample_Ancestral_Seq(int mutmap, int fromprior, t_tree *tree)
 
       /* Scale probas. */
       sum = .0;
-      For(j,tree->mod->ras->n_catg) sum += probs[j];
-      For(j,tree->mod->ras->n_catg) probs[j]/=sum;
+      for(j=0;j<tree->mod->ras->n_catg;j++) sum += probs[j];
+      for(j=0;j<tree->mod->ras->n_catg;j++) probs[j]/=sum;
 
       /* CDF */
       for(j=1;j<tree->mod->ras->n_catg;j++) probs[j] += probs[j-1];
@@ -3106,7 +2892,7 @@ void Sample_Ancestral_Seq(int mutmap, int fromprior, t_tree *tree)
       /* Sample rate */
       u = Uni();
       rate_cat = -1;
-      For(j,tree->mod->ras->n_catg)
+      for(j=0;j<tree->mod->ras->n_catg;j++)
         if(probs[j] > u)
           {
             rate_cat = j;
@@ -3120,9 +2906,9 @@ void Sample_Ancestral_Seq(int mutmap, int fromprior, t_tree *tree)
                                mutmap,fromprior,tree);
       
 
-      For(j,n_mut) ordering[j] = 0;
+      for(j=0;j<n_mut;j++) ordering[j] = 0;
       
-      For(j,n_mut-1)
+      for(j=0;j<n_mut-1;j++)
         {
           for(k=j+1;k<n_mut;k++)
             {
@@ -3136,13 +2922,13 @@ void Sample_Ancestral_Seq(int mutmap, int fromprior, t_tree *tree)
       fp = fopen(s,"a");
       PhyML_Fprintf(fp,"\n-1 -1 -1.0 -1");
 
-      For(j,n_mut)
+      for(j=0;j<n_mut;j++)
     {
-      For(k,n_mut)
+      for(k=0;k<n_mut;k++)
         {
           if(ordering[k] == j)
         {
-          For(l,tree->data->init_len) if(tree->data->sitepatt[l] == i) break;
+          for(l=0;l<tree->data->init_len;l++) if(tree->data->sitepatt[l] == i) break;
           PhyML_Fprintf(fp,"\n%4d %4d %12f %4d",j,muttype[k],muttime[k],l);
           /* PhyML_Fprintf(fp,"\n%d",muttype[ordering[j]]); */
           break;
@@ -3151,7 +2937,7 @@ void Sample_Ancestral_Seq(int mutmap, int fromprior, t_tree *tree)
     }
 
 
-      For(j,n_mut)
+      for(j=0;j<n_mut;j++)
         {
           muttype[j] = -2;
           muttime[j] = +1.;
@@ -3201,12 +2987,12 @@ void Sample_Ancestral_Seq_Pre(t_node *a, t_node *d, t_edge *b,
   
   if(sa == -1) /* c is an indel */
     {
-      For(j,tree->mod->ns) probs[j] = tree->mod->e_frq->pi->v[j];
+      for(j=0;j<tree->mod->ns;j++) probs[j] = tree->mod->e_frq->pi->v[j];
       
       for(j=1;j<tree->mod->ns;j++) probs[j] += probs[j-1];
       
       u = Uni();
-      For(j,tree->mod->ns)
+      for(j=0;j<tree->mod->ns;j++)
         if(probs[j] > u)
           {
             sa = j;
@@ -3229,10 +3015,10 @@ void Sample_Ancestral_Seq_Pre(t_node *a, t_node *d, t_edge *b,
       else
         p_lk = b->p_lk_rght;
       
-      For(j,tree->mod->ns) probs[j] = 0.0;
+      for(j=0;j<tree->mod->ns;j++) probs[j] = 0.0;
       
       /* Formula (10) in Nielsen's Mutation Maping paper, e.g. */
-      For(j,tree->mod->ns)
+      for(j=0;j<tree->mod->ns;j++)
         {
           if(fromprior == NO)
             probs[j] =
@@ -3244,8 +3030,8 @@ void Sample_Ancestral_Seq_Pre(t_node *a, t_node *d, t_edge *b,
       
       /* Scale the probabilities */
       sum = 0.0;
-      For(j,tree->mod->ns) sum += probs[j];
-      For(j,tree->mod->ns) probs[j] /= sum;
+      for(j=0;j<tree->mod->ns;j++) sum += probs[j];
+      for(j=0;j<tree->mod->ns;j++) probs[j] /= sum;
       
       /* CDF */
       for(j=1;j<tree->mod->ns;j++) probs[j] += probs[j-1];
@@ -3253,7 +3039,7 @@ void Sample_Ancestral_Seq_Pre(t_node *a, t_node *d, t_edge *b,
       /* Sample state according to their posterior probas. */
       sd = -1;
       u = Uni();
-      For(j,tree->mod->ns)
+      for(j=0;j<tree->mod->ns;j++)
         if(probs[j] > u)
           {
             sd = j;
@@ -3276,12 +3062,12 @@ void Sample_Ancestral_Seq_Pre(t_node *a, t_node *d, t_edge *b,
       
       if(sd == -1) // c is an indel
         {
-          For(j,tree->mod->ns) probs[j] = tree->mod->e_frq->pi->v[j];
+          for(j=0;j<tree->mod->ns;j++) probs[j] = tree->mod->e_frq->pi->v[j];
           
           for(j=1;j<tree->mod->ns;j++) probs[j] += probs[j-1];
           
           u = Uni();
-          For(j,tree->mod->ns)
+          for(j=0;j<tree->mod->ns;j++)
             if(probs[j] > u)
               {
                 sd = j;
@@ -3303,7 +3089,7 @@ void Sample_Ancestral_Seq_Pre(t_node *a, t_node *d, t_edge *b,
   if(d->tax) return;
   else
     {
-      For(i,3)
+      for(i=0;i<3;i++)
         {
           if(d->v[i] != a)
             {
@@ -3337,7 +3123,7 @@ void Map_Mutations(t_node *a, t_node *d, int sa, int sd, t_edge *b, int site, in
   // Edge rate
   br =
     (tree->rates->model_log_rates == YES)?
-    EXP(tree->rates->br_r[d->num]):
+    exp(tree->rates->br_r[d->num]):
     tree->rates->br_r[d->num];
 
   // Clock (i.e., overall) rate
@@ -3358,17 +3144,17 @@ void Map_Mutations(t_node *a, t_node *d, int sa, int sd, t_edge *b, int site, in
   td = b->l->v * gr;
 
   // Matrix of change probabilities
-  For(i,tree->mod->ns)
+  for(i=0;i<tree->mod->ns;i++)
     {
       // We only care about the non-diagonal elements here
-      For(j,tree->mod->ns) all_probs[i*tree->mod->ns+j] = -Q[i*tree->mod->ns+j] / Q[i*tree->mod->ns+i];
+      for(j=0;j<tree->mod->ns;j++) all_probs[i*tree->mod->ns+j] = -Q[i*tree->mod->ns+j] / Q[i*tree->mod->ns+i];
 
       // Set the diagonal to 0
       all_probs[i*tree->mod->ns+i] = 0.0;
 
       // \sum_{j != i} -q_{ij}/q_{ii}
       sum = 0;
-      For(j,tree->mod->ns) sum += all_probs[i*tree->mod->ns+j];
+      for(j=0;j<tree->mod->ns;j++) sum += all_probs[i*tree->mod->ns+j];
 
       // Diagonal: 1 - \sum_{j != i} -q_{ij}/q_{ii}
       all_probs[i*tree->mod->ns+i] = 1.-sum;
@@ -3392,7 +3178,7 @@ void Map_Mutations(t_node *a, t_node *d, int sa, int sd, t_edge *b, int site, in
       // Sample a time for the first mutation conditional on at least one mutation
       // occurring (see formula A2 in Nielsen's Genetics paper (2001))
       u = Uni();
-      tlast = -LOG(1. - u*(1.-EXP(Q[sa*tree->mod->ns+sa]*td)))/-Q[sa*tree->mod->ns+sa];
+      tlast = -log(1. - u*(1.-exp(Q[sa*tree->mod->ns+sa]*td)))/-Q[sa*tree->mod->ns+sa];
     }
       else
     {
@@ -3416,7 +3202,7 @@ void Map_Mutations(t_node *a, t_node *d, int sa, int sd, t_edge *b, int site, in
       n_mut_branch++;
 
       u = Uni();
-      For(i,tree->mod->ns)
+      for(i=0;i<tree->mod->ns;i++)
         if(probs[i] > u)
           {
         // Record mutation type
@@ -3448,8 +3234,8 @@ void Map_Mutations(t_node *a, t_node *d, int sa, int sd, t_edge *b, int site, in
         {
           // Restart from the beginning
           For(i,tree->mod->ns*tree->mod->ns) mut[i] = 0;
-          For(i,n_mut_branch) muttype[(*n_mut)+n_mut_branch-1] = -2;
-          For(i,n_mut_branch) muttime[(*n_mut)+n_mut_branch-1] = +1.;
+          for(i=0;i<n_mut_branch;i++) muttype[(*n_mut)+n_mut_branch-1] = -2;
+          for(i=0;i<n_mut_branch;i++) muttime[(*n_mut)+n_mut_branch-1] = +1.;
           tlast = 0.0;
           slast = sa;
           n_mut_branch = 0;
@@ -3463,7 +3249,7 @@ void Map_Mutations(t_node *a, t_node *d, int sa, int sd, t_edge *b, int site, in
   (*n_mut) += n_mut_branch;
 
 
-  For(i,tree->mod->ns)
+  for(i=0;i<tree->mod->ns;i++)
     {
       for(j=i+1;j<tree->mod->ns;j++)
     {
@@ -3501,6 +3287,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)
@@ -3532,48 +3319,49 @@ int Check_Lk_At_Given_Edge(int verbose, t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-void ML_Ancestral_Sequences(t_tree *tree)
+void Ancestral_Sequences(t_tree *tree, int print)
 {
   int i;
 
-  /* PhyML_Printf("\n. %s \n",Write_Tree(tree,NO)); */
-
-  PhyML_Printf("\n\n. Estimating ancestral sequences...");
-
-  strcpy(tree->io->out_ancestral_file,tree->io->out_file);
-  if(tree->io->append_run_ID) { strcat(tree->io->out_ancestral_file,"_"); strcat(tree->io->out_ancestral_file,tree->io->run_id_string); }
-  strcat(tree->io->out_ancestral_file,"_phyml_ancestral_seq");
-  tree->io->fp_out_ancestral = Openfile(tree->io->out_ancestral_file,1);
-
-  if(tree->n_root)
-    {
-      PhyML_Fprintf(tree->io->fp_out_ancestral,"\n== Printing the tree structure. Starting from the root node");
-      PhyML_Fprintf(tree->io->fp_out_ancestral,"\n== and displaying the nodes underneath recursively. Edge numbers");
-      PhyML_Fprintf(tree->io->fp_out_ancestral,"\n== and their lengths are also provided.\n\n");
-      Print_Node_Brief(tree->n_root,tree->n_root->v[0],tree,tree->io->fp_out_ancestral);
-      Print_Node_Brief(tree->n_root,tree->n_root->v[1],tree,tree->io->fp_out_ancestral);
-    }
-  else
+  if(print == YES)
     {
-      PhyML_Fprintf(tree->io->fp_out_ancestral,"\n== Printing the tree structure. Starting from node 0 (taxon %s)",tree->a_nodes[0]->name);
-      PhyML_Fprintf(tree->io->fp_out_ancestral,"\n== and displaying the nodes underneath recursively. Edge numbers");
-      PhyML_Fprintf(tree->io->fp_out_ancestral,"\n== and their lengths are also provided.\n\n");
-      Print_Node_Brief(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree,tree->io->fp_out_ancestral);
+      PhyML_Printf("\n\n. Estimating ancestral sequences...");
+
+      strcpy(tree->io->out_ancestral_file,tree->io->out_file);
+      if(tree->io->append_run_ID) { strcat(tree->io->out_ancestral_file,"_"); strcat(tree->io->out_ancestral_file,tree->io->run_id_string); }
+      strcat(tree->io->out_ancestral_file,"_phyml_ancestral_seq");
+      tree->io->fp_out_ancestral = Openfile(tree->io->out_ancestral_file,1);
+      
+      if(tree->n_root)
+        {
+          PhyML_Fprintf(tree->io->fp_out_ancestral,"\n== Printing the tree structure. Starting from the root node");
+          PhyML_Fprintf(tree->io->fp_out_ancestral,"\n== and displaying the nodes underneath recursively. Edge numbers");
+          PhyML_Fprintf(tree->io->fp_out_ancestral,"\n== and their lengths are also provided.\n\n");
+          Print_Node_Brief(tree->n_root,tree->n_root->v[0],tree,tree->io->fp_out_ancestral);
+          Print_Node_Brief(tree->n_root,tree->n_root->v[1],tree,tree->io->fp_out_ancestral);
+        }
+      else
+        {
+          PhyML_Fprintf(tree->io->fp_out_ancestral,"\n== Printing the tree structure. Starting from node 0 (taxon %s)",tree->a_nodes[0]->name);
+          PhyML_Fprintf(tree->io->fp_out_ancestral,"\n== and displaying the nodes underneath recursively. Edge numbers");
+          PhyML_Fprintf(tree->io->fp_out_ancestral,"\n== and their lengths are also provided.\n\n");
+          Print_Node_Brief(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree,tree->io->fp_out_ancestral);
+        }
+      
+      PhyML_Fprintf(tree->io->fp_out_ancestral,"\n\n\n");
+      PhyML_Fprintf(tree->io->fp_out_ancestral,"\n== Printing marginal probabilities of ancestral sequences at each site");
+      PhyML_Fprintf(tree->io->fp_out_ancestral,"\n== of the alignment and each node of the tree.");
+      PhyML_Fprintf(tree->io->fp_out_ancestral,"\n\n");
+      PhyML_Fprintf(tree->io->fp_out_ancestral,"Site\tNode\t");
+      for(i=0;i<tree->mod->ns;i++) PhyML_Fprintf(tree->io->fp_out_ancestral,"%c\t",Reciproc_Assign_State(i,tree->io->datatype));
+      PhyML_Fprintf(tree->io->fp_out_ancestral,"\n");
     }
-  
-  PhyML_Fprintf(tree->io->fp_out_ancestral,"\n\n\n");
-  PhyML_Fprintf(tree->io->fp_out_ancestral,"\n== Printing marginal probabilities of ancestral sequences at each site");
-  PhyML_Fprintf(tree->io->fp_out_ancestral,"\n== of the alignment and each node of the tree.");
-  PhyML_Fprintf(tree->io->fp_out_ancestral,"\n\n");
-  PhyML_Fprintf(tree->io->fp_out_ancestral,"Site\tNode\t");
-  For(i,tree->mod->ns) PhyML_Fprintf(tree->io->fp_out_ancestral,"%c\t",Reciproc_Assign_State(i,tree->io->datatype));
-  PhyML_Fprintf(tree->io->fp_out_ancestral,"\n");
 
   For(i,2*tree->n_otu-2)
     if(tree->a_nodes[i]->tax == NO)
-      ML_Ancestral_Sequences_One_Node(tree->a_nodes[i],tree);
+      Ancestral_Sequences_One_Node(tree->a_nodes[i],tree,print);
 
-  if(tree->n_root) ML_Ancestral_Sequences_One_Node(tree->n_root,tree);
+  if(tree->n_root) Ancestral_Sequences_One_Node(tree->n_root,tree,print);
 
 
   fclose(tree->io->fp_out_ancestral);
@@ -3582,329 +3370,759 @@ void ML_Ancestral_Sequences(t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-void ML_Ancestral_Sequences_One_Node(t_node *mixt_d, t_tree *mixt_tree)
+void Ancestral_Sequences_One_Node(t_node *d, t_tree *tree, int print)
 {
-  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(tree->is_mixt_tree) 
+        {
+          MIXT_Ancestral_Sequences_One_Node(d,tree,print);
+        }
+      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;
+          FILE *fp;
+
+          unsigned const int ncatg = tree->mod->ras->n_catg;
+          unsigned const int ns = tree->mod->ns;
+          unsigned const int nsns = ns*ns;
+          unsigned const int ncatgns = ns*ncatg;
+          
+          if(!d) return;
+          
+          fp = tree->io->fp_out_ancestral;
+          assert(fp != NULL);
 
-      if(!mixt_d) return;
+          
+          p = (phydbl *)mCalloc(ns,sizeof(phydbl));
+              
+          for(site=0;site<tree->data->init_len;site++) // For each site in the current partition element
+            {
+              csite = tree->data->sitepatt[site];
+                                    
+              for(i=0;i<ns;i++) 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=0;catg<ncatg;catg++)
+                {
+                  for(i=0;i<ns;i++)
+                    {
+                      p0 = .0;
+                      if(v0->tax)
+                        for(j=0;j<ns;j++)
+                          {
+                            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=0;j<ns;j++)
+                          {
+                            p0 += p_lk0[csite*ncatgns+catg*ns+j] * Pij0[catg*nsns+i*ns+j] / (phydbl)POW(2,sum_scale0[csite*ncatg+catg]);
+                            
+                            /* p0 += p_lk0[site*ncatgns+catg*ns+j] * Pij0[catg*nsns+i*ns+j]; */
+                            
+                            /* printf("\n. p0 %f %f", */
+                                    /*        p_lk0[site*ncatgns+catg*ns+j], */
+                                    /*        Pij0[catg*nsns+i*ns+j]); */
+                          }
+                      p1 = .0;
+                      if(v1->tax)
+                        for(j=0;j<ns;j++)
+                          {
+                            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=0;j<ns;j++)
+                          {
+                            p1 += p_lk1[csite*ncatgns+catg*ns+j] * Pij1[catg*nsns+i*ns+j] / (phydbl)POW(2,sum_scale1[csite*ncatg+catg]);
+                            
+                            /* p1 += p_lk1[site*ncatgns+catg*ns+j] * Pij1[catg*nsns+i*ns+j];  */
+                            
+                            /* printf("\n. p1 %f %f", */
+                                    /*        p_lk1[site*ncatgns+catg*ns+j], */
+                                    /*        Pij1[catg*nsns+i*ns+j]); */
+                          }
+                      
+                      
+                      p2 = .0;
+                      if(v2->tax)
+                        for(j=0;j<ns;j++)
+                          {
+                            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=0;j<ns;j++)
+                          {
+                            p2 += p_lk2[csite*ncatgns+catg*ns+j] * Pij2[catg*nsns+i*ns+j] / (phydbl)POW(2,sum_scale2[csite*ncatg+catg]);
+                            
+                            /* p2 += p_lk2[site*ncatgns+catg*ns+j] * Pij2[catg*nsns+i*ns+j]; */
+                            
+                            /* printf("\n. p2 %f %f", */
+                            /*        p_lk2[site*ncatgns+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];
+                      
+                    }
+                }
+              
+              if(print == YES)
+                {
+                  PhyML_Fprintf(fp,"%4d\t%4d\t",site+1,d->num);
+                  sum_probas = .0;
+                  for(i=0;i<ns;i++)
+                    {
+                      PhyML_Fprintf(fp,"%.4f\t",p[i]);
+                      sum_probas += p[i];
+                    }
+                  PhyML_Fprintf(fp,"\n");
+                  fflush(NULL);
+                  assert(Are_Equal(sum_probas,1.0,0.01));
+                }
 
-      curr_mixt_tree = mixt_tree;
-      curr_mixt_d    = mixt_d;
-      fp             = mixt_tree->io->fp_out_ancestral;
+            }
+          Free(p);
+        }
+    }
+}
 
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+// Computes the value of fact_sum_scale, the part of the scaling factors
+// that is common to all classes of the mixture and scale the 
+// likelihood for each mixture using the part of the scaling
+// factors that is class-specific
+ 
+void Pull_Scaling_Factors(int site, t_edge *b, t_tree *tree)
+{
+  unsigned int catg;
+  const unsigned int ncatg = tree->mod->ras->n_catg;
 
-      do /* For each partition element */
+  if(tree->apply_lk_scaling == NO)
+    {
+      tree->fact_sum_scale[site] = 0;
+      for(catg=0;catg<ncatg;++catg) tree->unscaled_site_lk_cat[site*ncatg+catg] = tree->site_lk_cat[catg];
+      return;
+    }
+  else
+    {
+      switch(tree->scaling_method)
         {
-          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
+        case SCALE_RATE_SPECIFIC : 
+          {
+            int *sum_scale_left_cat,*sum_scale_rght_cat;
+            int exponent;
+            phydbl max_sum_scale,min_sum_scale;
+            phydbl sum,tmp,dum;
+            
+            sum_scale_left_cat = b->sum_scale_left_cat;
+            sum_scale_rght_cat = b->sum_scale_rght_cat;
+            
+            max_sum_scale =   (phydbl)BIG;
+            min_sum_scale =  -(phydbl)BIG;
+            
+            for(catg=0;catg<ncatg;++catg)
+              {
+                sum_scale_left_cat[catg] =
+                  (b->sum_scale_left)?
+                  (b->sum_scale_left[site*ncatg+catg]):
+                  (0.0);
+                
+                sum_scale_rght_cat[catg] =
+                  (b->sum_scale_rght)?
+                  (b->sum_scale_rght[site*ncatg+catg]):
+                  (0.0);
+                
+                sum = sum_scale_left_cat[catg] + sum_scale_rght_cat[catg];
+                
+                if(sum < .0)
+                  {
+                    printf("\n== tree: %s\n",Write_Tree(tree,NO));
+                    PhyML_Printf("\n== b->num = %d  sum = %G root ? %d",sum,b->num,b == tree->e_root);
+                    PhyML_Printf("\n== Err. in file %s at line %d.\n",__FILE__,__LINE__);
+                    Exit("\n");
+                  }
+                
+                dum = log(FABS(tree->site_lk_cat[catg]));
+                
+                tmp = sum + ((phydbl)LOGBIG - dum)/(phydbl)LOG2;
+                if(tmp < max_sum_scale) max_sum_scale = tmp; /* min of the maxs */
+                
+                tmp = sum + ((phydbl)LOGSMALL - dum)/(phydbl)LOG2;
+                if(tmp > min_sum_scale) min_sum_scale = tmp; /* max of the mins */
+                
+                assert(isnan(tmp) == NO);
+              }
+            
+            if(min_sum_scale > max_sum_scale)
+              {
+#ifdef SAFEMODE
+                PhyML_Printf("\n== Numerical precision issue alert.");
+                PhyML_Printf("\n== min_sum_scale = %G max_sum_scale = %G",min_sum_scale,max_sum_scale);
+#endif
+                min_sum_scale = max_sum_scale;
+              }
+            
+            tree->fact_sum_scale[site] = (int)((max_sum_scale + min_sum_scale) / 2);
+                        
+            /* Apply scaling factors */
+            for(catg=0;catg<ncatg;++catg)
+              {
+                exponent = -(sum_scale_left_cat[catg]+sum_scale_rght_cat[catg])+tree->fact_sum_scale[site];
+                Rate_Correction(exponent,tree->site_lk_cat + catg);
+              }
+            
+            break;
+          }
+        case SCALE_FAST :
+          {
+            int sum_scale_left,sum_scale_rght;
+            
+            sum_scale_left =
+              (b->sum_scale_left)?
+              (b->sum_scale_left[site]):
+              (0.0);
+            
+            sum_scale_rght =
+              (b->sum_scale_rght)?
+              (b->sum_scale_rght[site]):
+              (0.0);
+            
+            tree->fact_sum_scale[site] = sum_scale_left + sum_scale_rght;
+
+            break;
+          }
+        }
+      for(catg=0;catg<ncatg;++catg) tree->unscaled_site_lk_cat[site*ncatg+catg] = tree->site_lk_cat[catg]; 
+    }
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+// Tree should be ready for likelihood analysis when calling
+// this function.
+ void Stepwise_Add_Lk(t_tree *tree)
+ {
+   t_edge **residuals,**targets,*best_target;
+  int *nd_idx,i,j,n_targets,*tg_idx,n_opt;
+
+  residuals   = (t_edge **)mCalloc(tree->n_otu-3,sizeof(t_edge *));
+  targets     = (t_edge **)mCalloc(2*tree->n_otu-3,sizeof(t_edge *));
+  best_target = NULL;
+  nd_idx      = Permutate(tree->n_otu-3);
+
+  // Remove all tips except that corresponding to a_nodes[0], 
+  // a_nodes[1] and a_nodes[2].  
+  for(i=0;i<tree->n_otu-3;i++)
+    {
+      Prune_Subtree(tree->a_nodes[i+3]->v[0],                   
+                    tree->a_nodes[i+3],
+                    NULL,
+                    residuals+i,
+                    tree);
+    }
+
+  // Initial targets
+  n_targets = 3;
+  for(i=0;i<n_targets;i++) targets[i] = tree->a_nodes[i]->b[0];
+
+  // Regraft each tip on the tree at most parsimonious position
+  for(i=0;i<tree->n_otu-3;i++)
+    {
+      Set_Both_Sides(YES,tree);
+      Lk(NULL,tree);
+
+      printf("\n. [%d/%d]",i,tree->n_otu-3);
+
+      tree->best_lnL = UNLIKELY;
+      best_target    = NULL;
+      tg_idx         = Permutate(n_targets);
+
+      for(j=0;j<n_targets;j++)
+        {
+          Graft_Subtree(targets[tg_idx[j]],
+                        tree->a_nodes[nd_idx[i]+3]->v[0],
+                        NULL,
+                        residuals[i],
+                        NULL,
+                        tree);
+          
+          Update_PMat_At_Given_Edge(targets[tg_idx[j]],tree);
+          Update_PMat_At_Given_Edge(tree->a_nodes[nd_idx[i]+3]->b[0],tree);
+          Update_Partial_Lk(tree,residuals[i],tree->a_nodes[nd_idx[i]+3]->v[0]);
+          Lk(residuals[i],tree);
+
+          if(tree->c_lnL > tree->best_lnL)
             {
-              r_mat_weight_sum = 1.;
-              e_frq_weight_sum = 1.;
-              sum_probas       = 1.;
+              tree->best_lnL = tree->c_lnL;
+              best_target = targets[tg_idx[j]];
             }
+          
+          Prune_Subtree(tree->a_nodes[nd_idx[i]+3]->v[0],                        
+                        tree->a_nodes[nd_idx[i]+3],
+                        NULL,
+                        residuals+i,
+                        tree);
+        }
 
-          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;
+      assert(best_target);
+            
+      Graft_Subtree(best_target,
+                    tree->a_nodes[nd_idx[i]+3]->v[0],
+                    NULL,
+                    residuals[i],
+                    NULL,
+                    tree);
+      
+      n_opt = 0;
+      do Optimize_Br_Len_Serie (tree); while(n_opt++ < 3);
 
-          p = (phydbl *)mCalloc(Ns,sizeof(phydbl));
+      targets[n_targets]   = residuals[i]; 
+      targets[n_targets+1] = tree->a_nodes[nd_idx[i]+3]->b[0];
+      
+      Free(tg_idx);
+      n_targets+=2;
+    }
 
-          /* 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];
+  Round_Optimize(tree,5);
+  printf("\n. lk: %f",tree->c_lnL);
+  Exit("\n");
 
-              d    = curr_mixt_d->next ? curr_mixt_d->next : curr_mixt_d;
-              tree = curr_mixt_tree->next ? curr_mixt_tree->next : curr_mixt_tree;
+  Free(nd_idx);
+  Free(residuals);
+  Free(targets);
+}
 
-              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];
+/*     |
+       |
+       |b
+       |
+       |d
+      /  \
+     /    \
+    /      \
+   /        \
+  /v1        \v2
 
-                  b0 = d->b[0];
-                  b1 = d->b[1];
-                  b2 = d->b[2];
+  Set p_lk and sum_scale for subtrees with d, v1 and v2 as root,
+  Pij for edges b, and the two edges connecting d to v1 and d to
+  v2;
+  Account for rooted trees.
+*/
 
-                  Pij0 = b0->Pij_rr;
-                  Pij1 = b1->Pij_rr;
-                  Pij2 = b2->Pij_rr;
+void Set_All_Partial_Lk(t_node **n_v1, t_node **n_v2,
+                        phydbl **p_lk, int **sum_scale, int **p_lk_loc,
+                        phydbl **Pij1, phydbl **tPij1, phydbl **p_lk_v1, int **sum_scale_v1,
+                        phydbl **Pij2, phydbl **tPij2, phydbl **p_lk_v2, int **sum_scale_v2,
+                        t_node *d, t_edge *b, t_tree *tree
+#ifdef BEAGLE
+                        , int *dest_p_idx, int *child1_p_idx, int* child2_p_idx, int* Pij1_idx, int* Pij2_idx
+#endif
+                        )
+{
+  unsigned int i;
+  
+  assert(tree->is_mixt_tree == NO);
+  assert(d->tax == NO);
+  
+  if(tree->n_root == NULL || tree->ignore_root == YES)
+    {
+      /* Does d lie on the "left" or "right" of the branch? */
+      if(d == b->left)
+        {
+          *p_lk      = b->p_lk_left;
+          *sum_scale = b->sum_scale_left;
+          *p_lk_loc  = b->p_lk_loc_left;
+#ifdef BEAGLE
+          *dest_p_idx = b->p_lk_left_idx;
+#endif
+        }
+      else
+        {
+          *p_lk      = b->p_lk_rght;
+          *sum_scale = b->sum_scale_rght;
+          *p_lk_loc  = b->p_lk_loc_rght;
+#ifdef BEAGLE
+          *dest_p_idx = b->p_lk_rght_idx;
+#endif
+        }
 
-                  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;
-                    }
+      *n_v1 = *n_v2 = NULL;
+      for(i=0;i<3;++i)
+        {
+          if(d->b[i] != b)
+            {
+              if(!(*n_v1))
+                {
+                  *n_v1 = d->v[i];
+#ifdef BEAGLE
+                  Set_Partial_Lk_One_Side(Pij1,tPij1,p_lk_v1,sum_scale_v1,d,d->b[i],tree,child1_p_idx,Pij1_idx);
+#else
+                  Set_Partial_Lk_One_Side(Pij1,tPij1,p_lk_v1,sum_scale_v1,d,d->b[i],tree);
+#endif
+                }
+              else if(!(*n_v2))
+                {
+                  *n_v2 = d->v[i];
+#ifdef BEAGLE
+                  Set_Partial_Lk_One_Side(Pij2,tPij2,p_lk_v2,sum_scale_v2,d,d->b[i],tree,child2_p_idx,Pij2_idx);
+#else
+                  Set_Partial_Lk_One_Side(Pij2,tPij2,p_lk_v2,sum_scale_v2,d,d->b[i],tree);
+#endif
+                }
+              else assert(FALSE);
+            }
+        }
+    }
+  else
+    {
+      if(b == tree->e_root)
+        {
+          if(d == tree->n_root->v[1])      b = tree->n_root->b[1];
+          else if(d == tree->n_root->v[2]) b = tree->n_root->b[2];
+          else assert(FALSE);
+        }
 
-                  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(d == tree->n_root)
+        {
+          if(b == tree->n_root->b[1])
+            {
+              *p_lk      = tree->n_root->b[1]->p_lk_left;
+              *sum_scale = tree->n_root->b[1]->sum_scale_left;
+              *p_lk_loc  = tree->n_root->b[1]->p_lk_loc_left;
+#ifdef BEAGLE
+              *dest_p_idx = tree->n_root->b[1]->p_lk_left_idx;
+#endif
+            }
+          else
+            {
+              *p_lk      = tree->n_root->b[2]->p_lk_left;
+              *sum_scale = tree->n_root->b[2]->sum_scale_left;
+              *p_lk_loc  = tree->n_root->b[2]->p_lk_loc_left;
+#ifdef BEAGLE
+              *dest_p_idx = tree->n_root->b[2]->p_lk_left_idx;
+#endif
+            }
 
-                  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;
-                    }
+          *n_v1         = NULL;
+          *Pij1         = NULL;
+          *tPij1        = NULL;
+          *p_lk_v1      = NULL;
+          *sum_scale_v1 = NULL;
 
+          if(b == tree->n_root->b[1])
+            {
+              *n_v2         = tree->n_root->v[2];
+              *Pij2         = tree->n_root->b[2]->Pij_rr;
+              *tPij2        = tree->n_root->b[2]->tPij_rr;
+              *p_lk_v2      = tree->n_root->b[2]->p_lk_rght;
+              *sum_scale_v2 = tree->n_root->b[2]->sum_scale_rght;
+#ifdef BEAGLE
+              *child2_p_idx = tree->n_root->b[2]->p_lk_rght_idx;
+              *Pij2_idx     = tree->n_root->b[2]->Pij_rr_idx;
+#endif
+            }
+          else if(b == tree->n_root->b[2])
+            {
+              *n_v2         = tree->n_root->v[1];
+              *Pij2         = tree->n_root->b[1]->Pij_rr;
+              *tPij2        = tree->n_root->b[1]->tPij_rr;
+              *p_lk_v2      = tree->n_root->b[1]->p_lk_rght;
+              *sum_scale_v2 = tree->n_root->b[1]->sum_scale_rght;
+#ifdef BEAGLE
+              *child2_p_idx = tree->n_root->b[1]->p_lk_rght_idx;
+              *Pij2_idx     = tree->n_root->b[1]->Pij_rr_idx;
+#endif
+            }
+          else assert(FALSE);
+        }
+      else if(d == tree->n_root->v[1] || d == tree->n_root->v[2])
+        {
+          if(b == tree->n_root->b[1] || b == tree->n_root->b[2])
+            {
+              if(b == tree->n_root->b[1])
+                {
+                  *p_lk      = tree->n_root->b[1]->p_lk_rght;
+                  *sum_scale = tree->n_root->b[1]->sum_scale_rght;
+                  *p_lk_loc  = tree->n_root->b[1]->p_lk_loc_left;
+#ifdef BEAGLE
+                  *dest_p_idx = tree->n_root->b[1]->p_lk_rght_idx;
+#endif
+                }
+              else
+                {
+                  *p_lk      = tree->n_root->b[2]->p_lk_rght;
+                  *sum_scale = tree->n_root->b[2]->sum_scale_rght;
+                  *p_lk_loc  = tree->n_root->b[2]->p_lk_loc_rght;
+#ifdef BEAGLE
+                  *dest_p_idx = tree->n_root->b[2]->p_lk_rght_idx;
+#endif
+                }
 
-                  For(catg,tree->mod->ras->n_catg)
+              *n_v1 = *n_v2 = NULL;
+              for(i=0;i<3;++i)
+                {
+                  if(d->b[i] != tree->e_root)
                     {
-                      For(i,Ns)
+                      if(!(*n_v1))
                         {
-                          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;
-
+                          *n_v1 = d->v[i];
+#ifdef BEAGLE
+                          Set_Partial_Lk_One_Side(Pij1,tPij1,p_lk_v1,sum_scale_v1,d,d->b[i],tree,child1_p_idx,Pij1_idx);
+#else
+                          Set_Partial_Lk_One_Side(Pij1,tPij1,p_lk_v1,sum_scale_v1,d,d->b[i],tree);
+#endif
+                        }
+                      else
+                        {
+                          *n_v2 = d->v[i];
+#ifdef BEAGLE
+                          Set_Partial_Lk_One_Side(Pij2,tPij2,p_lk_v2,sum_scale_v2,d,d->b[i],tree,child2_p_idx,Pij2_idx);
+#else
+                          Set_Partial_Lk_One_Side(Pij2,tPij2,p_lk_v2,sum_scale_v2,d,d->b[i],tree);
+#endif
                         }
                     }
+                }
+            }
+          else
+            {
+              if(d == b->left)
+                {
+                  *p_lk      = b->p_lk_left;
+                  *sum_scale = b->sum_scale_left;
+                  *p_lk_loc  = b->p_lk_loc_left;
+#ifdef BEAGLE
+                  *dest_p_idx = b->p_lk_left_idx;
+#endif
+                }
+              else
+                {
+                  *p_lk      = b->p_lk_rght;
+                  *sum_scale = b->sum_scale_rght;
+                  *p_lk_loc  = b->p_lk_loc_rght;
+#ifdef BEAGLE
+                  *dest_p_idx = b->p_lk_rght_idx;
+#endif
+                }
 
-                  PhyML_Fprintf(fp,"%4d\t%4d\t",site+1,d->num);
-                  For(i,Ns)
+
+              *n_v1 = tree->n_root;
+#ifdef BEAGLE
+              Set_Partial_Lk_One_Side(Pij1,tPij1,p_lk_v1,sum_scale_v1,d,
+                                (d == tree->n_root->v[1])?
+                                (tree->n_root->b[1]):
+                                (tree->n_root->b[2]),
+                                tree,child1_p_idx,Pij1_idx);
+#else
+              Set_Partial_Lk_One_Side(Pij1,tPij1,p_lk_v1,sum_scale_v1,d,
+                                (d == tree->n_root->v[1])?
+                                (tree->n_root->b[1]):
+                                (tree->n_root->b[2]),
+                                tree);
+#endif
+              for(i=0;i<3;i++)
+                {
+                  if(d->b[i] != tree->e_root && d->b[i] != b)
                     {
-                      PhyML_Fprintf(fp,"%.4f\t",p[i]);
+                      *n_v2 = d->v[i];
+#ifdef BEAGLE
+                      Set_Partial_Lk_One_Side(Pij2,tPij2,p_lk_v2,sum_scale_v2,d,d->b[i],tree,child2_p_idx,Pij2_idx);
+#else
+                      Set_Partial_Lk_One_Side(Pij2,tPij2,p_lk_v2,sum_scale_v2,d,d->b[i],tree);
+#endif
+                      break;
                     }
-                  PhyML_Fprintf(fp,"\n");
-                  fflush(NULL);
-                  /* Exit("\n"); */
-                  
-
-                  tree = tree->next;
-                  d    = d->next;
+                }
 
+            }
+        }
+      else
+        {
+          if(d == b->left)
+            {
+              *p_lk      = b->p_lk_left;
+              *sum_scale = b->sum_scale_left;
+              *p_lk_loc  = b->p_lk_loc_left;
+#ifdef BEAGLE
+              *dest_p_idx = b->p_lk_left_idx;
+#endif
+            }
+          else
+            {
+              *p_lk      = b->p_lk_rght;
+              *sum_scale = b->sum_scale_rght;
+              *p_lk_loc  = b->p_lk_loc_rght;
+#ifdef BEAGLE
+              *dest_p_idx = b->p_lk_rght_idx;
+#endif
+            }
 
+          *n_v1 = *n_v2 = NULL;
+          for(i=0;i<3;i++)
+            {
+              if(d->b[i] != b)
+                {
+                  if(!(*n_v1))
+                    {
+                      *n_v1 = d->v[i];
+#ifdef BEAGLE
+                      Set_Partial_Lk_One_Side(Pij1,tPij1,p_lk_v1,sum_scale_v1,d,d->b[i],tree,child1_p_idx,Pij1_idx);
+#else
+                      Set_Partial_Lk_One_Side(Pij1,tPij1,p_lk_v1,sum_scale_v1,d,d->b[i],tree);
+#endif
+                    }
+                  else
+                    {
+                      *n_v2 = d->v[i];
+#ifdef BEAGLE
+                      Set_Partial_Lk_One_Side(Pij2,tPij2,p_lk_v2,sum_scale_v2,d,d->b[i],tree,child2_p_idx,Pij2_idx);
+#else
+                      Set_Partial_Lk_One_Side(Pij2,tPij2,p_lk_v2,sum_scale_v2,d,d->b[i],tree);
+#endif
+                    }
                 }
-              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);
     }
 }
 
+/*     |
+       |
+       |d
+      /  \
+     /    \
+    /      \b
+   /        \
+  /          \x (either n_v1 or n_v2)
+
+  Returns p_lk and sum_scale for subtree with x as root, Pij for edge b
+*/
+
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
-// Returns the value of fact_sum_scale, the part of the scaling factors
-// that is common to all classes of the mixture and scale the 
-// likelihood for each mixture (using the part of the scaling
-// factors that is class-specific)
 
-void Pull_Scaling_Factors(int site,
-                          t_edge *b,
-                          t_tree *tree)
+void Set_Partial_Lk_One_Side(phydbl **Pij, phydbl **tPij, phydbl **p_lk,  int **sum_scale, t_node *d, t_edge *b, t_tree *tree
+#ifdef BEAGLE
+                                     , int* child_p_idx, int* Pij_idx
+#endif
+                                     )
 {
-  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;
 
-  sum_scale_left_cat = b->sum_scale_left_cat;
-  sum_scale_rght_cat = b->sum_scale_rght_cat;
+  if(Pij != NULL)
+    {
+      *Pij  = b->Pij_rr;
+      *tPij = b->tPij_rr;
+#ifdef BEAGLE
+      *Pij_idx = b->Pij_rr_idx;
+#endif
+    }
 
-  if(tree->apply_lk_scaling == YES)
+  if(d->tax == NO)
     {
-      max_sum_scale =   (phydbl)BIG;
-      min_sum_scale =  -(phydbl)BIG;
-      
-      For(catg,tree->mod->ras->n_catg)
+      if(d == b->left) // if d is on the left of b, then d's neighbor is on the right
         {
-          sum_scale_left_cat[catg] =
-            (b->sum_scale_left)?
-            (b->sum_scale_left[catg*tree->n_pattern+site]):
-            (0.0);
-          
-          sum_scale_rght_cat[catg] =
-            (b->sum_scale_rght)?
-            (b->sum_scale_rght[catg*tree->n_pattern+site]):
-            (0.0);
-          
-          sum = sum_scale_left_cat[catg] + sum_scale_rght_cat[catg];
-          
-          if(sum < .0)
-            {
-              printf("\n== tree: %s\n",Write_Tree(tree,NO));
-              PhyML_Printf("\n== b->num = %d  sum = %G root ? %d",sum,b->num,b == tree->e_root);
-              PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__);
-              Exit("\n");
-            }
-          
-          tmp = sum + ((phydbl)LOGBIG - LOG(tree->site_lk_cat[catg]))/(phydbl)LOG2;
-          if(tmp < max_sum_scale) max_sum_scale = tmp; /* min of the maxs */
-          
-          tmp = sum + ((phydbl)LOGSMALL - LOG(tree->site_lk_cat[catg]))/(phydbl)LOG2;
-          if(tmp > min_sum_scale) min_sum_scale = tmp; /* max of the mins */
-          
-        }
-      
-      if(min_sum_scale > max_sum_scale)
-        {
-          /* PhyML_Printf("\n== Numerical precision issue alert."); */
-          /* PhyML_Printf("\n== min_sum_scale = %G max_sum_scale = %G",min_sum_scale,max_sum_scale); */
-          /* PhyML_Printf("\n== Err in file %s at line %d\n\n",__FILE__,__LINE__); */
-          /* Warn_And_Exit("\n"); */
-          min_sum_scale = max_sum_scale;
+          *p_lk      = (b->rght->tax == YES) ? b->p_lk_tip_r : b->p_lk_rght;
+          *sum_scale = b->sum_scale_rght;
+#ifdef BEAGLE
+          *child_p_idx = b->rght->tax? b->p_lk_tip_idx: b->p_lk_rght_idx;
+#endif
         }
-      
-      tree->fact_sum_scale[site] = (int)((max_sum_scale + min_sum_scale) / 2);
-            
-      /* fact_sum_scale = (int)(max_sum_scale / 2); */
-      
-      /* Apply scaling factors */
-      For(catg,tree->mod->ras->n_catg)
+      else
         {
-          exponent = -(sum_scale_left_cat[catg]+sum_scale_rght_cat[catg])+tree->fact_sum_scale[site];
-          site_lk_cat = tree->site_lk_cat[catg];
-          Rate_Correction(exponent,&site_lk_cat,tree);
-          tree->site_lk_cat[catg] = site_lk_cat;
+          *p_lk      = b->p_lk_left;
+          *sum_scale = b->sum_scale_left;
+#ifdef BEAGLE
+          *child_p_idx   = b->rght->tax? b->p_lk_tip_idx: b->p_lk_left_idx;
+#endif
         }
     }
-  else // No scaling of lk
-    {
-      tree->fact_sum_scale[site] = 0;
-    }
-  
-  For(catg,tree->mod->ras->n_catg) 
+  else
     {
-      tree->unscaled_site_lk_cat[catg*tree->n_pattern + site] = tree->site_lk_cat[catg];
-      
-      if(isinf(tree->unscaled_site_lk_cat[catg*tree->n_pattern + site]) || 
-         isnan(tree->unscaled_site_lk_cat[catg*tree->n_pattern + site]))
-        {
-          PhyML_Printf("\n== Err. in file %s at line %d (function '%s')",__FILE__,__LINE__,__FUNCTION__);
-          Exit("\n");
-        }
+#ifdef BEAGLE
+      Warn_And_Exit(TODO_BEAGLE);
+#endif
+      *p_lk        = NULL;
+      *sum_scale   = NULL;
     }
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
diff --git a/src/lk.h b/src/lk.h
index dfbba69..af527ed 100644
--- a/src/lk.h
+++ b/src/lk.h
@@ -21,7 +21,10 @@ the GNU public licence.  See http://www.opensource.org for details.
 #include "free.h"
 #include "times.h"
 #include "mixt.h"
+#include "avx.h"
+#include "sse.h"
 
+void Update_All_Partial_Lk(t_tree *tree);
 void Init_Tips_At_One_Site_Nucleotides_Float(char state, int pos, phydbl *p_lk);
 void Init_Tips_At_One_Site_AA_Float(char aa, int pos, phydbl *p_lk);
 void Get_All_Partial_Lk(t_tree *tree,t_edge *b_fcus,t_node *a,t_node *d);
@@ -30,30 +33,27 @@ void Post_Order_Lk(t_node *pere, t_node *fils, t_tree *tree);
 void Pre_Order_Lk(t_node *pere, t_node *fils, t_tree *tree);
 phydbl Lk(t_edge *b, t_tree *tree);
 void Site_Lk(t_tree *tree);
-/* phydbl Lk_At_Given_Edge(t_edge *b_fcus,t_tree *tree); */
 phydbl Return_Abs_Lk(t_tree *tree);
 matrix *ML_Dist(calign *data, t_mod *mod);
 phydbl Lk_Given_Two_Seq(calign *data, int numseq1, int numseq2, phydbl dist, t_mod *mod, phydbl *loglk);
 void Unconstraint_Lk(t_tree *tree);
-void Update_P_Lk(t_tree *tree,t_edge *b_fcus,t_node *n);
-void Update_P_Lk_Generic(t_tree *tree,t_edge *b_fcus,t_node *n);
-void Update_P_Lk_AA(t_tree *tree,t_edge *b_fcus,t_node *n);
-void Update_P_Lk_Nucl(t_tree *tree,t_edge *b_fcus,t_node *n);
-void Init_P_Lk_Tips_Double(t_tree *tree);
-void Init_P_Lk_Tips_Int(t_tree *tree);
-void Init_P_Lk_At_One_Node(t_node *a, t_tree *tree);
+void Update_Partial_Lk(t_tree *tree,t_edge *b_fcus,t_node *n);
+void Update_Partial_Lk_Generic(t_tree *tree,t_edge *b_fcus,t_node *n);
+void Default_Update_Partial_Lk(t_tree *tree,t_edge *b_fcus,t_node *n);
+void Init_Partial_Lk_Tips_Double(t_tree *tree);
+void Init_Partial_Lk_Tips_Int(t_tree *tree);
+void Init_Partial_Lk_At_One_Node(t_node *a, t_tree *tree);
 void Update_PMat_At_Given_Edge(t_edge *b_fcus, t_tree *tree);
 void Sort_Sites_Based_On_Lk(t_tree *tree);
 void Get_Partial_Lk_Scale(t_tree *tree, t_edge *b_fcus, t_node *a, t_node *d);
 void Get_Partial_Lk(t_tree *tree, t_edge *b_fcus, t_node *a, t_node *d);
 void Init_Tips_At_One_Site_Nucleotides_Int(char state, int pos, short int *p_pars);
 void Init_Tips_At_One_Site_AA_Int(char aa, int pos, short int *p_pars);
-void Update_P_Lk_Along_A_Path(t_node **path, int path_length, t_tree *tree);
+void Update_Partial_Lk_Along_A_Path(t_node **path, int path_length, t_tree *tree);
 phydbl Lk_Dist(phydbl *F, phydbl dist, t_mod *mod);
 phydbl Update_Lk_At_Given_Edge(t_edge *b_fcus, t_tree *tree);
-void Update_P_Lk_Greedy(t_tree *tree, t_edge *b_fcus, t_node *n);
+void Update_Partial_Lk_Greedy(t_tree *tree, t_edge *b_fcus, t_node *n);
 void Get_All_Partial_Lk_Scale_Greedy(t_tree *tree, t_edge *b_fcus, t_node *a, t_node *d);
-phydbl Lk_Core(int state, int ambiguity_check, t_edge *b, t_tree *tree);
 phydbl Lk_Triplet(t_node *a, t_node *d, t_tree *tree);
 void Print_Lk_Given_Edge_Recurr(t_node *a, t_node *d, t_edge *b, t_tree *tree);
 phydbl *Post_Prob_Rates_At_Given_Edge(t_edge *b, phydbl *post_prob, t_tree *tree);
@@ -64,9 +64,11 @@ void Alias_Subpatt(t_tree *tree);
 void Alias_One_Subpatt(t_node *a, t_node *d, t_tree *tree);
 void Alias_Subpatt_Post(t_node *a, t_node *d, t_tree *tree);
 void Alias_Subpatt_Pre(t_node *a, t_node *d, t_tree *tree);
-void Copy_P_Lk(phydbl *p_lk, int site_from, int site_to, t_tree *tree);
-void Copy_Scale(int *scale, int site_from, int site_to, t_tree *tree);
-void Init_P_Lk_Loc(t_tree *tree);
+void Backup_Partial_Lk(t_node *d, t_edge *b, t_tree *tree);
+void Restore_Partial_Lk(t_node *d, t_edge *b, t_tree *tree);
+void Backup_Partial_Scale(t_node *d, t_edge *b, t_tree *tree);
+void Restore_Partial_Scale(t_node *d, t_edge *b, t_tree *tree);
+void Init_Partial_Lk_Loc(t_tree *tree);
 phydbl Lk_Normal_Approx(t_tree *tree);
 phydbl Wrap_Lk(t_edge *b, t_tree *tree, supert_tree *stree);
 phydbl Wrap_Lk_At_Given_Edge(t_edge *b, t_tree *tree, supert_tree *stree);
@@ -78,18 +80,45 @@ phydbl Wrap_Lk_Rates(t_edge *b, t_tree *tree, supert_tree *stree);
 phydbl Wrap_Lk_Linreg(t_edge *b, t_tree *tree, supert_tree *stree);
 void Sample_Ancestral_Seq(int mutmap, int fromprior, t_tree *tree);
 void Map_Mutations(t_node *a, t_node *d, int sa, int sd, t_edge *b, int site, int rate_cat, int *muttype, phydbl *muttime, int *n_mut, t_tree *tree);
-void Sample_Ancestral_Seq_Pre(t_node *a, t_node *d, t_edge *b,
-                  int site, int rate_cat,
-                  int *muttype, phydbl *muttime, int *n_mut,
-                  int mutmap, int fromprior, t_tree *tree);
+void Sample_Ancestral_Seq_Pre(t_node *a, t_node *d, t_edge *b,int site, int rate_cat,int *muttype, phydbl *muttime, int *n_mut,int mutmap, int fromprior, t_tree *tree);
 phydbl Wrap_Lk_Times(t_edge *b, t_tree *tree, supert_tree *stree);
 phydbl Lk_LastFirst(t_tree *tree);
-phydbl Invariant_Lk(int fact_sum_scale, int site, int *num_prec_issue, t_tree *tree);
-void Rate_Correction(int exponent, phydbl *site_lk_cat, t_tree *tree);
 int Check_Lk_At_Given_Edge(int verbose, t_tree *tree);
-void ML_Ancestral_Sequences_One_Node(t_node *mixt_d, t_tree *mixt_tree);
-void ML_Ancestral_Sequences(t_tree *tree);
-void Pull_Scaling_Factors(int site, t_edge *b, t_tree *tree);
+void Ancestral_Sequences_One_Node(t_node *mixt_d, t_tree *mixt_tree, int print);
+void Ancestral_Sequences(t_tree *tree, int print);
+void Stepwise_Add_Lk(t_tree *tree);
+void Update_Eigen_Lr(t_edge *b, t_tree *tree);
+phydbl dLk(phydbl *l, t_edge *b, t_tree *tree);
+phydbl Lk_Core(int state, int ambiguity_check, short int derivative,
+                             phydbl *p_lk_left, phydbl *p_lk_rght,
+                             phydbl *Pij_rr,
+                             t_edge *b,
+                             t_tree *tree);
+phydbl Lk_Core_Eigen_Lr(phydbl *expl, phydbl *dot_prod, short int derivative, t_edge *b, t_tree *tree);
+phydbl Invariant_Lk(int fact_sum_scale, int site, int *num_prec_issue, t_tree *tree);
+
+
+
+
+
+
+phydbl Lk_Core_One_Class_Eigen_Lr(phydbl *dot_prod, phydbl *expl, int ns);
+phydbl Lk_Core_One_Class_No_Eigen_Lr(phydbl *p_lk_left, phydbl *p_lk_rght, phydbl *Pij,phydbl *pi, int ns, int ambiguity_check, int state);
+
+void Pull_Scaling_Factors(int site,t_edge *b,t_tree *tree);
+void Set_All_Partial_Lk(t_node **n_v1, t_node **n_v2,phydbl **p_lk, int **sum_scale, int **p_lk_loc,phydbl **Pij1, phydbl **tPij1, phydbl **p_lk_v1, int **sum_scale_v1,phydbl **Pij2, phydbl **tPij2, phydbl **p_lk_v2, int **sum_scale_v2,t_node *d, t_edge *b, t_tree *tree
+#ifdef BEAGLE
+                                , int *dest_p_idx, int *child1_p_idx, int* child2_p_idx, int* Pij1_idx, int* Pij2_idx
+#endif
+                                );
+void Set_Partial_Lk_One_Side(phydbl **Pij, phydbl **tPij, phydbl **p_lk,  int **sum_scale, t_node *d, t_edge *b, t_tree *tree
+#ifdef BEAGLE
+                                     , int* child_p_idx, int* Pij_idx
+#endif
+                                     );
+void Rate_Correction(int exponent, phydbl *site_lk_cat);
+
+
 
 #endif
 
diff --git a/src/m4.c b/src/m4.c
index efbc334..46dc91c 100644
--- a/src/m4.c
+++ b/src/m4.c
@@ -1,7 +1,7 @@
 /*
 
 PhyML:  a program that  computes maximum likelihood phylogenies from
-DNA or AA homoLOGous sequences.
+DNA or AA homologous sequences.
 
 Copyright (C) Stephane Guindon. Oct 2003 onward.
 
@@ -66,7 +66,7 @@ int M4_main(int argc, char **argv)
       io->n_trees     = MIN(io->n_trees,io->n_data_sets);
     }
 
-  For(num_data_set,io->n_data_sets)
+  for(num_data_set=0;num_data_set<io->n_data_sets;num_data_set++)
     {
       best_lnL = UNLIKELY;
       Get_Seq(io);
@@ -93,7 +93,7 @@ int M4_main(int argc, char **argv)
 	    {
 	      if(!io->mod->s_opt->random_input_tree) io->mod->s_opt->n_rand_starts = 1;
 
-	      For(num_rand_tree,io->mod->s_opt->n_rand_starts)
+	      for(num_rand_tree=0;num_rand_tree<io->mod->s_opt->n_rand_starts;num_rand_tree++)
 		{
 		  if((io->mod->s_opt->random_input_tree) && (io->mod->s_opt->topo_search != NNI_MOVE))
 		    if(!io->quiet) PhyML_Printf("\n. [Random start %3d/%3d]\n",num_rand_tree+1,io->mod->s_opt->n_rand_starts);
@@ -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)
 		    {
@@ -146,7 +144,7 @@ int M4_main(int argc, char **argv)
 		  else
 		    {
 		      if(tree->mod->s_opt->opt_subst_param || 
-			 tree->mod->s_opt->opt_bl)                       Round_Optimize(tree,tree->data,ROUND_MAX);
+			 tree->mod->s_opt->opt_bl)                       Round_Optimize(tree,ROUND_MAX);
 		      else                                               Lk(NULL,tree);
 		    }
 		  
@@ -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
 	{
@@ -315,7 +313,7 @@ void M4_Make_Complete(int n_h, int n_o, m4 *m4mod)
   m4mod->o_rr = (phydbl *)mCalloc(n_o*n_o,sizeof(phydbl));
   m4mod->o_fq = (phydbl *)mCalloc(n_o,sizeof(phydbl));
   m4mod->o_mats = (phydbl **)mCalloc(n_h,sizeof(phydbl *));
-  For(i,n_h) m4mod->o_mats[i] = (phydbl *)mCalloc(n_o*n_o,sizeof(phydbl));
+  for(i=0;i<n_h;i++) m4mod->o_mats[i] = (phydbl *)mCalloc(n_o*n_o,sizeof(phydbl));
   m4mod->h_mat = (phydbl *)mCalloc(n_h*n_h,sizeof(phydbl));
   m4mod->h_rr = (phydbl *)mCalloc(n_h*n_h,sizeof(phydbl));
   m4mod->h_fq = (phydbl *)mCalloc(n_h,sizeof(phydbl));
@@ -351,28 +349,28 @@ void M4_Update_Qmat(m4 *m4mod, t_mod *mod)
   else if(mod->m4mod->use_cov_free)
     {
       sum = .0;
-      For(i,mod->m4mod->n_h) sum += FABS(mod->m4mod->h_fq_unscaled[i]);
-      For(i,mod->m4mod->n_h) mod->m4mod->h_fq[i] = FABS(mod->m4mod->h_fq_unscaled[i])/sum;
+      for(i=0;i<mod->m4mod->n_h;i++) sum += FABS(mod->m4mod->h_fq_unscaled[i]);
+      for(i=0;i<mod->m4mod->n_h;i++) mod->m4mod->h_fq[i] = FABS(mod->m4mod->h_fq_unscaled[i])/sum;
       
       do
 	{
 	  sum = .0;
-	  For(i,mod->m4mod->n_h)
+	  for(i=0;i<mod->m4mod->n_h;i++)
 	    {
 	      if(mod->m4mod->h_fq[i] < 0.01) mod->m4mod->h_fq[i]=0.01;
 	      if(mod->m4mod->h_fq[i] > 0.99) mod->m4mod->h_fq[i]=0.99;
 	      sum += mod->m4mod->h_fq[i];
 	    }
 
-	  For(i,mod->m4mod->n_h) mod->m4mod->h_fq[i]/=sum;
+	  for(i=0;i<mod->m4mod->n_h;i++) mod->m4mod->h_fq[i]/=sum;
 	}
       while((sum > 1.01) || (sum < 0.99));
 
 
       /* Make sure the multipliers are centered on 1.0 */
       sum = .0;
-      For(i,mod->m4mod->n_h) sum += FABS(mod->m4mod->multipl_unscaled[i]) * mod->m4mod->h_fq[i];
-      For(i,mod->m4mod->n_h) mod->m4mod->multipl[i] = mod->m4mod->multipl_unscaled[i] / sum;
+      for(i=0;i<mod->m4mod->n_h;i++) sum += FABS(mod->m4mod->multipl_unscaled[i]) * mod->m4mod->h_fq[i];
+      for(i=0;i<mod->m4mod->n_h;i++) mod->m4mod->multipl[i] = mod->m4mod->multipl_unscaled[i] / sum;
       
       /* printf("\n. WARNING\n"); */
       /* mod->m4mod->h_fq[0] = 1./3; */
@@ -384,7 +382,7 @@ void M4_Update_Qmat(m4 *m4mod, t_mod *mod)
       /* mod->m4mod->multipl[2] = 1.0; */
 
       sum = 0;
-      For(i,mod->m4mod->n_h) sum += mod->m4mod->multipl[i] * mod->m4mod->h_fq[i];
+      for(i=0;i<mod->m4mod->n_h;i++) sum += mod->m4mod->multipl[i] * mod->m4mod->h_fq[i];
       if(sum < 0.99 || sum > 1.01)
 	{
 	  PhyML_Printf("\n. sum = %f",sum);
@@ -393,7 +391,7 @@ void M4_Update_Qmat(m4 *m4mod, t_mod *mod)
 	}
 
       /* PhyML_Printf("\n__ "); */
-      /* For(i,mod->m4mod->n_h) PhyML_Printf("\n.%f %f %f", */
+      /* for(i=0;i<mod->m4mod->n_h;i++) PhyML_Printf("\n.%f %f %f", */
       /* 				    mod->m4mod->h_fq[i], */
       /* 				    mod->m4mod->h_fq_unscaled[i], */
       /* 				    mod->m4mod->multipl[i]); */
@@ -404,12 +402,12 @@ void M4_Update_Qmat(m4 *m4mod, t_mod *mod)
   /* PhyML_Printf("\n. M4 model parameters"); */
   /* m4mod->delta=.0; */
   /* PhyML_Printf("\n. Delta = %f",m4mod->delta); */
-  /* For(i,mod->m4mod->n_h) PhyML_Printf("\n. multipl %d = %f",i,m4mod->multipl[i]); */
-  /* For(i,mod->m4mod->n_h) PhyML_Printf("\n. fq %d = %f",i,m4mod->h_fq[i]); */
+  /* for(i=0;i<mod->m4mod->n_h;i++) PhyML_Printf("\n. multipl %d = %f",i,m4mod->multipl[i]); */
+  /* for(i=0;i<mod->m4mod->n_h;i++) PhyML_Printf("\n. fq %d = %f",i,m4mod->h_fq[i]); */
 
 
   /* Set up the stationary frequency vector */
-  For(i,n_s) mod->e_frq->pi->v[i] = m4mod->o_fq[i%n_o] * m4mod->h_fq[i/n_o];
+  for(i=0;i<n_s;i++) mod->e_frq->pi->v[i] = m4mod->o_fq[i%n_o] * m4mod->h_fq[i/n_o];
 
 
   if(mod->whichmodel != CUSTOM &&
@@ -446,7 +444,7 @@ void M4_Update_Qmat(m4 *m4mod, t_mod *mod)
   For(i,n_s*n_s) mod->r_mat->qmat->v[i] = .0;
 
   /* Diagonal blocks (i.e, nucleotide substitutions), symmetric */
-  For(i,n_s)
+  for(i=0;i<n_s;i++)
     {
       for(j=i+1;j<n_s;j++)
 	{
@@ -461,10 +459,10 @@ void M4_Update_Qmat(m4 *m4mod, t_mod *mod)
   /* Work out scaling factor such that the  expected number of observed state substitution
      along a branch of length 1 is 1.*/
   mr = .0;
-  For(i,n_s)
+  for(i=0;i<n_s;i++)
     {
       sum = .0;
-      For(j,n_s) sum += mod->r_mat->qmat->v[i*n_s+j];
+      for(j=0;j<n_s;j++) sum += mod->r_mat->qmat->v[i*n_s+j];
       mr += sum * m4mod->o_fq[i%n_o] * m4mod->h_fq[(int)(i/n_o)]; 
     }
   
@@ -482,7 +480,7 @@ void M4_Update_Qmat(m4 *m4mod, t_mod *mod)
   For(i,n_h*n_h) m4mod->h_mat[i] *= m4mod->delta;
 
   /* Fill the non diagonal blocks */
-  For(i,n_s)
+  for(i=0;i<n_s;i++)
     {
       for(j=i+1;j<n_s;j++)
 	{
@@ -504,10 +502,10 @@ void M4_Update_Qmat(m4 *m4mod, t_mod *mod)
 
 
   /* Diagonal cells */
-  For(i,n_s)
+  for(i=0;i<n_s;i++)
     {
       sum = .0;
-      For(j,n_s)
+      for(j=0;j<n_s;j++)
 	{
 	  if(j != i)
 	    sum += mod->r_mat->qmat->v[i*n_s+j];
@@ -522,7 +520,7 @@ void M4_Update_Qmat(m4 *m4mod, t_mod *mod)
 //////////////////////////////////////////////////////////////
 
 
-void M4_Init_P_Lk_Tips_Double(t_tree *tree)
+void M4_Init_Partial_Lk_Tips_Double(t_tree *tree)
 {
   int curr_site,i,j,k,l,dim1,dim2,dim3;
   
@@ -533,11 +531,11 @@ void M4_Init_P_Lk_Tips_Double(t_tree *tree)
 
   Fors(curr_site,tree->data->crunch_len,tree->mod->io->state_len)
     {
-      For(i,tree->n_otu)
+      for(i=0;i<tree->n_otu;i++)
 	{
 	  for(j=1;j<tree->mod->m4mod->n_h;j++)
 	    {
-	      For(k,tree->mod->m4mod->n_o)
+	      for(k=0;k<tree->mod->m4mod->n_o;k++)
 		{
 		  tree->a_nodes[i]->b[0]->p_lk_rght[curr_site*dim1 + 0*dim2 + j*dim3+k] = 
 		    tree->a_nodes[i]->b[0]->p_lk_rght[curr_site*dim1 + 0*dim2 + 0*dim3+k];
@@ -551,7 +549,7 @@ void M4_Init_P_Lk_Tips_Double(t_tree *tree)
 		}
 
 
-	      For(k,tree->mod->m4mod->n_o)
+	      for(k=0;k<tree->mod->m4mod->n_o;k++)
 		for(l=1;l<tree->mod->ras->n_catg;l++)
 		  tree->a_nodes[i]->b[0]->p_lk_rght[curr_site*dim1 + l*dim2 + j*dim3+k] = 
 		  tree->a_nodes[i]->b[0]->p_lk_rght[curr_site*dim1 + 0*dim2 + j*dim3+k];
@@ -566,7 +564,7 @@ void M4_Init_P_Lk_Tips_Double(t_tree *tree)
 //////////////////////////////////////////////////////////////
 
 
-void M4_Init_P_Lk_Tips_Int(t_tree *tree)
+void M4_Init_Partial_Lk_Tips_Int(t_tree *tree)
 {
   int curr_site,i,j,k,dim2,dim3;
 
@@ -575,11 +573,11 @@ void M4_Init_P_Lk_Tips_Int(t_tree *tree)
 
   Fors(curr_site,tree->data->crunch_len,tree->mod->io->state_len)
     {
-      For(i,tree->n_otu)
+      for(i=0;i<tree->n_otu;i++)
 	{
 	  for(j=1;j<tree->mod->m4mod->n_h;j++)
 	    {
-	      For(k,tree->mod->m4mod->n_o)
+	      for(k=0;k<tree->mod->m4mod->n_o;k++)
 		{
 		  tree->a_nodes[i]->b[0]->p_lk_tip_r[curr_site*dim2 + j*dim3+k] = 
 		    tree->a_nodes[i]->b[0]->p_lk_tip_r[curr_site*dim2 + 0*dim3+k];
@@ -611,13 +609,13 @@ phydbl ****M4_Integral_Term_On_One_Edge(t_edge *b, t_tree *tree)
 
 
   integral = (phydbl ****)mCalloc(tree->mod->ras->n_catg,sizeof(phydbl ***));
-  For(g,tree->mod->ras->n_catg)
+  for(g=0;g<tree->mod->ras->n_catg;g++)
     {
       integral[g] = (phydbl ***)mCalloc(ns,sizeof(phydbl **));
-      For(j,ns)
+      for(j=0;j<ns;j++)
 	{
 	  integral[g][j] = (phydbl **)mCalloc(ns,sizeof(phydbl *));
-	  For(k,ns) integral[g][j][k] = (phydbl *)mCalloc(ns,sizeof(phydbl));
+	  for(k=0;k<ns;k++) integral[g][j][k] = (phydbl *)mCalloc(ns,sizeof(phydbl));
 	}
     }
 
@@ -625,18 +623,18 @@ phydbl ****M4_Integral_Term_On_One_Edge(t_edge *b, t_tree *tree)
   step = 100;
 
   PhyML_Printf("\n. [");
-  For(i,step)
+  for(i=0;i<step;i++)
     {
-      For(g,tree->mod->ras->n_catg)
+      for(g=0;g<tree->mod->ras->n_catg;g++)
 	{
-	  PMat(((phydbl)(i+0.5)/step)*b->l->v*tree->mod->ras->gamma_rr->v[g],tree->mod,g*ns*ns,P1);
-	  PMat(((phydbl)(step-i-0.5)/step)*b->l->v*tree->mod->ras->gamma_rr->v[g],tree->mod,g*ns*ns,P2);
+	  PMat(((phydbl)(i+0.5)/step)*b->l->v*tree->mod->ras->gamma_rr->v[g],tree->mod,g*ns*ns,P1,NULL);
+	  PMat(((phydbl)(step-i-0.5)/step)*b->l->v*tree->mod->ras->gamma_rr->v[g],tree->mod,g*ns*ns,P2,NULL);
 
-	  For(j,ns)
+	  for(j=0;j<ns;j++)
 	    {
-	      For(k,ns)
+	      for(k=0;k<ns;k++)
 		{
-		  For(l,ns)
+		  for(l=0;l<ns;l++)
 		    {
 		      /* integral[g][j][k][l] += P1[g][j][k] * P2[g][j][l]  / ((phydbl)(step)); */
 		      integral[g][j][k][l] += P1[g*ns*ns + j*ns+k] * P2[g*ns*ns + j*ns+l] / ((phydbl)(step));
@@ -674,21 +672,21 @@ void M4_Post_Prob_H_Class_Edge_Site(t_edge *b, phydbl ****integral, phydbl *post
 
   n_h = tree->mod->m4mod->n_h; /* number of classes, i.e., number of hidden states */
 
-  site_lk = (phydbl)EXP(tree->cur_site_lk[tree->curr_site]);
+  site_lk = (phydbl)exp(tree->cur_site_lk[tree->curr_site]);
 
   if(b->rght->tax)
     {
       sum = .0;
-      For(i,n_h)
+      for(i=0;i<n_h;i++)
 	{
 	  postprob[i] = .0;
-	  For(j,tree->mod->m4mod->n_o)
+	  for(j=0;j<tree->mod->m4mod->n_o;j++)
 	    {
-	      For(g,tree->mod->ras->n_catg)
+	      for(g=0;g<tree->mod->ras->n_catg;g++)
 		{
-		  For(k,tree->mod->ns)
+		  for(k=0;k<tree->mod->ns;k++)
 		    {
-		      For(l,tree->mod->ns)
+		      for(l=0;l<tree->mod->ns;l++)
 			{
 			  postprob[i] +=
 
@@ -716,22 +714,22 @@ void M4_Post_Prob_H_Class_Edge_Site(t_edge *b, phydbl ****integral, phydbl *post
 	}
 
       /* TO DO */
-      For(i,n_h) postprob[i] *= EXP(b->sum_scale_left[tree->curr_site]); 
+      for(i=0;i<n_h;i++) postprob[i] *= exp(b->sum_scale_left[tree->curr_site]); 
 
     }
   else
     {
       sum = .0;
-      For(i,n_h)
+      for(i=0;i<n_h;i++)
 	{
 	  postprob[i] = .0;
-	  For(j,tree->mod->m4mod->n_o)
+	  for(j=0;j<tree->mod->m4mod->n_o;j++)
 	    {
-	      For(g,tree->mod->ras->n_catg)
+	      for(g=0;g<tree->mod->ras->n_catg;g++)
 		{
-		  For(k,tree->mod->ns)
+		  for(k=0;k<tree->mod->ns;k++)
 		    {
-		      For(l,tree->mod->ns)
+		      for(l=0;l<tree->mod->ns;l++)
 			{
 			  postprob[i] +=
 
@@ -758,11 +756,11 @@ void M4_Post_Prob_H_Class_Edge_Site(t_edge *b, phydbl ****integral, phydbl *post
 	}
 
       /* TO DO */
-      For(i,n_h) postprob[i] *= EXP(b->sum_scale_left[tree->curr_site] + b->sum_scale_rght[tree->curr_site]); 
+      for(i=0;i<n_h;i++) postprob[i] *= exp(b->sum_scale_left[tree->curr_site] + b->sum_scale_rght[tree->curr_site]); 
 
     }
 
-  For(i,n_h) 
+  for(i=0;i<n_h;i++) 
     if((postprob[i] < -1.E-5) || (postprob[i] > 1.0+1.E-5))
       {
 	PhyML_Printf("\n. Cat : %d Prob : %f\n",i,postprob[i]);
@@ -771,7 +769,7 @@ void M4_Post_Prob_H_Class_Edge_Site(t_edge *b, phydbl ****integral, phydbl *post
       }
 
   sum = 0.0;
-  For(i,n_h) sum += postprob[i];
+  for(i=0;i<n_h;i++) sum += postprob[i];
 
   if((sum > 1.0+1.E-2) || (sum < 1.0-1.E-2))
     {
@@ -799,7 +797,7 @@ phydbl ***M4_Compute_Proba_Hidden_States_On_Edges(t_tree *tree)
   For(i,2*tree->n_otu-3)
     {
       post_probs[i] = (phydbl **)mCalloc(tree->n_pattern,sizeof(phydbl *));
-      For(tree->curr_site,tree->n_pattern) 
+      for(tree->curr_site=0;tree->curr_site<tree->n_pattern;tree->curr_site++) 
 	post_probs[i][tree->curr_site] = (phydbl *)mCalloc(tree->mod->m4mod->n_h,sizeof(phydbl));
     }
 
@@ -813,7 +811,7 @@ phydbl ***M4_Compute_Proba_Hidden_States_On_Edges(t_tree *tree)
 
       integral = M4_Integral_Term_On_One_Edge(tree->a_edges[i],tree);
 
-      For(tree->curr_site,tree->n_pattern)
+      for(tree->curr_site=0;tree->curr_site<tree->n_pattern;tree->curr_site++)
 	M4_Post_Prob_H_Class_Edge_Site(tree->a_edges[i],
 				       integral,
 				       post_probs[i][tree->curr_site],
@@ -857,7 +855,7 @@ void M4_Compute_Posterior_Mean_Rates(phydbl ***post_probs, t_tree *tree)
   /* Compute the posterior mean relative rate on each branch averaged over the 
      whole set of patterns (sites) */
   len_var = 0;
-  For(patt,tree->n_pattern) 
+  for(patt=0;patt<tree->n_pattern;patt++) 
     {
       if(!Is_Invar(patt,1,NT,tree->data))
 	{
@@ -865,7 +863,7 @@ void M4_Compute_Posterior_Mean_Rates(phydbl ***post_probs, t_tree *tree)
 	    {
 	      max_prob = -1.;
 	      best_r = -1;
-	      For(rcat,tree->mod->m4mod->n_h)
+	      for(rcat=0;rcat<tree->mod->m4mod->n_h;rcat++)
 		{
 		  if(post_probs[br][patt][rcat] > max_prob)
 		    {
@@ -875,7 +873,7 @@ void M4_Compute_Posterior_Mean_Rates(phydbl ***post_probs, t_tree *tree)
 		}
 
 /* /\* 	      Add weight on each category, weight is proportional to the corresponding posterior probability *\/ */
-/* 	      For(rcat,tree->mod->m4mod->n_h) */
+/* 	      for(rcat=0;rcat<tree->mod->m4mod->n_h;rcat++) */
 /* 		{ */
 /* 		  mean_post_probs[br][rcat] += post_probs[br][patt][rcat] * tree->data->wght[patt]; */
 /* 		} */
@@ -889,7 +887,7 @@ void M4_Compute_Posterior_Mean_Rates(phydbl ***post_probs, t_tree *tree)
 
   For(br,2*tree->n_otu-3) 
     {
-      For(rcat,tree->mod->m4mod->n_h)
+      for(rcat=0;rcat<tree->mod->m4mod->n_h;rcat++)
 	{
 	  mean_post_probs[br][rcat] /= (phydbl)len_var;
 	}
@@ -899,7 +897,7 @@ void M4_Compute_Posterior_Mean_Rates(phydbl ***post_probs, t_tree *tree)
      each branch length using this factor */
   For(br,2*tree->n_otu-3)
     {
-      For(rcat,tree->mod->m4mod->n_h)
+      for(rcat=0;rcat<tree->mod->m4mod->n_h;rcat++)
 	{
 	  mrr[br] += mean_post_probs[br][rcat] * tree->mod->m4mod->multipl[rcat];
 	}
@@ -907,11 +905,11 @@ void M4_Compute_Posterior_Mean_Rates(phydbl ***post_probs, t_tree *tree)
     }
 
   PhyML_Fprintf(tree->io->fp_out_stats,"\n. Mean posterior probabilities & rates\n");
-  For(rcat,tree->mod->m4mod->n_h) PhyML_Fprintf(tree->io->fp_out_stats,"%2.4f ",tree->mod->m4mod->multipl[rcat]);
+  for(rcat=0;rcat<tree->mod->m4mod->n_h;rcat++) PhyML_Fprintf(tree->io->fp_out_stats,"%2.4f ",tree->mod->m4mod->multipl[rcat]);
   PhyML_Fprintf(tree->io->fp_out_stats,"\n");
   For(br,2*tree->n_otu-3) 
     {
-      For(rcat,tree->mod->m4mod->n_h)
+      for(rcat=0;rcat<tree->mod->m4mod->n_h;rcat++)
 	{
 	  PhyML_Fprintf(tree->io->fp_out_stats,"%2.4f ",mean_post_probs[br][rcat]);
 	}
@@ -943,14 +941,14 @@ void M4_Compute_Posterior_Mean_Rates(phydbl ***post_probs, t_tree *tree)
   /* Compute the posterior mean relative rate at each site, for each branch
      and each rate category. Scale branch lengths using these factors and
      print each tree (i.e., on tree per site pattern) */
-  For(patt,tree->n_pattern) 
+  for(patt=0;patt<tree->n_pattern;patt++) 
     {
       For(br,2*tree->n_otu-3) 
 	{
 	  mrr[br] = .0;
 	  max_prob = -1.;
 	  best_r = -1;
-	  For(rcat,tree->mod->m4mod->n_h) /* For each rate class */
+	  for(rcat=0;rcat<tree->mod->m4mod->n_h;rcat++) /* For each rate class */
 	    {
 	      mrr[br] += post_probs[br][patt][rcat] * tree->mod->m4mod->multipl[rcat];
 	      if(post_probs[br][patt][rcat] > max_prob)
@@ -970,14 +968,14 @@ void M4_Compute_Posterior_Mean_Rates(phydbl ***post_probs, t_tree *tree)
 	     tree->data->wght[patt],
 	     Is_Invar(patt,1,NT,tree->data));
 
-      For(rcat,tree->mod->m4mod->n_h) PhyML_Fprintf(tree->io->fp_out_stats,"%2.4f ",tree->mod->m4mod->multipl[rcat]);
+      for(rcat=0;rcat<tree->mod->m4mod->n_h;rcat++) PhyML_Fprintf(tree->io->fp_out_stats,"%2.4f ",tree->mod->m4mod->multipl[rcat]);
       PhyML_Fprintf(tree->io->fp_out_stats,"\n");
       For(br,2*tree->n_otu-3)
 	{
 	  PhyML_Fprintf(tree->io->fp_out_stats,"Edge %3d ",br);
 	  max_prob = -1.0;
 	  best_r = -1;
-	  For(rcat,tree->mod->m4mod->n_h)
+	  for(rcat=0;rcat<tree->mod->m4mod->n_h;rcat++)
 	    {
 	      if(post_probs[br][patt][rcat] > max_prob)
 		{
@@ -986,7 +984,7 @@ void M4_Compute_Posterior_Mean_Rates(phydbl ***post_probs, t_tree *tree)
 		}
 	    }
 
-	  For(rcat,tree->mod->m4mod->n_h)
+	  for(rcat=0;rcat<tree->mod->m4mod->n_h;rcat++)
 	    {
 	      PhyML_Fprintf(tree->io->fp_out_stats,"%2.4f",post_probs[br][patt][rcat]);
 	      if(rcat == best_r) PhyML_Fprintf(tree->io->fp_out_stats,"* ");
@@ -1014,7 +1012,7 @@ void M4_Compute_Posterior_Mean_Rates(phydbl ***post_probs, t_tree *tree)
       For(br,2*tree->n_otu-3) 
 	{
 	  sum = .0;
-	  For(rcat,tree->mod->m4mod->n_h)
+	  for(rcat=0;rcat<tree->mod->m4mod->n_h;rcat++)
 	    {
 	      sum += post_probs[br][patt][rcat];
 	    }
@@ -1046,7 +1044,7 @@ void M4_Compute_Posterior_Mean_Rates(phydbl ***post_probs, t_tree *tree)
 
   For(br,2*tree->n_otu-3)
     {
-      For(tree->curr_site,tree->n_pattern)
+      for(tree->curr_site=0;tree->curr_site<tree->n_pattern;tree->curr_site++)
 	Free(post_probs[br][tree->curr_site]);
       Free(post_probs[br]);
     }
@@ -1069,18 +1067,18 @@ phydbl **M4_Site_Branch_Classification(phydbl ***post_probs, t_tree *tree)
   phydbl post_prob_fast, post_prob_slow;
 
   best_probs = (phydbl **)mCalloc(tree->n_pattern,sizeof(phydbl *));
-  For(i,tree->n_pattern) best_probs[i] = (phydbl *)mCalloc(2*tree->n_otu-3,sizeof(phydbl));
+  for(i=0;i<tree->n_pattern;i++) best_probs[i] = (phydbl *)mCalloc(2*tree->n_otu-3,sizeof(phydbl));
 
   tree->write_labels = YES;
 
-  For(patt,tree->n_pattern) 
+  for(patt=0;patt<tree->n_pattern;patt++) 
     {
       For(br,2*tree->n_otu-3) 
 	{
 	  post_prob_fast = .0;
 	  post_prob_slow = .0;
 
-	  For(rcat,tree->mod->m4mod->n_h) /* For each rate class */
+	  for(rcat=0;rcat<tree->mod->m4mod->n_h;rcat++) /* For each rate class */
 	    {	      
 	      if(tree->mod->m4mod->multipl[rcat] > 1.0) 
 		post_prob_fast += post_probs[br][patt][rcat];
@@ -1125,7 +1123,7 @@ void M4_Site_Branch_Classification_Experiment(t_tree *tree)
   true_rclass = (short int **)mCalloc(tree->data->init_len, sizeof(short int *));
   est_rclass  = (short int **)mCalloc(tree->data->init_len, sizeof(short int *));
  
-  For(i,tree->data->init_len)
+  for(i=0;i<tree->data->init_len;i++)
     {
       true_rclass[i] = (short int *)mCalloc(2*tree->n_otu-3,sizeof(short int));
       est_rclass[i]  = (short int *)mCalloc(2*tree->n_otu-3,sizeof(short int));
@@ -1142,9 +1140,9 @@ void M4_Site_Branch_Classification_Experiment(t_tree *tree)
 
   /* Generate a simulated data set under H0, with the right sequence length. */
   PhyML_Printf("\n. Evolving sequences (delta=%f, alpha=%f) ...\n",tree->mod->m4mod->delta,tree->mod->m4mod->alpha);
-  Evolve(cpy_data,tree->mod,tree);
+  Evolve(cpy_data,tree->mod,0,tree);
 
-  For(i,cpy_data->init_len)
+  for(i=0;i<cpy_data->init_len;i++)
     {
       For(j,2*tree->n_otu-3)
 	{
@@ -1189,7 +1187,7 @@ void M4_Site_Branch_Classification_Experiment(t_tree *tree)
   PhyML_Printf("\n. Estimating model parameters...\n");
   tree->mod->s_opt->opt_cov_alpha = 1;
   tree->mod->s_opt->opt_cov_delta = 1;
-  Round_Optimize(tree,tree->data,ROUND_MAX);
+  Round_Optimize(tree,ROUND_MAX);
 
   tree->both_sides = 1;
   Lk(NULL,tree);
@@ -1197,7 +1195,7 @@ void M4_Site_Branch_Classification_Experiment(t_tree *tree)
   /* Classify branches */
   best_probs = M4_Site_Branch_Classification(M4_Compute_Proba_Hidden_States_On_Edges(tree),tree);
 
-  For(i,tree->data->init_len)
+  for(i=0;i<tree->data->init_len;i++)
     {
       For(j,2*tree->n_otu-3)
 	{
@@ -1224,7 +1222,7 @@ void M4_Site_Branch_Classification_Experiment(t_tree *tree)
   unknown       = .0;
   correct_class = .0;
   mis_class     = .0;
-  For(i,tree->data->init_len)
+  for(i=0;i<tree->data->init_len;i++)
     {
       For(j,2*tree->n_otu-3)
 	{
@@ -1260,7 +1258,7 @@ void M4_Site_Branch_Classification_Experiment(t_tree *tree)
 	 unknown);
 
 
-  For(i,tree->data->init_len)
+  for(i=0;i<tree->data->init_len;i++)
     {
       Free(true_rclass[i]);
       Free(est_rclass[i]);
@@ -1286,9 +1284,9 @@ void M4_Scale_Br_Len(t_tree *tree)
 
   /* (1) Work out the relative mean rate of switches */
   mrs = .0;
-  For(i,tree->mod->m4mod->n_h)
+  for(i=0;i<tree->mod->m4mod->n_h;i++)
     {
-      For(j,tree->mod->m4mod->n_h)
+      for(j=0;j<tree->mod->m4mod->n_h;j++)
 	{
 	  if(j != i)
 	    mrs += tree->mod->m4mod->h_fq[i] * tree->mod->m4mod->h_mat[i*tree->mod->m4mod->n_h+j];
@@ -1310,11 +1308,11 @@ void M4_Free_Integral_Term_On_One_Edge(phydbl ****integral, t_tree *tree)
 {
   int g,i,j;
 
-  For(g,tree->mod->ras->n_catg)
+  for(g=0;g<tree->mod->ras->n_catg;g++)
     {
-      For(i,tree->mod->m4mod->n_h)
+      for(i=0;i<tree->mod->m4mod->n_h;i++)
 	{
-	  For(j,tree->mod->m4mod->n_h)
+	  for(j=0;j<tree->mod->m4mod->n_h;j++)
 	    {
 	      Free(integral[g][i][j]);
 	    }
@@ -1359,7 +1357,7 @@ void M4_Detect_Site_Switches_Experiment(t_tree *tree)
   Simu_Loop(tree);
   nocov_mod = (t_mod *)Copy_Model(tree->mod); /* Record model parameters */
   For(i,2*tree->n_otu-3) nocov_bl[i] = tree->a_edges[i]->l->v; /* Record branch lengths */
-  For(i,tree->data->crunch_len) site_lnl_nocov[i] = tree->cur_site_lk[i];
+  for(i=0;i<tree->data->crunch_len;i++) site_lnl_nocov[i] = tree->cur_site_lk[i];
   Print_Lk(tree,"[LnL under non-switching substitution model]");
   
   PhyML_Printf("\n. Estimate model parameters under switching substitution model.\n");
@@ -1367,16 +1365,16 @@ void M4_Detect_Site_Switches_Experiment(t_tree *tree)
   Simu_Loop(tree);
   cov_mod = (t_mod *)Copy_Model(tree->mod); /* Record model parameters */
   For(i,2*tree->n_otu-3) cov_bl[i] = tree->a_edges[i]->l->v; /* Record branch lengths */
-  For(i,tree->data->crunch_len) site_lnl_cov[i] = tree->cur_site_lk[i];
+  for(i=0;i<tree->data->crunch_len;i++) site_lnl_cov[i] = tree->cur_site_lk[i];
   Print_Lk(tree,"[LnL under switching substitution model]");
   
 
   PhyML_Printf("\n");
-  For(i,tree->data->crunch_len) PhyML_Printf("TRUTH %f %f\n",site_lnl_nocov[i],site_lnl_cov[i]);
+  for(i=0;i<tree->data->crunch_len;i++) PhyML_Printf("TRUTH %f %f\n",site_lnl_nocov[i],site_lnl_cov[i]);
 
   /* Generate a simulated data set under H0, with the right sequence length. */
   tree->mod = nocov_mod;
-  Evolve(cpy_data, nocov_mod, tree);
+  Evolve(cpy_data, nocov_mod, 0, tree);
 
   /* Generate the memory needed for likelihood calculation because
      we will need bigger arrays 
@@ -1405,26 +1403,26 @@ void M4_Detect_Site_Switches_Experiment(t_tree *tree)
       For(i,2*tree->n_otu-3) Update_PMat_At_Given_Edge(tree->a_edges[i],tree);
       
       /* Generate sequences */
-      Evolve(cpy_data, nocov_mod, tree);
+      Evolve(cpy_data, nocov_mod, 0, tree);
       tree->data = cpy_data;
 
-      if(tree->mod->s_opt->greedy) Init_P_Lk_Tips_Double(tree);
-      else Init_P_Lk_Tips_Int(tree);
+      if(tree->mod->s_opt->greedy) Init_Partial_Lk_Tips_Double(tree);
+      else Init_Partial_Lk_Tips_Int(tree);
       
       tree->mod = nocov_mod;
       For(i,2*tree->n_otu-3) tree->a_edges[i]->l->v = nocov_bl[i];
       Lk(NULL,tree);
-      For(i,tree->data->crunch_len) site_lnl_nocov[i] = tree->cur_site_lk[i];
+      for(i=0;i<tree->data->crunch_len;i++) site_lnl_nocov[i] = tree->cur_site_lk[i];
       Print_Lk(tree,"[CPY LnL under non-switching substitution model]");
 
       tree->mod = cov_mod;
       For(i,2*tree->n_otu-3) tree->a_edges[i]->l->v = cov_bl[i];
       Lk(NULL,tree);
-      For(i,tree->data->crunch_len) site_lnl_cov[i] = tree->cur_site_lk[i];
+      for(i=0;i<tree->data->crunch_len;i++) site_lnl_cov[i] = tree->cur_site_lk[i];
       Print_Lk(tree,"[CPY LnL under switching substitution model]");
 
       PhyML_Printf("\n");
-      For(i,tree->data->crunch_len) PhyML_Printf("SYNTH %f %f\n",site_lnl_nocov[i],site_lnl_cov[i]);
+      for(i=0;i<tree->data->crunch_len;i++) PhyML_Printf("SYNTH %f %f\n",site_lnl_nocov[i],site_lnl_cov[i]);
     }
   while(++n_iter < 200);
 
@@ -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);
 }
@@ -1503,7 +1501,7 @@ void M4_Posterior_Prediction_Experiment(t_tree *tree)
   /* Generate a simulated data set under H0, with the right sequence length. */
   Set_Model_Parameters(tree->mod);
   For(i,2*tree->n_otu-3) Update_PMat_At_Given_Edge(tree->a_edges[i],tree);
-  Evolve(cpy_data,tree->mod,tree);
+  Evolve(cpy_data,tree->mod,0,tree);
 
   /* Generate the memory needed for likelihood calculation because
      we will need bigger arrays
@@ -1524,8 +1522,8 @@ void M4_Posterior_Prediction_Experiment(t_tree *tree)
   tree->data      = ori_data;
   tree->n_pattern = ori_data->crunch_len;
   
-  if(tree->mod->s_opt->greedy) Init_P_Lk_Tips_Double(tree);
-  else Init_P_Lk_Tips_Int(tree);
+  if(tree->mod->s_opt->greedy) Init_Partial_Lk_Tips_Double(tree);
+  else Init_Partial_Lk_Tips_Int(tree);
 
   PhyML_Printf("\n. Estimate model parameters under non-switching substitution model.\n");
   Switch_From_M4mod_To_Mod(tree->mod);
@@ -1551,12 +1549,12 @@ void M4_Posterior_Prediction_Experiment(t_tree *tree)
   n_iter = 0;
   do
     {
-      Evolve(cpy_data,tree->mod,tree);
+      Evolve(cpy_data,tree->mod,0,tree);
       tree->data      = cpy_data;
       tree->n_pattern = cpy_data->init_len;
 
-      if(tree->mod->s_opt->greedy) Init_P_Lk_Tips_Double(tree);
-      else Init_P_Lk_Tips_Int(tree);
+      if(tree->mod->s_opt->greedy) Init_Partial_Lk_Tips_Double(tree);
+      else Init_Partial_Lk_Tips_Int(tree);
 
       Lk(NULL,tree);
 
@@ -1572,8 +1570,8 @@ void M4_Posterior_Prediction_Experiment(t_tree *tree)
   tree->data      = ori_data;
   tree->n_pattern = ori_data->crunch_len;
   
-  if(tree->mod->s_opt->greedy) Init_P_Lk_Tips_Double(tree);
-  else Init_P_Lk_Tips_Int(tree);
+  if(tree->mod->s_opt->greedy) Init_Partial_Lk_Tips_Double(tree);
+  else Init_Partial_Lk_Tips_Int(tree);
 
   PhyML_Printf("\n. Estimate model parameters under switching substitution model.\n");
   Switch_From_Mod_To_M4mod(tree->mod);
@@ -1586,11 +1584,11 @@ void M4_Posterior_Prediction_Experiment(t_tree *tree)
   n_iter = 0;
   do
     {
-      Evolve(cpy_data,tree->mod,tree);
+      Evolve(cpy_data,tree->mod,0,tree);
       tree->data      = cpy_data;
       tree->n_pattern = cpy_data->init_len;
-      if(tree->mod->s_opt->greedy) Init_P_Lk_Tips_Double(tree);
-      else Init_P_Lk_Tips_Int(tree);
+      if(tree->mod->s_opt->greedy) Init_Partial_Lk_Tips_Double(tree);
+      else Init_Partial_Lk_Tips_Int(tree);
 
       Lk(NULL,tree);
 
@@ -1637,15 +1635,15 @@ m4 *M4_Copy_M4_Model(t_mod *ori_mod, m4 *ori_m4mod)
       
       cpy_m4mod->n_h = ori_m4mod->n_h;
       cpy_m4mod->n_o = ori_m4mod->n_o;
-      For(i,n_h) For(j,n_o*n_o) cpy_m4mod->o_mats[i][j] = ori_m4mod->o_mats[i][j];
-      For(i,n_h) cpy_m4mod->multipl[i] = ori_m4mod->multipl[i];
-      For(i,n_h) cpy_m4mod->multipl_unscaled[i] = ori_m4mod->multipl_unscaled[i];  
+      for(i=0;i<n_h;i++) For(j,n_o*n_o) cpy_m4mod->o_mats[i][j] = ori_m4mod->o_mats[i][j];
+      for(i=0;i<n_h;i++) cpy_m4mod->multipl[i] = ori_m4mod->multipl[i];
+      for(i=0;i<n_h;i++) cpy_m4mod->multipl_unscaled[i] = ori_m4mod->multipl_unscaled[i];  
       For(i,n_o*n_o) cpy_m4mod->o_rr[i] = ori_m4mod->o_rr[i];
       For(i,n_h*n_h) cpy_m4mod->h_rr[i] = ori_m4mod->h_rr[i];
       For(i,n_h*n_h) cpy_m4mod->h_mat[i] = ori_m4mod->h_mat[i];
-      For(i,n_o) cpy_m4mod->o_fq[i] = ori_m4mod->o_fq[i];
-      For(i,n_h) cpy_m4mod->h_fq[i] = ori_m4mod->h_fq[i];
-      For(i,n_h) cpy_m4mod->h_fq_unscaled[i] = ori_m4mod->h_fq_unscaled[i];
+      for(i=0;i<n_o;i++) cpy_m4mod->o_fq[i] = ori_m4mod->o_fq[i];
+      for(i=0;i<n_h;i++) cpy_m4mod->h_fq[i] = ori_m4mod->h_fq[i];
+      for(i=0;i<n_h;i++) cpy_m4mod->h_fq_unscaled[i] = ori_m4mod->h_fq_unscaled[i];
       cpy_m4mod->delta = ori_m4mod->delta;
       cpy_m4mod->alpha = ori_m4mod->alpha;
     }
diff --git a/src/m4.h b/src/m4.h
index ad2f3d3..1d9c050 100644
--- a/src/m4.h
+++ b/src/m4.h
@@ -40,8 +40,8 @@ void M4_Free_M4_Model(m4 *m4mod);
 void M4_Init_Qmat(m4 *m4mod, calign *data, t_mod *mod);
 void M4_Update_Qmat(m4 *m4mod, t_mod *mod);
 void M4_Init_Model(m4 *m4mod, calign *data, t_mod *mod);
-void M4_Init_P_Lk_Tips_Double(t_tree *tree);
-void M4_Init_P_Lk_Tips_Int(t_tree *tree);
+void M4_Init_Partial_Lk_Tips_Double(t_tree *tree);
+void M4_Init_Partial_Lk_Tips_Int(t_tree *tree);
 void M4_Post_Prob_H_Class_Edge_Site(t_edge *b, phydbl ****integral, phydbl *postprob, t_tree *tree);
 phydbl ****M4_Integral_Term_On_One_Edge(t_edge *b, t_tree *tree);
 phydbl ***M4_Compute_Proba_Hidden_States_On_Edges(t_tree *tree);
diff --git a/src/main.c b/src/main.c
index e13fd42..f1c0144 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,7 +1,7 @@
 /*
 
-PhyML:  a program that  computes maximum likelihood phyLOGenies from
-DNA or AA homoLOGous sequences.
+PhyML:  a program that  computes maximum likelihood phylogenies from
+DNA or AA homologous sequences.
 
 Copyright (C) Stephane Guindon. Oct 2003 onward.
 
@@ -81,7 +81,6 @@ int main(int argc, char **argv)
       return(0);
     }
 
-
 #ifdef EVOLVE
   io->colalias = NO;
 #endif
@@ -105,7 +104,7 @@ int main(int argc, char **argv)
       io->n_trees     = MIN(io->n_trees,io->n_data_sets);
     }
 
-  For(num_data_set,io->n_data_sets)
+  for(num_data_set=0;num_data_set<io->n_data_sets;num_data_set++)
     {
       best_lnL = UNLIKELY;
       Get_Seq(io);
@@ -117,14 +116,14 @@ int main(int argc, char **argv)
       
       if(io->data)
         {
-          if(io->n_data_sets > 1) PhyML_Printf("\n. Data set [#%d]\n",num_data_set+1);
+          if(io->n_data_sets > 1) PhyML_Printf("\n\u2022 Data set [#%d]\n",num_data_set+1);
           cdata = Compact_Data(io->data,io);
 
           Free_Seq(io->data,cdata->n_otu);
 
           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)
                 {
@@ -132,10 +131,10 @@ int main(int argc, char **argv)
                   Exit("\n");
                 }
 
-              For(num_rand_tree,io->mod->s_opt->n_rand_starts)
+              for(num_rand_tree=0;num_rand_tree<io->mod->s_opt->n_rand_starts;num_rand_tree++)
                 {
                   if((io->mod->s_opt->random_input_tree) && (io->mod->s_opt->topo_search != NNI_MOVE))
-                    if(!io->quiet) PhyML_Printf("\n\n. [Random start %3d/%3d]",num_rand_tree+1,io->mod->s_opt->n_rand_starts);
+                    if(!io->quiet) PhyML_Printf("\n\n\u2022 [Random start %3d/%3d]",num_rand_tree+1,io->mod->s_opt->n_rand_starts);
 
                   Init_Model(cdata,mod,io);
 
@@ -152,7 +151,7 @@ int main(int argc, char **argv)
                     {
                       char *s;
 
-                      PhyML_Printf("\n. Reading constraint tree file...");
+                      PhyML_Printf("\n\u2022 Reading constraint tree file...");
                       
                       io->cstr_tree = Read_Tree_File_Phylip(io->fp_in_constraint_tree);
 
@@ -173,7 +172,7 @@ int main(int argc, char **argv)
                       Get_Bip(io->cstr_tree->a_nodes[0],
                               io->cstr_tree->a_nodes[0]->v[0],
                               io->cstr_tree);
-                      if(!tree->has_branch_lengths) Add_BioNJ_Branch_Lengths(tree,cdata,mod);                      
+                      if(tree->has_branch_lengths == NO) Add_BioNJ_Branch_Lengths(tree,cdata,mod,NULL);
                     }
 
                   if(!tree) continue;
@@ -205,11 +204,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,20 +223,18 @@ 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->mod->s_opt->opt_topo)
+                  if(tree->io->print_json_trace == YES) JSON_Tree_Io(tree,tree->io->fp_out_json_trace); 
+                                                     
+                  Switch_Eigen(YES,tree->mod);                 
+                  Lk(NULL,tree);
+                  Switch_Eigen(NO,tree->mod);
+                  
+                  if(tree->mod->s_opt->opt_topo)
 		    {
 		      if(tree->mod->s_opt->topo_search      == NNI_MOVE) Simu_Loop(tree);
 		      else if(tree->mod->s_opt->topo_search == SPR_MOVE) Speed_Spr_Loop(tree);
 		      else                                               Best_Of_NNI_And_SPR(tree);
-
+                      
                       if(tree->n_root) Add_Root(tree->a_edges[0],tree);
                     }
                   else
@@ -246,25 +243,21 @@ int main(int argc, char **argv)
                       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);
-                      } 
-                      else { //No topology or branch length optimizations
-                        Lk(NULL,tree);
-                      }
+                      /* if(tree->mod->s_opt->opt_subst_param || tree->mod->s_opt->opt_bl)  */
+                        Round_Optimize(tree,ROUND_MAX);
+                       
                     }
-
-
-                  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);
                   Pars(NULL,tree);
                   Get_Tree_Size(tree);
-                  PhyML_Printf("\n\n. Log likelihood of the current tree: %f.",tree->c_lnL);
+                  PhyML_Printf("\n\n\u2022 Log likelihood of the current tree: %f.",tree->c_lnL);
 
                           
-                  if(tree->io->ancestral == YES) ML_Ancestral_Sequences(tree);
+                  if(tree->io->ancestral == YES) Ancestral_Sequences(tree,YES);
                   
                   /* Build_Distrib_Number_Of_Diff_States_Under_Model(tree); */
                   /* Exit("\n"); */
@@ -276,7 +269,7 @@ int main(int argc, char **argv)
 
 #elif defined EVOLVE
                   Evolve(tree->data,tree->mod,tree);
-                  Exit("\n. Exiting 'evolve'\n");
+                  Exit("\n\u2022 Exiting 'evolve'\n");
 #endif
 
                   if(!tree->n_root) Get_Best_Root_Position(tree);
@@ -326,16 +319,16 @@ int main(int argc, char **argv)
               /* Launch bootstrap analysis */
               if(mod->bootstrap)
                 {
-                  if(!io->quiet) PhyML_Printf("\n\n. Launch bootstrap analysis on the most likely tree...");
+                  if(!io->quiet) PhyML_Printf("\n\n\u2022 Launch bootstrap analysis on the most likely tree...");
 
 #ifdef MPI
                   MPI_Bcast (most_likely_tree, strlen(most_likely_tree)+1, MPI_CHAR, 0, MPI_COMM_WORLD);
-                  if(!io->quiet)  PhyML_Printf("\n\n. The bootstrap analysis will use %d CPUs.",Global_numTask);
+                  if(!io->quiet)  PhyML_Printf("\n\n\u2022 The bootstrap analysis will use %d CPUs.",Global_numTask);
 #endif
                   
                   most_likely_tree = Bootstrap_From_String(most_likely_tree,cdata,mod,io);
 
-                  PhyML_Printf("\n\n. Completed the bootstrap analysis succesfully."); fflush(NULL);
+                  PhyML_Printf("\n\n\u2022 Completed the bootstrap analysis succesfully."); fflush(NULL);
                 }
               else
                 if(io->ratio_test != NO)
@@ -345,13 +338,13 @@ int main(int argc, char **argv)
                   }
 
               /* Print the most likely tree in the output file */
-              if(!io->quiet) PhyML_Printf("\n\n. Printing the most likely tree in file '%s'.", Basename(io->out_tree_file));
+              if(!io->quiet) PhyML_Printf("\n\n\u2022 Printing the most likely tree in file '%s'.", Basename(io->out_tree_file));
               if(io->n_data_sets == 1) rewind(io->fp_out_tree);
               PhyML_Fprintf(io->fp_out_tree,"%s\n",most_likely_tree);
 
               if(io->n_trees > 1 && io->n_data_sets > 1) break;
             }
-            Free_Cseq(cdata);
+            Free_Calign(cdata);
         }
     else
         {
@@ -364,7 +357,7 @@ int main(int argc, char **argv)
 
   if(most_likely_tree) Free(most_likely_tree);
 
-  if(mod->s_opt->n_rand_starts > 1) PhyML_Printf("\n. Best log likelihood: %f\n",best_lnL);
+  if(mod->s_opt->n_rand_starts > 1) PhyML_Printf("\n\u2022 Best log likelihood: %f\n",best_lnL);
 
   Free_Optimiz(mod->s_opt);
   M4_Free_M4_Model(mod->m4mod);
@@ -378,6 +371,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);
@@ -408,13 +402,13 @@ int main(int argc, char **argv)
   return 1;
 }
 
-#elif(PHYTIME)
-#include "times.h"
-int main(int argc, char **argv)
-{
-  TIMES_main(argc, argv);
-  return 1;
-}
+/* #elif(PHYTIME) */
+/* #include "times.h" */
+/* int main(int argc, char **argv) */
+/* { */
+/*   TIMES_main(argc, argv); */
+/*   return 1; */
+/* } */
 
 #elif(PHYCONT)
 #include "continuous.h"
@@ -441,7 +435,7 @@ int main(int argc, char **argv)
 
   For(i,2*tree1->n_otu-2)
     {
-      printf("\n. Node %d in tree1 matches node %d in tree2",i,(tree1->noeud[i]->match_node)?(tree1->noeud[i]->match_node->num):(-1));
+      printf("\n\u2022 Node %d in tree1 matches node %d in tree2",i,(tree1->noeud[i]->match_node)?(tree1->noeud[i]->match_node->num):(-1));
     }
 
 
@@ -471,7 +465,7 @@ int main(int argc, char **argv)
 /*   Get_Bip(tree1->noeud[0],tree1->noeud[0]->v[0],tree1); */
 /*   Get_Bip(tree2->noeud[0],tree2->noeud[0]->v[0],tree2); */
 
-/* /\*   PhyML_Printf("\n. rf=%f\n",Compare_Bip_On_Existing_Edges(thresh,tree1,tree2)); *\/ */
+/* /\*   PhyML_Printf("\n\u2022 rf=%f\n",Compare_Bip_On_Existing_Edges(thresh,tree1,tree2)); *\/ */
 /*   For(i,2*tree1->n_otu-3) tree1->a_edges[i]->bip_score = 0; */
 /*   For(i,2*tree2->n_otu-3) tree2->a_edges[i]->bip_score = 0; */
 
@@ -517,12 +511,12 @@ int main(int argc, char **argv)
 
 /*   if(!n_edges) */
 /*     { */
-/*       Exit("\n. No comparable internal edges were found.\n"); */
+/*       Exit("\n\u2022 No comparable internal edges were found.\n"); */
 /*     } */
 /*   else */
 /*     { */
-/*       PhyML_Printf("\n. Robinson and Foulds distance: %f.",(double)rf/(n_edges)); */
-/* /\*       PhyML_Printf("\n. %d internal edges were processed (%d in the first tree, %d in the second).\n",n_edges,n_edges_t1,n_edges-n_edges_t1); *\/ */
+/*       PhyML_Printf("\n\u2022 Robinson and Foulds distance: %f.",(double)rf/(n_edges)); */
+/* /\*       PhyML_Printf("\n\u2022 %d internal edges were processed (%d in the first tree, %d in the second).\n",n_edges,n_edges_t1,n_edges-n_edges_t1); *\/ */
 /*       PhyML_Printf("\n"); */
 /*     } */
 
@@ -569,6 +563,14 @@ int main(int argc, char **argv)
   return 1;
 }
 
+#elif(PHYTIME)
+#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..77a2097 100644
--- a/src/make.c
+++ b/src/make.c
@@ -25,8 +25,28 @@ void Make_Tree_4_Lk(t_tree *tree, calign *cdata, int n_site)
   tree->unscaled_site_lk_cat = (phydbl *)mCalloc(MAX(tree->mod->ras->n_catg,tree->mod->n_mixt_classes)*tree->n_pattern,sizeof(phydbl));
   tree->fact_sum_scale       = (int *)mCalloc(tree->n_pattern,sizeof(int));
 
+#if (defined(__AVX__) || defined(__SSE3__))
+#ifndef WIN32
+  if(posix_memalign((void **)&tree->eigen_lr_left,BYTE_ALIGN,(size_t)MAX(tree->mod->ras->n_catg,tree->mod->n_mixt_classes)*tree->mod->ns*sizeof(double))) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
+  if(posix_memalign((void **)&tree->eigen_lr_rght,BYTE_ALIGN,(size_t)MAX(tree->mod->ras->n_catg,tree->mod->n_mixt_classes)*tree->mod->ns*sizeof(double))) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
+  if(posix_memalign((void **)&tree->dot_prod,BYTE_ALIGN,(size_t)tree->n_pattern*tree->mod->ns*MAX(tree->mod->ras->n_catg,tree->mod->n_mixt_classes)*sizeof(double))) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
+  if(posix_memalign((void **)&tree->expl,BYTE_ALIGN,(size_t)3*MAX(tree->mod->ras->n_catg,tree->mod->n_mixt_classes)*tree->mod->ns*sizeof(double))) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
+#else
+  tree->eigen_lr_left = _aligned_malloc(MAX(tree->mod->ras->n_catg,tree->mod->n_mixt_classes) * tree->mod->ns * sizeof(phydbl),BYTE_ALIGN);
+  tree->eigen_lr_rght = _aligned_malloc(MAX(tree->mod->ras->n_catg,tree->mod->n_mixt_classes) * tree->mod->ns * sizeof(phydbl),BYTE_ALIGN);
+  tree->dot_prod = _aligned_malloc(tree->n_pattern*tree->mod->ns*MAX(tree->mod->ras->n_catg,tree->mod->n_mixt_classes)*sizeof(phydbl),BYTE_ALIGN);
+  tree->expl = _aligned_malloc(3*MAX(tree->mod->ras->n_catg,tree->mod->n_mixt_classes)*tree->mod->ns*sizeof(phydbl),BYTE_ALIGN);
+#endif
+#else
+  tree->eigen_lr_left = (phydbl *)mCalloc(MAX(tree->mod->ras->n_catg,tree->mod->n_mixt_classes) * tree->mod->ns,sizeof(phydbl));
+  tree->eigen_lr_rght = (phydbl *)mCalloc(MAX(tree->mod->ras->n_catg,tree->mod->n_mixt_classes) * tree->mod->ns,sizeof(phydbl));
+  tree->dot_prod = (phydbl *)mCalloc(tree->n_pattern*tree->mod->ns*MAX(tree->mod->ras->n_catg,tree->mod->n_mixt_classes),sizeof(phydbl));
+  tree->expl = (phydbl *)mCalloc(3*MAX(tree->mod->ras->n_catg,tree->mod->n_mixt_classes)*tree->mod->ns,sizeof(phydbl));
+#endif
+
+
   tree->log_lks_aLRT = (phydbl **)mCalloc(3,sizeof(phydbl *));
-  For(i,3) tree->log_lks_aLRT[i] = (phydbl *)mCalloc(tree->data->init_len,sizeof(phydbl));
+  for(i=0;i<3;i++) tree->log_lks_aLRT[i] = (phydbl *)mCalloc(tree->data->init_len,sizeof(phydbl));
 
   For(i,2*tree->n_otu-1) Make_Edge_NNI(tree->a_edges[i]);
 
@@ -34,13 +54,18 @@ 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);
-      else
-        Init_P_Lk_Tips_Int(tree);
+      Init_Partial_Lk_Tips_Double(tree);
+      Init_Partial_Lk_Loc(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 +78,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 */
+  Init_Partial_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);
 }
 
@@ -66,14 +99,14 @@ void Make_All_Edges_Lk(t_node *a, t_node *d, t_tree *tree)
 {
   int i;
 
-  For(i,3) 
+  for(i=0;i<3;i++) 
     if((a->v[i]) && (a->v[i] == d)) 
       Make_Edge_Lk(a->b[i],tree);
 
   if(d->tax) return;
   else
     {
-      For(i,3)
+      for(i=0;i<3;i++)
         {
           if(d->v[i] != a && d->b[i] != tree->e_root)
             Make_All_Edges_Lk(d,d->v[i],tree);
@@ -163,7 +196,7 @@ void Make_Edge_Pars(t_edge *b, t_tree *tree)
 void Make_Edge_Pars_Left(t_edge *b, t_tree *tree)
 {
   b->pars_l = (int *)mCalloc(tree->data->crunch_len,sizeof(int));
-  b->ui_l = (unsigned int *)mCalloc(tree->data->crunch_len,sizeof(unsigned int));
+  b->ui_l = (int *)mCalloc(tree->data->crunch_len,sizeof(int));
   b->p_pars_l = (int *)mCalloc(tree->data->crunch_len*tree->mod->ns,sizeof(int ));
   b->n_diff_states_l = (int *)mCalloc(tree->mod->ns,sizeof(int ));
 }
@@ -174,7 +207,7 @@ void Make_Edge_Pars_Left(t_edge *b, t_tree *tree)
 void Make_Edge_Pars_Rght(t_edge *b, t_tree *tree)
 {
   b->pars_r = (int *)mCalloc(tree->data->crunch_len,sizeof(int));
-  b->ui_r = (unsigned int *)mCalloc(tree->data->crunch_len,sizeof(unsigned int));
+  b->ui_r = (int *)mCalloc(tree->data->crunch_len,sizeof(int));
   b->p_pars_r = (int *)mCalloc(tree->data->crunch_len*tree->mod->ns,sizeof(int ));
   b->n_diff_states_r = (int *)mCalloc(tree->mod->ns,sizeof(int ));
 }
@@ -192,7 +225,18 @@ void Make_Edge_Lk(t_edge *b, t_tree *tree)
 
   b->l_old->v = b->l->v;
 
+#if (defined(__AVX__) || defined(__SSE3__))
+#ifndef WIN32
+  if(posix_memalign((void *)&b->Pij_rr,BYTE_ALIGN,(size_t)tree->mod->ras->n_catg*tree->mod->ns*tree->mod->ns*sizeof(phydbl))) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
+  if(posix_memalign((void *)&b->tPij_rr,BYTE_ALIGN,(size_t)tree->mod->ras->n_catg*tree->mod->ns*tree->mod->ns*sizeof(phydbl))) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
+#else
+  b->Pij_rr = _aligned_malloc(tree->mod->ras->n_catg*tree->mod->ns*tree->mod->ns*sizeof(phydbl),BYTE_ALIGN);
+  b->tPij_rr = _aligned_malloc(tree->mod->ras->n_catg*tree->mod->ns*tree->mod->ns*sizeof(phydbl),BYTE_ALIGN);
+#endif
+#else
   b->Pij_rr = (phydbl *)mCalloc(tree->mod->ras->n_catg*tree->mod->ns*tree->mod->ns,sizeof(phydbl));
+  b->tPij_rr = (phydbl *)mCalloc(tree->mod->ras->n_catg*tree->mod->ns*tree->mod->ns,sizeof(phydbl));
+#endif
 
   Make_Edge_Lk_Left(b,tree);
   Make_Edge_Lk_Rght(b,tree);
@@ -218,13 +262,30 @@ void Make_Edge_Lk_Left(t_edge *b, t_tree *tree)
     {
       if((!b->left->tax) || (tree->mod->s_opt->greedy))
         {
+#if (defined(__AVX__) || defined(__SSE3__))
+#ifndef WIN32
+          if(posix_memalign((void **)&b->p_lk_left,BYTE_ALIGN,(size_t)tree->data->crunch_len*MAX(tree->mod->ras->n_catg,tree->mod->n_mixt_classes)*tree->mod->ns*sizeof(double))) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
+#else
+          b->p_lk_left = _aligned_malloc(tree->data->crunch_len*MAX(tree->mod->ras->n_catg,tree->mod->n_mixt_classes)*tree->mod->ns*sizeof(phydbl),BYTE_ALIGN);
+#endif
+#else
           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));
+#endif
           b->p_lk_tip_l = NULL;
         }
       else if(b->left->tax)
         {
           b->p_lk_left   = NULL;
-          b->p_lk_tip_l  = (short int *)mCalloc(tree->data->crunch_len*tree->mod->ns,sizeof(short int ));
+          
+#if (defined(__AVX__) || defined(__SSE3__))
+#ifndef WIN32
+          if(posix_memalign((void **)&b->p_lk_tip_l,BYTE_ALIGN,(size_t)tree->data->crunch_len*tree->mod->ns*sizeof(double))) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
+#else
+          b->p_lk_tip_l = _aligned_malloc(tree->data->crunch_len*tree->mod->ns*sizeof(phydbl),BYTE_ALIGN);
+#endif
+#else
+          b->p_lk_tip_l  = (phydbl *)mCalloc(tree->data->crunch_len*tree->mod->ns,sizeof(phydbl));
+#endif
         }
     }
   else
@@ -236,12 +297,19 @@ void Make_Edge_Lk_Left(t_edge *b, t_tree *tree)
   if(b->num >= 2*tree->n_otu-3)
     {
       b->sum_scale_left = (int *)mCalloc(tree->data->crunch_len*MAX(tree->mod->ras->n_catg,tree->mod->n_mixt_classes),sizeof(int));
+
+#if (defined(__AVX__) || defined(__SSE3__))
+#ifndef WIN32
+      if(posix_memalign((void **)&b->p_lk_left,BYTE_ALIGN,(size_t)tree->data->crunch_len*MAX(tree->mod->ras->n_catg,tree->mod->n_mixt_classes)*tree->mod->ns*sizeof(double))) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
+#else
+      b->p_lk_left = _aligned_malloc(tree->data->crunch_len*MAX(tree->mod->ras->n_catg,tree->mod->n_mixt_classes)*tree->mod->ns*sizeof(phydbl),BYTE_ALIGN);
+#endif
+#else
       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));
+#endif
     }
 
-
   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));
 }
 
 //////////////////////////////////////////////////////////////
@@ -265,13 +333,29 @@ void Make_Edge_Lk_Rght(t_edge *b, t_tree *tree)
     {
       if((!b->rght->tax) || (tree->mod->s_opt->greedy))
         {
+#if (defined(__AVX__) || defined(__SSE3__))
+#ifndef WIN32
+	  if(posix_memalign((void **)&b->p_lk_rght,BYTE_ALIGN,(size_t)tree->data->crunch_len*MAX(tree->mod->ras->n_catg,tree->mod->n_mixt_classes)*tree->mod->ns*sizeof(double))) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
+#else          
+          b->p_lk_rght = _aligned_malloc(tree->data->crunch_len*MAX(tree->mod->ras->n_catg,tree->mod->n_mixt_classes)*tree->mod->ns*sizeof(phydbl),BYTE_ALIGN);
+#endif
+#else
           b->p_lk_rght = (phydbl *)mCalloc(tree->data->crunch_len*MAX(tree->mod->ras->n_catg,tree->mod->n_mixt_classes)*tree->mod->ns,sizeof(phydbl));
+#endif
           b->p_lk_tip_r = NULL;
         }
       else if(b->rght->tax)
         {
+#if (defined(__AVX__) || defined(__SSE3__))
+#ifndef WIN32
+          if(posix_memalign((void **)&b->p_lk_tip_r,BYTE_ALIGN,(size_t)tree->data->crunch_len*tree->mod->ns*sizeof(double))) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
+#else
+          b->p_lk_tip_r = _aligned_malloc(tree->data->crunch_len*tree->mod->ns*sizeof(phydbl),BYTE_ALIGN);
+#endif
+#else
+          b->p_lk_tip_r  = (phydbl *)mCalloc(tree->data->crunch_len*tree->mod->ns,sizeof(phydbl));
+#endif
           b->p_lk_rght = NULL;
-          b->p_lk_tip_r  = (short int *)mCalloc(tree->data->crunch_len*tree->mod->ns,sizeof(short int));
         }
     }
   else
@@ -283,16 +367,50 @@ void Make_Edge_Lk_Rght(t_edge *b, t_tree *tree)
   if(b->num >= 2*tree->n_otu-3)
     {
       b->sum_scale_rght = (int *)mCalloc(tree->data->crunch_len*MAX(tree->mod->ras->n_catg,tree->mod->n_mixt_classes),sizeof(int));
+#if (defined(__AVX__) || defined(__SSE3__))
+#ifndef WIN32
+      if(posix_memalign((void **)&b->p_lk_rght,BYTE_ALIGN,(size_t)tree->data->crunch_len*MAX(tree->mod->ras->n_catg,tree->mod->n_mixt_classes)*tree->mod->ns*sizeof(double))) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
+#else
+      b->p_lk_rght      = _aligned_malloc(tree->data->crunch_len*MAX(tree->mod->ras->n_catg,tree->mod->n_mixt_classes)*tree->mod->ns*sizeof(phydbl),BYTE_ALIGN);
+#endif
+
+
+#else
       b->p_lk_rght      = (phydbl *)mCalloc(tree->data->crunch_len*MAX(tree->mod->ras->n_catg,tree->mod->n_mixt_classes)*tree->mod->ns,sizeof(phydbl));
+#endif
     }
 
   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 +422,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 +446,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;
@@ -351,7 +471,7 @@ nexcom **Make_Nexus_Com()
 
   com = (nexcom **)mCalloc(N_MAX_NEX_COM,sizeof(nexcom *));
 
-  For(i,N_MAX_NEX_COM)
+  for(i=0;i<N_MAX_NEX_COM;i++)
     {
       com[i]       = (nexcom *)mCalloc(1,sizeof(nexcom));
       com[i]->name = (char *)mCalloc(T_MAX_NEX_COM,sizeof(char));
@@ -396,7 +516,7 @@ matrix *Make_Mat(int n_otu)
   mat->tip_node = (t_node **)mCalloc(n_otu,sizeof(t_node *));
 
 
-  For(i,n_otu)
+  for(i=0;i<n_otu;i++)
     {
       mat->P[i]    = (phydbl *)mCalloc(n_otu,sizeof(phydbl));
       mat->Q[i]    = (phydbl *)mCalloc(n_otu,sizeof(phydbl));
@@ -411,7 +531,7 @@ matrix *Make_Mat(int n_otu)
 //////////////////////////////////////////////////////////////
 
 t_tree *Make_Tree_From_Scratch(int n_otu, calign *data)
-{
+{  
   t_tree *tree;
 
   tree = Make_Tree(n_otu);
@@ -424,27 +544,27 @@ t_tree *Make_Tree_From_Scratch(int n_otu, calign *data)
       Copy_Tax_Names_To_Tip_Labels(tree,data);
       tree->data = data;
     }
-
+  
+  
 #ifdef BEAGLE
   //offset the branch's partial indices because BEAGLE insists on first storing the tips/taxa
   int num_branches = 2*tree->n_otu-1;
   int i;
   for(i=0;i<2*tree->n_otu-1;++i)
-  {
+    {
       //For edgeX, its "left" partial lies at index `num_tax + edgeX->num"
       tree->a_edges[i]->p_lk_left_idx = tree->n_otu + tree->a_edges[i]->p_lk_left_idx;
       //For edgeX, its "right" partial lies at index `num_tax + edgeX->num + num_branches"
       tree->a_edges[i]->p_lk_rght_idx = tree->n_otu + tree->a_edges[i]->p_lk_left_idx + num_branches;
-  }
+    }
 #endif
-
+  
   return tree;
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 t_tree *Make_Tree(int n_otu)
 {
   t_tree *tree;
@@ -493,26 +613,20 @@ 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)
+  for(j=0;j<n_otu;j++)
     {
       cdata->c_seq[j]            = (align *)mCalloc(1,sizeof(align));
       cdata->c_seq[j]->name      = (char *)mCalloc((int)(strlen(sp_names[j])+1),sizeof(char));
@@ -619,10 +733,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);
 
@@ -631,6 +741,7 @@ t_mod *Make_Model_Basic()
 
   mod->aa_rate_mat_file       = Make_String(T_MAX_FILE);
   Init_String(mod->aa_rate_mat_file);
+
   return mod;
 }
 
@@ -650,7 +761,16 @@ void Make_Model_Complete(t_mod *mod)
 
   mod->Pij_rr = (vect_dbl *)mCalloc(1,sizeof(vect_dbl));
   Init_Vect_Dbl(0,mod->Pij_rr);
+
+#if (defined(__AVX__) || defined(__SSE3__))
+#ifndef WIN32
+  if(posix_memalign((void **)&mod->Pij_rr->v,BYTE_ALIGN,(size_t)mod->ras->n_catg*mod->ns*mod->ns*sizeof(double))) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
+#else
+  mod->Pij_rr->v = _aligned_malloc(mod->ras->n_catg*mod->ns*mod->ns*sizeof(phydbl),BYTE_ALIGN);
+#endif
+#else
   mod->Pij_rr->v = (phydbl *)mCalloc(mod->ras->n_catg*mod->ns*mod->ns,sizeof(phydbl));
+#endif
 
   mod->eigen     = (eigen *)Make_Eigen_Struct(mod->ns);
 
@@ -660,15 +780,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)
     {
@@ -750,13 +871,27 @@ t_efrq *Make_Efrq(int ns)
   e_frq = (t_efrq *)mCalloc(1,sizeof(t_efrq));
 
   e_frq->pi               = (vect_dbl *)mCalloc(1,sizeof(vect_dbl));
-  e_frq->pi->v            = (phydbl *)mCalloc(ns,sizeof(phydbl));
   e_frq->pi->len          = ns;
 
+#if (defined(__AVX__) || defined(__SSE3__))
+#ifndef WIN32
+  if(posix_memalign((void **)&e_frq->pi->v,BYTE_ALIGN,(size_t)ns*sizeof(double))) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
+#else
+  e_frq->pi->v = _aligned_malloc(ns * sizeof(phydbl),BYTE_ALIGN);
+#endif
+#else
+  e_frq->pi->v = (phydbl *)mCalloc(ns,sizeof(phydbl));
+#endif
+
+
   e_frq->pi_unscaled      = (vect_dbl *)mCalloc(1,sizeof(vect_dbl));
   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,14 +949,16 @@ 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));
   io->alphabet                          = (char **)mCalloc(T_MAX_ALPHABET,sizeof(char *));
-  For(i,T_MAX_ALPHABET) io->alphabet[i] = (char *)mCalloc(T_MAX_STATE,sizeof(char ));
+  for(i=0;i<T_MAX_ALPHABET;i++) io->alphabet[i] = (char *)mCalloc(T_MAX_STATE,sizeof(char ));
   io->treelist                          = (t_treelist *)mCalloc(1,sizeof(t_treelist));
   io->mcmc                              = (t_mcmc *)MCMC_Make_MCMC_Struct();
   io->rates                             = (t_rate *)RATES_Make_Rate_Struct(-1);
@@ -887,28 +1024,28 @@ triplet *Make_Triplet_Struct(t_mod *mod)
   triplet_struct->eigen_struct    = (eigen *)Make_Eigen_Struct(mod->ns);
   triplet_struct->mod             = mod;
 
-  For(k,mod->ras->n_catg)
+  for(k=0;k<mod->ras->n_catg;k++)
     {
       triplet_struct->core[k]                = (phydbl ***)mCalloc(mod->ns,sizeof(phydbl **));
-      For(i,mod->ns)
+      for(i=0;i<mod->ns;i++)
     {
       triplet_struct->core[k][i]         = (phydbl **)mCalloc(mod->ns,sizeof(phydbl *));
-      For(j,mod->ns)
+      for(j=0;j<mod->ns;j++)
         triplet_struct->core[k][i][j]    = (phydbl  *)mCalloc(mod->ns,sizeof(phydbl ));
     }
     }
 
-  For(i,mod->ns)
+  for(i=0;i<mod->ns;i++)
     {
       triplet_struct->p_one_site[i]          = (phydbl **)mCalloc(mod->ns,sizeof(phydbl *));
-      For(j,mod->ns)
+      for(j=0;j<mod->ns;j++)
     triplet_struct->p_one_site[i][j]     = (phydbl  *)mCalloc(mod->ns,sizeof(phydbl ));
     }
 
-  For(i,mod->ns)
+  for(i=0;i<mod->ns;i++)
     {
       triplet_struct->sum_p_one_site[i]      = (phydbl **)mCalloc(mod->ns,sizeof(phydbl *));
-      For(j,mod->ns)
+      for(j=0;j<mod->ns;j++)
     triplet_struct->sum_p_one_site[i][j] = (phydbl  *)mCalloc(mod->ns,sizeof(phydbl ));
     }
 
@@ -969,16 +1106,9 @@ void XML_Make_Node_Value(xml_node *n, char *val)
 
 xml_node *XML_Make_Node(char *name)
 {
-
   xml_node *new_node = (xml_node *)mCalloc(1,sizeof(xml_node));
-
-  if(name)
-    {
-      new_node->name = (char *)mCalloc(strlen(name)+1,sizeof(char));
-    }
-
+  if(name) new_node->name = (char *)mCalloc(strlen(name)+1,sizeof(char));
   new_node->ds = (t_ds *)mCalloc(1,sizeof(t_ds));
-
   return new_node;
 }
 
@@ -1086,11 +1216,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 +1229,44 @@ 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);
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
+t_node **Make_Target_Tip(int n)
+{
+  t_node **this;
+  this = (t_node **)mCalloc(n,sizeof(t_node *));
+  return(this);
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+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 +1301,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 +1388,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);
@@ -1316,7 +1471,7 @@ void GEO_Make_Geo_Complete(int ldscape_sz, int n_dim, int n_tax, t_geo *t)
 
   // Locations
   t->coord_loc = (t_geo_coord **)mCalloc(ldscape_sz,sizeof(t_geo_coord *));
-  For(i,ldscape_sz) t->coord_loc[i] = GEO_Make_Geo_Coord(n_dim);
+  for(i=0;i<ldscape_sz;i++) t->coord_loc[i] = GEO_Make_Geo_Coord(n_dim);
 }
 
 //////////////////////////////////////////////////////////////
@@ -1397,13 +1552,33 @@ t_poly *Make_Poly(int n)
   int i;
   p = (t_poly *)mCalloc(1,sizeof(t_poly));
   p->poly_vert = (t_geo_coord **)mCalloc(n,sizeof(t_geo_coord *));
-  For(i,n) p->poly_vert[i] = GEO_Make_Geo_Coord(2);
+  for(i=0;i<n;i++) p->poly_vert[i] = GEO_Make_Geo_Coord(2);
   return(p);
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
+
+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..51f4622 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,12 @@ 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();
+t_node **Make_Target_Tip(int n);
 
 #endif
diff --git a/src/mcmc.c b/src/mcmc.c
index 0909182..ec37c3e 100644
--- a/src/mcmc.c
+++ b/src/mcmc.c
@@ -1,7 +1,7 @@
 /*
 
 PhyML:  a program that  computes maximum likelihood phylogenies from
-DNA or AA homoLOGous sequences.
+DNA or AA homologous sequences.
 
 Copyright (C) Stephane Guindon. Oct 2003 onward.
 
@@ -43,9 +43,7 @@ void MCMC(t_tree *tree)
     {
       MCMC_Read_Param_Vals(tree);
     }
-/* #ifdef INVITEE */
-/*   tree -> rates -> node_height_dens_log_norm_const_update = Norm_Constant_Prior_Times(tree); */
-/* #endif */
+
   Switch_Eigen(YES,tree->mod);
 
   MCMC_Initialize_Param_Val(tree->mcmc,tree);
@@ -53,14 +51,13 @@ void MCMC(t_tree *tree)
   Update_Ancestors(tree->n_root,tree->n_root->v[2],tree);
   Update_Ancestors(tree->n_root,tree->n_root->v[1],tree);
 
-  For(i,2*tree->n_otu-2) tree->rates->br_do_updt[i] = YES;  
   RATES_Update_Cur_Bl(tree);
   RATES_Lk_Rates(tree);	
 
 #ifdef INVITEE
   tree->rates->update_time_norm_const = YES;
 #endif
-  TIMES_Lk_Times(tree); 
+  TIMES_Lk_Times(NO,tree); 
 #ifdef INVITEE
   tree->rates->update_time_norm_const = NO;
 #endif
@@ -74,8 +71,7 @@ void MCMC(t_tree *tree)
   /* Exit("\n"); */
 
   Set_Both_Sides(NO,tree);  
-  if(tree->mcmc->use_data) Lk(NULL,tree);
-  else tree->c_lnL = 0.0;
+  Lk(NULL,tree);
   Switch_Eigen(NO,tree->mod);
   MCMC_Print_Param(tree->mcmc,tree);
   
@@ -89,7 +85,7 @@ void MCMC(t_tree *tree)
       
       Make_MutMap(tree);
  
-      For(j,tree->n_otu)
+      for(j=0;j<tree->n_otu;j++)
 	{
 	  s = (char *)mCalloc(T_MAX_NAME,sizeof(char));
 	  strcpy(s,tree->a_nodes[j]->name);
@@ -100,9 +96,9 @@ void MCMC(t_tree *tree)
       t = (char *)mCalloc(T_MAX_NAME,sizeof(char));
       
       tree->write_tax_names = YES;
-      For(i,tree->n_pattern)
+      for(i=0;i<tree->n_pattern;i++)
 	{
-	  For(j,tree->n_otu)
+	  for(j=0;j<tree->n_otu;j++)
 	    {
 	      strcpy(t,tree->a_nodes[j]->name);
 	      s[0]=tree->data->c_seq[j]->state[i];
@@ -120,7 +116,7 @@ void MCMC(t_tree *tree)
 	  PhyML_Fprintf(fp,"%s",s);
 	  fclose(fp);
 	  
-	  For(j,tree->n_otu) strcpy(tree->a_nodes[j]->name,t);
+	  for(j=0;j<tree->n_otu;j++) strcpy(tree->a_nodes[j]->name,t);
 	}
       Free(s);
       Free(t);
@@ -187,7 +183,7 @@ void MCMC(t_tree *tree)
 
       u = Uni();
 
-      For(move,tree->mcmc->n_moves) if(tree->mcmc->move_weight[move] > u) break;
+      for(move=0;move<tree->mcmc->n_moves;move++) if(tree->mcmc->move_weight[move] > u) break;
       
       if(u < .5) { first = 2; secod = 1; }
       else       { first = 1; secod = 2; }
@@ -289,19 +285,17 @@ void MCMC(t_tree *tree)
       else if(!strcmp(tree->mcmc->move_name[move],"time"))
       	{
           Set_Both_Sides(YES,tree);     
-      	  if(tree->mcmc->use_data == YES) Lk(NULL,tree);
+      	  Lk(NULL,tree);
           Set_Both_Sides(NO,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
       	    {
-	      /* 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); */
       	      RATES_Posterior_One_Time(tree->n_root,tree->n_root->v[first],YES,tree);
       	      RATES_Posterior_One_Time(tree->n_root,tree->n_root->v[secod],YES,tree);
       	    }
@@ -320,7 +314,7 @@ void MCMC(t_tree *tree)
       	{
 
       	  Set_Both_Sides(YES,tree);
-      	  if(tree->mcmc->use_data == YES) Lk(NULL,tree);
+      	  Lk(NULL,tree);
       	  Set_Both_Sides(NO,tree);
       	  
       	  if(tree->mcmc->is == NO)
@@ -339,7 +333,7 @@ void MCMC(t_tree *tree)
 
 	  /* MCMC_Sim_Rate(tree->n_root,tree->n_root->v[2],tree); */
 	  /* MCMC_Sim_Rate(tree->n_root,tree->n_root->v[1],tree); */
-      	  /* if(tree->mcmc->use_data == YES) Lk(NULL,tree); */
+      	  /* if(tree->eval_alnL == YES) Lk(NULL,tree); */
 	  /* RATES_Lk_Rates(tree); */          
       	}
 
@@ -361,7 +355,7 @@ void MCMC(t_tree *tree)
 	{
 	  if(!(tree->mcmc->run%tree->mcmc->sample_interval)) 
 	    {
-	      Sample_Ancestral_Seq(YES,!tree->mcmc->use_data,tree);
+	      Sample_Ancestral_Seq(YES,!tree->eval_alnL,tree);
 	      
 	      phydbl sum = 0.0;
 	      int edge,site,mut;
@@ -423,7 +417,7 @@ void MCMC_Single_Param_Generic(phydbl *val,
   new_val       = -1.0;
   ratio         =  0.0;
   K             = tree->mcmc->tune_move[move_num];
-  cur_lnval     = LOG(*val);
+  cur_lnval     = log(*val);
   new_lnval     = cur_lnval;
 
   if(lnLike)
@@ -464,7 +458,7 @@ void MCMC_Single_Param_Generic(phydbl *val,
 	  ratio += (new_lnPrior - cur_lnPrior); 
 	}
       
-      /* if(like_func && tree->mcmc->use_data == YES)  /\* Likelihood ratio *\/ */
+      /* if(like_func && tree->eval_alnL == YES)  /\* Likelihood ratio *\/ */
       if(like_func)  /* Likelihood ratio */
 	{ 
 	  new_lnLike  = (*like_func)(branch,tree,stree);  
@@ -481,7 +475,7 @@ void MCMC_Single_Param_Generic(phydbl *val,
       /*        new_lnPrior, */
       /*        ratio); */
 
-      ratio = EXP(ratio);
+      ratio = exp(ratio);
       alpha = MIN(1.,ratio);
       
       /* Always accept move */
@@ -538,7 +532,7 @@ void MCMC_Update_Effective_Sample_Size(int move_num, t_mcmc *mcmc, t_tree *tree)
   For(lag,MIN(N,mcmc->max_lag))
     {      
       rho = 0.0;
-      For(i,N-lag) rho += 
+      for(i=0;i<N-lag;i++) rho += 
         (mcmc->sampled_val[move_num*mcmc->sample_size+burnin+i]     - mean) *
         (mcmc->sampled_val[move_num*mcmc->sample_size+burnin+i+lag] - mean) ;
       
@@ -581,17 +575,17 @@ void MCMC_Update_Mode(int move_num, t_mcmc *mcmc, t_tree *tree)
   N -= burnin;
   
   min = +INFINITY;
-  For(i,N) 
+  for(i=0;i<N;i++) 
     if(mcmc->sampled_val[move_num*mcmc->sample_size+burnin+i] < min)
       min = mcmc->sampled_val[move_num*mcmc->sample_size+burnin+i];
 
   max = -INFINITY;
-  For(i,N) 
+  for(i=0;i<N;i++) 
     if(mcmc->sampled_val[move_num*mcmc->sample_size+burnin+i] > max)
       max = mcmc->sampled_val[move_num*mcmc->sample_size+burnin+i];
 
 
-  For(i,N) 
+  for(i=0;i<N;i++) 
     {
       for(j=1;j<breaks;j++)
         if(min+j*(max-min)/breaks > mcmc->sampled_val[move_num*mcmc->sample_size+burnin+i])
@@ -603,7 +597,7 @@ void MCMC_Update_Mode(int move_num, t_mcmc *mcmc, t_tree *tree)
 
   best_score = 0;
   best_bin = 0;
-  For(j,breaks) 
+  for(j=0;j<breaks;j++) 
     if(bin_score[j] > best_score) 
       {
         best_score = bin_score[j];
@@ -618,25 +612,79 @@ void MCMC_Update_Mode(int move_num, t_mcmc *mcmc, t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-void MCMC_Clock_R(t_tree *mixt_tree)
+void MCMC_Clock_R(t_tree *tree)
 {
-  t_tree *tree;
+  /* t_tree *tree; */
 
-  tree = mixt_tree;
-  do
-    {
-      MCMC_Single_Param_Generic(&(tree->rates->clock_r),
-                                mixt_tree->rates->min_clock,
-                                mixt_tree->rates->max_clock,
-                                mixt_tree->mcmc->num_move_clock_r,
-                                NULL,&(mixt_tree->c_lnL),
-                                NULL,Wrap_Lk,
-                                mixt_tree->mcmc->move_type[mixt_tree->mcmc->num_move_clock_r],
-                                NO,NULL,mixt_tree,NULL);
+  /* tree = mixt_tree; */
+  /* do */
+  /*   { */
+  /*     MCMC_Single_Param_Generic(&(tree->rates->clock_r), */
+  /*                               mixt_tree->rates->min_clock, */
+  /*                               mixt_tree->rates->max_clock, */
+  /*                               mixt_tree->mcmc->num_move_clock_r, */
+  /*                               NULL,&(mixt_tree->c_lnL), */
+  /*                               NULL,Wrap_Lk, */
+  /*                               mixt_tree->mcmc->move_type[mixt_tree->mcmc->num_move_clock_r], */
+  /*                               NO,NULL,mixt_tree,NULL); */
+
+  /*     tree = tree->next; */
+  /*   } */
+  /* while(tree); */
 
-      tree = tree->next;
+  phydbl new_lnL_data, cur_lnL_data;
+  phydbl new_lnL_rate, cur_lnL_rate;
+  phydbl u, ratio, alpha;
+  phydbl new_clock_r, cur_clock_r;
+  phydbl min, max;
+  int move_num;
+  phydbl K;
+
+   
+  new_clock_r  = tree->rates->clock_r;
+  cur_clock_r  = tree->rates->clock_r;
+  min          = tree->rates->min_clock;
+  max          = tree->rates->max_clock;
+  ratio        = 0.0;
+  move_num     = tree->mcmc->num_move_clock_r;
+  K            = tree->mcmc->tune_move[move_num];
+  cur_lnL_data = tree->c_lnL;
+  new_lnL_data = UNLIKELY;
+  cur_lnL_rate = tree->rates->c_lnL_rates;
+  new_lnL_rate = UNLIKELY;
+  
+  MCMC_Make_Move(&cur_clock_r,&new_clock_r,min,max,&ratio,K,tree->mcmc->move_type[move_num]);
+  
+  if(new_clock_r > min && new_clock_r < max)
+    {      
+      tree->rates->clock_r = new_clock_r;
+      
+      new_lnL_data = Lk(NULL,tree);
+      new_lnL_rate = RATES_Lk_Rates(tree);
+      
+      ratio += (new_lnL_data - cur_lnL_data);
+      ratio += (new_lnL_rate - cur_lnL_rate);
+            
+      ratio = exp(ratio);
+      alpha = MIN(1.,ratio);
+      
+      u = Uni();
+      
+      if(u > alpha) /* Reject */
+	{
+          /* PhyML_Printf("\n. reject"); */
+	  tree->rates->clock_r      = cur_clock_r;
+	  tree->c_lnL               = cur_lnL_data;
+	  tree->rates->c_lnL_rates  = cur_lnL_rate;
+          RATES_Update_Cur_Bl(tree);
+        }
+      else
+	{
+          /* PhyML_Printf("\n. accept"); */
+          tree->mcmc->acc_move[move_num]++;
+	}
     }
-  while(tree);
+  tree->mcmc->run_move[move_num]++;
 }
 
 //////////////////////////////////////////////////////////////
@@ -779,8 +827,8 @@ void MCMC_GEO_Loc(t_tree *tree)
       probs = (phydbl *)mCalloc(tree->geo->ldscape_sz,sizeof(phydbl));
 
       sum = 0.0;
-      For(i,tree->geo->ldscape_sz) sum += tree->geo->idx_loc_beneath[tree->n_root->num * tree->geo->ldscape_sz + i];
-      For(i,tree->geo->ldscape_sz) probs[i] = tree->geo->idx_loc_beneath[tree->n_root->num * tree->geo->ldscape_sz + i]/sum;
+      for(i=0;i<tree->geo->ldscape_sz;i++) sum += tree->geo->idx_loc_beneath[tree->n_root->num * tree->geo->ldscape_sz + i];
+      for(i=0;i<tree->geo->ldscape_sz;i++) probs[i] = tree->geo->idx_loc_beneath[tree->n_root->num * tree->geo->ldscape_sz + i]/sum;
       
       tree->geo->idx_loc[tree->n_root->num] = Sample_i_With_Proba_pi(probs,tree->geo->ldscape_sz);      
 
@@ -796,7 +844,7 @@ void MCMC_GEO_Loc(t_tree *tree)
   new_lnL = GEO_Lk(tree->geo,tree);
 
   ratio = (new_lnL - cur_lnL);        
-  ratio = EXP(ratio);
+  ratio = exp(ratio);
   alpha = MIN(1.,ratio);      
   u = Uni();
 
@@ -828,17 +876,17 @@ void MCMC_Sample_Joint_Rates_Prior(t_tree *tree)
   r      = tree->rates->br_r;
   t      = tree->rates->nd_t;
 
-  For(i,dim) tree->rates->mean_r[i] = 1.0;
+  for(i=0;i<dim;i++) tree->rates->mean_r[i] = 1.0;
 
   RATES_Fill_Lca_Table(tree);
   RATES_Covariance_Mu(tree);
 
   T = .0;
-  For(i,dim) T += (t[tree->a_nodes[i]->num] - t[tree->a_nodes[i]->anc->num]);
-  For(i,dim) lambda[i] = (t[tree->a_nodes[i]->num] - t[tree->a_nodes[i]->anc->num])/T;
-  For(i,dim) r[i] = 1.0;
-  For(i,dim) min_r[i] = tree->rates->min_rate;
-  For(i,dim) max_r[i] = tree->rates->max_rate;
+  for(i=0;i<dim;i++) T += (t[tree->a_nodes[i]->num] - t[tree->a_nodes[i]->anc->num]);
+  for(i=0;i<dim;i++) lambda[i] = (t[tree->a_nodes[i]->num] - t[tree->a_nodes[i]->anc->num])/T;
+  for(i=0;i<dim;i++) r[i] = 1.0;
+  for(i=0;i<dim;i++) min_r[i] = tree->rates->min_rate;
+  for(i=0;i<dim;i++) max_r[i] = tree->rates->max_rate;
 
   k = 1.; /* We want \sum_i lambda[i] r[i] = 1 */
 
@@ -854,6 +902,19 @@ void MCMC_Sample_Joint_Rates_Prior(t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
+void MCMC_Rates_All(t_tree *tree)
+{
+  Set_Both_Sides(YES,tree);
+  Lk(NULL,tree);
+  Set_Both_Sides(NO,tree);
+  MCMC_One_Rate(tree->n_root,tree->n_root->v[1],YES,tree);
+  Update_Partial_Lk(tree,tree->e_root,tree->n_root->v[1]);
+  MCMC_One_Rate(tree->n_root,tree->n_root->v[2],YES,tree);
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
 void MCMC_One_Rate(t_node *a, t_node *d, int traversal, t_tree *tree)
 {
   t_edge *b;
@@ -863,160 +924,107 @@ void MCMC_One_Rate(t_node *a, t_node *d, int traversal, t_tree *tree)
   phydbl ratio, alpha;
   phydbl new_mu, cur_mu;
   phydbl r_min, r_max;
-  t_edge *b1,*b2,*b3;
-  t_node *v2,*v3;
-  int move_num;
+  int move_num,err;
   phydbl K;
 
   if(tree->rates->model == STRICTCLOCK) return;
 
   b = NULL;
   if(a == tree->n_root) b = tree->e_root;
-  else
-    For(i,3) if(d->v[i] == a) { b = d->b[i]; break; }
+  else for(i=0;i<3;i++) if(d->v[i] == a) { b = d->b[i]; break; }
    
   cur_mu       = tree->rates->br_r[d->num];
-  cur_lnL_data = tree->c_lnL;
-  new_lnL_data = tree->c_lnL;
-  cur_lnL_rate = tree->rates->c_lnL_rates;
-  new_lnL_rate = tree->rates->c_lnL_rates;
   r_min        = tree->rates->min_rate;
   r_max        = tree->rates->max_rate;
   ratio        = 0.0;
-  move_num     = d->num+tree->mcmc->num_move_br_r;
+  move_num     = tree->mcmc->num_move_br_r;
   K            = tree->mcmc->tune_move[move_num];
+  cur_lnL_data = tree->c_lnL;
+  new_lnL_data = UNLIKELY;
+  cur_lnL_rate = tree->rates->c_lnL_rates;
+  new_lnL_rate = UNLIKELY;
+  
+  /* MCMC_Make_Move(&cur_mu,&new_mu,r_min,r_max,&ratio,K,tree->mcmc->move_type[move_num]); */
 
-  Record_Br_Len(tree);
+  /* new_mu = Rnorm_Trunc(1.0,3.*tree->rates->nu,r_min,r_max,&err); */
+  /* ratio -= Log_Dnorm_Trunc(new_mu,1.0,3.*tree->rates->nu,r_min,r_max,&err); */
+  /* ratio += Log_Dnorm_Trunc(cur_mu,1.0,3.*tree->rates->nu,r_min,r_max,&err); */
   
-  u = Uni();
+  new_mu = Rnorm_Trunc(cur_mu,K*tree->rates->nu,r_min,r_max,&err);
+  ratio -= Log_Dnorm_Trunc(new_mu,cur_mu,K*tree->rates->nu,r_min,r_max,&err);
+  ratio += Log_Dnorm_Trunc(cur_mu,new_mu,K*tree->rates->nu,r_min,r_max,&err);
   
-  MCMC_Make_Move(&cur_mu,&new_mu,r_min,r_max,&ratio,K,tree->mcmc->move_type[tree->mcmc->num_move_br_r+d->num]);
-
-  /* phydbl dt,sd,mean; */
-  /* int err; */
-  /* dt     = tree->rates->nd_t[d->num] - tree->rates->nd_t[a->num]; */
-  /* sd     = SQRT(tree->rates->nu * dt); */
-  /* mean   = tree->rates->br_r[a->num]; */
-  /* new_mu = Rnorm_Trunc(mean,sd,r_min,r_max,&err); */
-  /* ratio  = Log_Dnorm_Trunc(cur_mu,mean,sd,r_min,r_max,&err) - Log_Dnorm_Trunc(new_mu,mean,sd,r_min,r_max,&err); */
-
   if(new_mu > r_min && new_mu < r_max)
     {      
-      tree->rates->br_r[d->num] = new_mu;
-            
-      v2 = v3 = NULL;
-      For(i,3)
-	if((d->v[i] != a) && (d->b[i] != tree->e_root))
-	  {
-	    if(!v2) { v2 = d->v[i]; }
-	    else    { v3 = d->v[i]; }
-	  }
-      
-      
-      b1 = NULL;
-      if(a == tree->n_root) b1 = tree->e_root;
-      else For(i,3) if(d->v[i] == a) { b1 = d->b[i]; break; }
-      
-      b2 = b3 = NULL;
-      if(!d->tax)
-	{
-	  For(i,3)
-	    if((d->v[i] != a) && (d->b[i] != tree->e_root))
-	      {
-		if(!b2) { b2 = d->b[i]; }
-		else    { b3 = d->b[i]; }
-	      }
-	}
-      
+      tree->rates->br_r[d->num] = new_mu;      
       tree->rates->br_do_updt[d->num] = YES;
-      if(!d->tax)
-      	{
-      	  tree->rates->br_do_updt[v2->num] = YES;
-      	  tree->rates->br_do_updt[v3->num] = YES;
-      	}
-      
-      RATES_Update_Cur_Bl(tree);
-      
-      /* printf("\n. r0=%f r1=%f cr=%f mean=%f var=%f nu=%f dt=%f", */
-      /* 	 r0,r1,tree->rates->clock_r,b1->gamma_prior_mean,b1->gamma_prior_var,nu,t1-t0); */
-            
-      if(tree->mcmc->use_data)
-	{
-	  if(tree->io->lk_approx == EXACT)
-	    {
-	      Update_PMat_At_Given_Edge(b1,tree);
-	      if(!d->tax)
-		{
-		  Update_PMat_At_Given_Edge(b2,tree);
-		  Update_PMat_At_Given_Edge(b3,tree);
-		}
-	      Update_P_Lk(tree,b1,d);
-	    }
-	  new_lnL_data = Lk(b1,tree);
-	  
-	  /* tree->both_sides = NO; */
-	  /* new_lnL_data = Lk(tree); */
-	}
-      
+
+      new_lnL_data = Lk(b,tree);
       new_lnL_rate = RATES_Lk_Rates(tree);
       
-      /* Likelihood ratio */
-      if(tree->mcmc->use_data) ratio += (new_lnL_data - cur_lnL_data);
-
-      /* Prior ratio */
+      ratio += (new_lnL_data - cur_lnL_data);
       ratio += (new_lnL_rate - cur_lnL_rate);
             
-      ratio = EXP(ratio);
+      ratio = exp(ratio);
       alpha = MIN(1.,ratio);
       
       u = Uni();
       
+      /* PhyML_Printf("\n== %f->%f %f->%f %f->%f ratio:%f", */
+      /*              cur_mu,new_mu, */
+      /*              cur_lnL_data,new_lnL_data, */
+      /*              cur_lnL_rate,new_lnL_rate, */
+      /*              ratio); */
+
       if(u > alpha) /* Reject */
 	{
 	  tree->rates->br_r[d->num] = cur_mu;	  
 	  tree->c_lnL               = cur_lnL_data;
 	  tree->rates->c_lnL_rates  = cur_lnL_rate;
-	  
-	  Restore_Br_Len(tree);
-	  
-	  if(tree->mcmc->use_data && tree->io->lk_approx == EXACT)
-	    {
-	      Update_PMat_At_Given_Edge(b1,tree);
-	      if(!d->tax)
-		{
-		  Update_PMat_At_Given_Edge(b2,tree);
-		  Update_PMat_At_Given_Edge(b3,tree);
-		}
-	      Update_P_Lk(tree,b1,d);
-	    }
-	  
-	  /* tree->both_sides = YES; */
-	  /* new_lnL_data = Lk(tree); */
-	  /* tree->both_sides = NO; */
-	  
-	}
+
+          RATES_Update_Cur_Bl(tree);
+	  Update_PMat_At_Given_Edge(b,tree);
+          
+          /* !!!!!!!!!!!!!! */
+          /* /\* printf("\n. Rej %d",d->num); *\/ */
+          /* new_lnL_data = Lk(b,tree); /\* Not necessary. Remove once tested *\/ */
+          /* if(Are_Equal(new_lnL_data,cur_lnL_data,1.E-3) == NO) */
+          /*   { */
+          /*     PhyML_Printf("\n== a: %d d: %d ",a->num,d->num); */
+          /*     PhyML_Printf("\n== new_alnL: %f cur_alnL: %f",new_lnL_data,cur_lnL_data); */
+          /*     Generic_Exit(__FILE__,__LINE__,__FUNCTION__); */
+          /*   } */
+        }
       else
 	{
-	  tree->mcmc->acc_move[tree->mcmc->num_move_br_r+d->num]++;
+          tree->mcmc->acc_move[move_num]++;
+          /* /\* !!!!!!!!!!!!!! *\/ */
+          /* /\* printf("\n. Acc %d",d->num); *\/ */
+          /* cur_lnL_data = Lk(b,tree); /\* Not necessary. Remove once tested *\/ */
+          /* if(Are_Equal(new_lnL_data,cur_lnL_data,1.E-3) == NO) */
+          /*   { */
+          /*     PhyML_Printf("\n== a: %d d: %d",a->num,d->num); */
+          /*     PhyML_Printf("\n== new_alnL: %f cur_alnL: %f",new_lnL_data,cur_lnL_data); */
+          /*     Generic_Exit(__FILE__,__LINE__,__FUNCTION__); */
+          /*   } */
 	}
     }
-  tree->mcmc->run_move[tree->mcmc->num_move_br_r+d->num]++;
+
+  tree->mcmc->run_move[move_num]++;
   
   if(traversal == YES)
     {
       if(d->tax == YES) return;
       else
 	{
-	  For(i,3)
+	  for(i=0;i<3;i++)
 	    if(d->v[i] != a && d->b[i] != tree->e_root)
-	      {
-		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_Rate(d,d->v[i],YES,tree);
-	      }
-	}
-      if(tree->io->lk_approx == EXACT && tree->mcmc->use_data) Update_P_Lk(tree,b,d);
-      /* if(tree->io->lk_approx == EXACT && tree->mcmc->use_data) {tree->both_sides = YES; Lk(tree); } */
+              {
+                Update_Partial_Lk(tree,d->b[i],d);
+                MCMC_One_Rate(d,d->v[i],YES,tree);
+              }
+          Update_Partial_Lk(tree,b,d);
+        }
     }
 }
 
@@ -1031,17 +1039,17 @@ void MCMC_One_Node_Rate(t_node *a, t_node *d, int traversal, t_tree *tree)
   b = NULL;
   if(a == tree->n_root) b = tree->e_root;
   else
-    For(i,3) if(d->v[i] == a) { b = d->b[i]; break; }
+    for(i=0;i<3;i++) if(d->v[i] == a) { b = d->b[i]; break; }
 
-  /* Only the LOG_RANDWALK move seems to work here. Change with caution then. */
+  /* Only the log_RANDWALK move seems to work here. Change with caution then. */
   tree->rates->br_do_updt[d->num] = YES;
   MCMC_Single_Param_Generic(&(tree->rates->nd_r[d->num]),
 			    tree->rates->min_rate,
 			    tree->rates->max_rate,
-			    tree->mcmc->num_move_nd_r+d->num,
+			    tree->mcmc->num_move_nd_r,
 			    &(tree->rates->c_lnL_rates),NULL,
 			    Wrap_Lk_Rates,NULL,
-			    tree->mcmc->move_type[tree->mcmc->num_move_nd_r+d->num],
+			    tree->mcmc->move_type[tree->mcmc->num_move_nd_r],
 			    NO,NULL,tree,NULL);
 
 
@@ -1052,7 +1060,7 @@ void MCMC_One_Node_Rate(t_node *a, t_node *d, int traversal, t_tree *tree)
       if(d->tax == YES) return;
       else
 	{
-	  For(i,3)
+	  for(i=0;i<3;i++)
 	    if(d->v[i] != a && d->b[i] != tree->e_root)
 	      {
 		MCMC_One_Node_Rate(d,d->v[i],YES,tree);
@@ -1064,230 +1072,490 @@ 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_Times_And_Rates_All(t_tree *tree)
+{
+  MCMC_Times_And_Rates_Root(tree);
+  MCMC_Times_And_Rates_Recur(tree->n_root,tree->n_root->v[1],YES,tree);
+  MCMC_Times_And_Rates_Recur(tree->n_root,tree->n_root->v[2],YES,tree);
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void MCMC_Times_And_Rates_Root(t_tree *tree)
 {
   phydbl u;
   phydbl t_min,t_max;
+  phydbl r_min,r_max;
   phydbl t1_cur, t1_new;
-  phydbl cur_lnL_data, new_lnL_data;
   phydbl cur_lnL_rate, new_lnL_rate;
   phydbl cur_lnL_time, new_lnL_time;
   phydbl ratio,alpha;
-  t_edge *b1,*b2,*b3;
-  int    i;
   phydbl t0,t2,t3;
   t_node *v2,*v3;
   phydbl K;
   int move_num;
-  
-  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; */
-
-  Record_Br_Len(tree);
-  RATES_Record_Rates(tree);
-  RATES_Record_Times(tree);
-  
-  move_num       = d->num-tree->n_otu+tree->mcmc->num_move_nd_t;
-  K              = tree->mcmc->tune_move[move_num];
-  cur_lnL_data   = tree->c_lnL;
-  cur_lnL_rate   = tree->rates->c_lnL_rates;
-  t1_cur         = tree->rates->nd_t[d->num];
-  new_lnL_data   = cur_lnL_data;
-  new_lnL_rate   = cur_lnL_rate;
-  ratio          = 0.0;
-  cur_lnL_time   = tree->rates->c_lnL_times;
-  new_lnL_time   = cur_lnL_time;
+  t_node *root;
+  phydbl r2_cur,r3_cur;
+  phydbl r2_new,r3_new;
 
-  v2 = v3 = NULL;
-  For(i,3)
-    if((d->v[i] != a) && (d->b[i] != tree->e_root))
-      {
-	if(!v2) { v2 = d->v[i]; }
-	else    { v3 = d->v[i]; }
-      }
+  /* printf("\n IN ROOT: %f",tree->rates->c_lnL_times); */
 
+  root = tree->n_root;
 
-  b1 = NULL;
-  if(a == tree->n_root) b1 = tree->e_root;
-  else For(i,3) if(d->v[i] == a) { b1 = d->b[i]; break; }
+  if(FABS(tree->rates->t_prior_min[root->num] - tree->rates->t_prior_max[root->num]) < 1.E-10) return;
+  
+  move_num     = tree->mcmc->num_move_times_and_rates_root;
+  K            = tree->mcmc->tune_move[move_num];
+  t1_cur       = tree->rates->nd_t[root->num];
+  ratio        = 0.0;
+  cur_lnL_rate = tree->rates->c_lnL_rates;
+  new_lnL_rate = UNLIKELY;
+  cur_lnL_time = tree->rates->c_lnL_times;
+  new_lnL_time = UNLIKELY;
+  r_min        = tree->rates->min_rate;
+  r_max        = tree->rates->max_rate;
 
-  b2 = b3 = NULL;
-  For(i,3)
-    if((d->v[i] != a) && (d->b[i] != tree->e_root))
-      {
-	if(!b2) { b2 = d->b[i]; }
-	else    { b3 = d->b[i]; }
-      }
- 
-  t0 = tree->rates->nd_t[a->num];
+  v2 = root->v[2];
+  v3 = root->v[1];
+  
+  t0 = tree->rates->t_prior_min[root->num];
   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_min = -INFINITY;
   t_max = MIN(t2,t3);
 
   t_min += tree->rates->min_dt;
   t_max -= tree->rates->min_dt;
 
+  u = Uni();
+  t1_new = t_max - (t_max - t1_cur)*exp(K*(u-.5));
+  ratio += log((t1_new - t_max) / (t1_cur - t_max));
+
+  r2_cur = tree->rates->br_r[v2->num];
+  r3_cur = tree->rates->br_r[v3->num];
+
+  r2_new = r2_cur * (t2 - t1_cur) / (t2 - t1_new);
+  r3_new = r3_cur * (t3 - t1_cur) / (t3 - t1_new);
+
+
   if(t_min > t_max) 
     {
+      PhyML_Printf("\n== glnL:%f",TIMES_Lk_Times(NO,tree));
+      PhyML_Printf("\n== t:%f",tree->rates->nd_t[tree->n_root->num]);
+      PhyML_Printf("\n== t0 = %f t2 = %f t3 = %f",t0,t2,t3);
       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"); */
+      PhyML_Printf("\n== prior_min = %f prior_max = %f",tree->rates->t_prior_min[root->num],tree->rates->t_prior_max[root->num]);
+      Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
     }
- 
-  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) 
-    {
-      tree->rates->nd_t[d->num] = t1_new;
 
-      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
-        {
-          /* Update branch lengths */
-          tree->rates->br_do_updt[d->num]  = YES;
-          tree->rates->br_do_updt[v2->num] = YES;
-          tree->rates->br_do_updt[v3->num] = YES;
-          RATES_Update_Cur_Bl(tree);
-          
-          new_lnL_rate = RATES_Lk_Rates(tree);
-          ratio += (new_lnL_rate - cur_lnL_rate);
+  if(t1_new > t_min &&
+     t1_new < t_max &&
+     r2_new > r_min &&
+     r2_new < r_max &&
+     r3_new > r_min &&
+     r3_new < r_max) 
+    {
+      RATES_Record_Times(tree);
 
-          if(tree->mcmc->use_data)
-            {
-              if(tree->io->lk_approx == EXACT)
-                {
-                  Update_PMat_At_Given_Edge(b1,tree);
-                  Update_PMat_At_Given_Edge(b2,tree);
-                  Update_PMat_At_Given_Edge(b3,tree);
-                  Update_P_Lk(tree,b1,d);
-                }
-              new_lnL_data = Lk(b1,tree);
-              
-              /* /\* !!!!!!!!!!!!!!!!!!!!1 *\/ */
-              /* if(FABS(Lk(tree) - new_lnL_data) > 1.E-5) */
-              /*   { */
-              /*     PhyML_Printf("\n. b1->l->v=%f b2->l->v=%f b3->l->v=%f",b1->l->v,b2->l->v,b3->l->v); */
-              /*     PhyML_Printf("\n. a->num=%d d->num=%d root=%d (%d %d)",a->num,d->num,a==tree->n_root,tree->n_root->v[2]->num,tree->n_root->v[1]->num); */
-              /*     PhyML_Printf("\n. t_min=%f t_max=%f",t_min,t_max); */
-              /*     PhyML_Printf("\n. t1_new=%f t1_cur=%f",t1_new,t1_cur); */
-              /*     PhyML_Printf("\n. %f %f",cur_lnL_data,tree->c_lnL); */
-              /*     PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); */
-              /*     Warn_And_Exit(""); */
-              /*   } */
-            }
-          
-          if(tree->mcmc->use_data) ratio += (new_lnL_data - cur_lnL_data);
-        }
+      tree->rates->nd_t[root->num] = t1_new;
+      tree->rates->br_r[v2->num]   = r2_new;
+      tree->rates->br_r[v3->num]   = r3_new;
       
-      /* if(d->num == 7) */
-      /*   { */
-      /*     printf("\n. nd_t: %f %f new_lnL_rate: %f cur_lnL_rate: %f new_lnL_time: %f cur_lnL_time: %f ratio: %f", */
-      /*            t1_cur, */
-      /*            tree->rates->nd_t[d->num], */
-      /*            new_lnL_rate, */
-      /*            cur_lnL_rate, */
-      /*            new_lnL_time, */
-      /*            cur_lnL_time, */
-      /*            ratio); */
-      /*   } */
+      new_lnL_time = TIMES_Lk_Times(NO,tree); 
+      new_lnL_rate = RATES_Lk_Rates(tree);
+      
+      ratio += (new_lnL_rate - cur_lnL_rate);
+      ratio += (new_lnL_time - cur_lnL_time);
 
-          
-      ratio = EXP(ratio);
+      ratio = exp(ratio);
       alpha = MIN(1.,ratio);
       u = Uni();
-	           
+         
+      /* printf("\n. alnL:%f->%f tlnL: %f->%f rlnL: %f->%f ratio: %f", */
+      /*        cur_lnL_data,new_lnL_data, */
+      /*        cur_lnL_time,new_lnL_time, */
+      /*        cur_lnL_rate,new_lnL_rate, */
+      /*        ratio); */
+
       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->nd_t[root->num] = t1_cur;
+          tree->rates->br_r[v2->num]   = r2_cur;
+          tree->rates->br_r[v3->num]   = r3_cur;
+
+          tree->rates->c_lnL_rates = cur_lnL_rate;
 	  tree->rates->c_lnL_times = cur_lnL_time;
           
-          if(isinf(new_lnL_time) == NO)
-            {
-              Restore_Br_Len(tree);
-              RATES_Reset_Rates(tree);
-              RATES_Reset_Times(tree);
-              
-              if(tree->io->lk_approx == EXACT && tree->mcmc->use_data) 
-                {
-                  Update_PMat_At_Given_Edge(b1,tree);
-                  Update_PMat_At_Given_Edge(b2,tree);
-                  Update_PMat_At_Given_Edge(b3,tree);
-                  Update_P_Lk(tree,b1,d);
-                }
-            }
 	}
       else
 	{
-	  /* printf("\n. A new_lnL_data = %f cur_lnL_data = %f t_new=%f t_cur=%f tmin=%f tmax=%f", */
-	  /* 	 new_lnL_data,cur_lnL_data,t1_new,t1_cur,t_min,t_max); */
-	  tree->mcmc->acc_move[move_num]++;
-	}
-      if(t1_new < t0)
-	{
-	  t1_new = t0+1.E-4;
-	  PhyML_Printf("\n");
-	  PhyML_Printf("\n== a is root -> %s",(a == tree->n_root)?("YES"):("NO"));
-	  PhyML_Printf("\n== t0 = %f t1_new = %f",t0,t1_new);
-	  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"); */
-	}
-      if(t1_new > MIN(t2,t3))
-	{
-	  PhyML_Printf("\n");
-	  PhyML_Printf("\n== a is root -> %s",(a == tree->n_root)?("YES"):("NO"));
-	  PhyML_Printf("\n== t0 = %f t1_new = %f t1 = %f t2 = %f t3 = %f MIN(t2,t3)=%f",t0,t1_new,t1_cur,t2,t3,MIN(t2,t3));
-	  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"); */
-	}
-      
-      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"); */
+	  tree->mcmc->acc_move[move_num]+=1;
 	}
-    }
-  
-  tree->mcmc->run_move[move_num]++;
 
-  if(traversal == YES)
-    {
-      if(d->tax == YES) return;
-      else
-	For(i,3)
-	  if(d->v[i] != a && d->b[i] != tree->e_root)
-	    {
-	      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);
-	    }
-      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); } */
-    }	    
+      // Ignore boundaries when updating tuning parameter 
+      tree->mcmc->run_move[move_num]+=1;
+
+    }   
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-void MCMC_Jump_Calibration(t_tree *tree)
+void MCMC_Times_And_Rates_Recur(t_node *a, t_node *d, int traversal, t_tree *tree)
+{
+  phydbl u;
+  phydbl t_min,t_max;
+  phydbl r_min,r_max;
+  phydbl t1_cur, t1_new;
+  phydbl cur_lnL_rate, new_lnL_rate;
+  phydbl cur_lnL_time, new_lnL_time;
+  phydbl ratio,alpha;
+  int    i;
+  phydbl t0,t2,t3;
+  t_node *v2,*v3;
+  int move_num;
+  phydbl r1_cur,r2_cur,r3_cur;
+  phydbl r1_new,r2_new,r3_new;
+  
+  if(d->tax) return; /* Won't change time at tip */
+  
+  move_num     = tree->mcmc->num_move_times_and_rates;
+  t1_cur       = tree->rates->nd_t[d->num];
+  ratio        = 0.0;
+  cur_lnL_rate = tree->rates->c_lnL_rates;
+  new_lnL_rate = UNLIKELY;
+  cur_lnL_time = tree->rates->c_lnL_times;
+  new_lnL_time = UNLIKELY;
+  r_min        = tree->rates->min_rate;
+  r_max        = tree->rates->max_rate;
+
+  
+  v2 = v3 = NULL;
+  for(i=0;i<3;i++)
+    if((d->v[i] != a) && (d->b[i] != tree->e_root))
+      {
+	if(!v2) { v2 = d->v[i]; }
+	else    { v3 = d->v[i]; }
+      }
+
+  r1_cur = tree->rates->br_r[d->num];
+  r2_cur = tree->rates->br_r[v2->num];
+  r3_cur = tree->rates->br_r[v3->num];
+ 
+  t0 = tree->rates->nd_t[a->num];
+  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(tree->rates->t_prior_max[d->num],MIN(t2,t3));
+
+  t_min += tree->rates->min_dt;
+  t_max -= tree->rates->min_dt;
+
+  t1_new = Uni()*(t_max - t_min) + t_min;
+
+  r1_new = r1_cur * (t1_cur - t0) / (t1_new - t0);
+  r2_new = r2_cur * (t2 - t1_cur) / (t2 - t1_new);
+  r3_new = r3_cur * (t3 - t1_cur) / (t3 - t1_new);
+
+  ratio +=
+    log((t1_cur - t0) / (t1_new - t0) *
+        (t2 - t1_cur) / (t2 - t1_new) *
+        (t3 - t1_cur) / (t3 - t1_new));
+  
+  if(t1_new > t_min && t1_new < t_max &&
+     r1_new > r_min && r1_new < r_max &&
+     r2_new > r_min && r2_new < r_max &&
+     r3_new > r_min && r3_new < r_max) 
+    {
+      RATES_Record_Times(tree);
+
+      tree->rates->nd_t[d->num] = t1_new;
+
+      tree->rates->br_r[d->num]  = r1_new;
+      tree->rates->br_r[v2->num] = r2_new;
+      tree->rates->br_r[v3->num] = r3_new;
+
+      new_lnL_time = TIMES_Lk_Times(NO,tree);
+      new_lnL_rate = RATES_Lk_Rates(tree);
+
+      ratio += (new_lnL_time - cur_lnL_time);
+      ratio += (new_lnL_rate - cur_lnL_rate);
+
+      
+      ratio = exp(ratio);
+      alpha = MIN(1.,ratio);
+      u = Uni();
+
+      if(u > alpha) /* Reject */
+	{
+          /* printf("\n. rej"); */
+          RATES_Reset_Times(tree);
+              
+          tree->rates->br_r[d->num]  = r1_cur;
+          tree->rates->br_r[v2->num] = r2_cur;
+          tree->rates->br_r[v3->num] = r3_cur;
+
+          tree->rates->c_lnL_rates  = cur_lnL_rate;
+          tree->rates->c_lnL_times  = cur_lnL_time;          
+	}
+      else
+	{
+          /* printf("\n. acc"); */
+	  tree->mcmc->acc_move[move_num]++;
+	}
+
+    }
+  
+  tree->mcmc->run_move[move_num]++;
+
+  if(d->tax == YES) return;
+  else
+    {
+      for(i=0;i<3;i++)
+        if(d->v[i] != a && d->b[i] != tree->e_root)
+          {
+            MCMC_Times_And_Rates_Recur(d,d->v[i],YES,tree);
+          }
+    }	    
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void MCMC_Times_All(t_tree *tree)
+{
+  // Down partials may not be up to date.
+  Set_Both_Sides(YES,tree);
+  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);
+  Update_Partial_Lk(tree,tree->e_root,tree->n_root->v[1]);
+  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;
+  phydbl t1_cur, t1_new;
+  phydbl cur_lnL_data, new_lnL_data;
+  phydbl cur_lnL_rate, new_lnL_rate;
+  phydbl cur_lnL_time, new_lnL_time;
+  phydbl ratio,alpha;
+  t_edge *b1,*b2,*b3;
+  int    i;
+  phydbl t0,t2,t3;
+  t_node *v2,*v3;
+  int move_num;
+  
+  if(d->tax) return; /* Won't change time at tip */
+  
+  move_num     = tree->mcmc->num_move_times;
+  t1_cur       = tree->rates->nd_t[d->num];
+  ratio        = 0.0;
+  cur_lnL_data = tree->c_lnL;
+  new_lnL_data = UNLIKELY;
+  cur_lnL_rate = tree->rates->c_lnL_rates;
+  new_lnL_rate = UNLIKELY;
+  cur_lnL_time = tree->rates->c_lnL_times;
+  new_lnL_time = UNLIKELY;
+
+  
+  v2 = v3 = NULL;
+  for(i=0;i<3;i++)
+    if((d->v[i] != a) && (d->b[i] != tree->e_root))
+      {
+	if(!v2) { v2 = d->v[i]; }
+	else    { v3 = d->v[i]; }
+      }
+
+
+  b1 = NULL;
+  if(a == tree->n_root) b1 = tree->e_root;
+  else for(i=0;i<3;i++) if(d->v[i] == a) { b1 = d->b[i]; break; }
+
+  b2 = b3 = NULL;
+  for(i=0;i<3;i++)
+    if((d->v[i] != a) && (d->b[i] != tree->e_root))
+      {
+	if(!b2) { b2 = d->b[i]; }
+	else    { b3 = d->b[i]; }
+      }
+ 
+  t0 = tree->rates->nd_t[a->num];
+  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(tree->rates->t_prior_max[d->num],MIN(t2,t3));
+
+  t_min += tree->rates->min_dt;
+  t_max -= tree->rates->min_dt;
+
+  /* K = tree->mcmc->tune_move[tree->mcmc->num_move_times] * (t_max - t_min); */  
+  /* MCMC_Make_Move(&t1_cur,&t1_new,t_min,t_max,&ratio,K,tree->mcmc->move_type[move_num]); */
+  t1_new = Uni()*(t_max - t_min) + t_min;
+
+  if(t1_new > t_min && t1_new < t_max) 
+    {
+      RATES_Record_Times(tree);
+
+      tree->rates->nd_t[d->num] = t1_new;
+
+      new_lnL_time = TIMES_Lk_Times(NO,tree);
+      ratio += (new_lnL_time - cur_lnL_time);
+
+      if(new_lnL_time > UNLIKELY)
+        {
+          RATES_Update_Cur_Bl(tree);
+          
+          new_lnL_rate = RATES_Lk_Rates(tree);
+          ratio += (new_lnL_rate - cur_lnL_rate);
+          
+          if(tree->eval_alnL == YES && tree->io->lk_approx == EXACT)
+            {
+              Update_PMat_At_Given_Edge(b1,tree);
+              Update_PMat_At_Given_Edge(b2,tree);
+              Update_PMat_At_Given_Edge(b3,tree);
+              Update_Partial_Lk(tree,b1,d);
+            }
+          new_lnL_data = Lk(b1,tree);
+          
+          ratio += (new_lnL_data - cur_lnL_data);
+        }
+      
+      /* printf("\n. One_Time cur_t: %f new_t: %f ratio: %f alnL:%f->%f tlnL: %f->%f rlnL: %f->%f", */
+      /*        t1_cur,t1_new, */
+      /*        ratio, */
+      /*        cur_lnL_data,new_lnL_data, */
+      /*        cur_lnL_time,new_lnL_time, */
+      /*        cur_lnL_rate,new_lnL_rate); */
+
+      ratio = exp(ratio);
+      alpha = MIN(1.,ratio);
+      u = Uni();
+
+      if(u > alpha) /* Reject */
+	{
+          /* printf("\n. rej"); */
+          RATES_Reset_Times(tree);
+          RATES_Update_Cur_Bl(tree);
+              
+          if(tree->eval_alnL == YES && tree->io->lk_approx == EXACT) 
+            {
+              Update_PMat_At_Given_Edge(b1,tree);
+              Update_PMat_At_Given_Edge(b2,tree);
+              Update_PMat_At_Given_Edge(b3,tree);
+              Update_Partial_Lk(tree,b1,d);
+            }
+
+          if(isinf(FABS(new_lnL_time)) == YES || isnan(new_lnL_time) == YES)
+            {
+              Print_Node(tree->n_root,tree->n_root->v[1],tree);
+              Print_Node(tree->n_root,tree->n_root->v[2],tree);              
+              assert(FALSE);
+            }
+
+	  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\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__);
+            }
+          
+          /* !!!!!!!!!!!!!! */
+          /* new_lnL_data = Lk(NULL,tree); /\* Not necessary. Remove once tested *\/ */
+          /* if(Are_Equal(new_lnL_data,cur_lnL_data,1.E-3) == NO) */
+          /*   { */
+          /*     PhyML_Printf("\n== a: %d d: %d v2: %d v3: %d",a->num,d->num,v2->num,v3->num); */
+          /*     PhyML_Printf("\n== t1_cur: %f t1_new: %f",t1_cur,t1_new); */
+          /*     PhyML_Printf("\n== new_alnL: %f cur_alnL: %f",new_lnL_data,cur_lnL_data); */
+          /*     Generic_Exit(__FILE__,__LINE__,__FUNCTION__); */
+          /*   } */
+	}
+      else
+	{
+          /* !!!!!!!!!!!!!! */
+          /* cur_lnL_data = Lk(NULL,tree); /\* Not necessary. Remove once tested *\/ */
+          /* if(Are_Equal(new_lnL_data,cur_lnL_data,1.E-3) == NO) */
+          /*   { */
+          /*     PhyML_Printf("\n== a: %d d: %d v2: %d v3: %d",a->num,d->num,v2->num,v3->num); */
+          /*     PhyML_Printf("\n== t1_cur: %f t1_new: %f",t1_cur,t1_new); */
+          /*     PhyML_Printf("\n== new_alnL: %f cur_alnL: %f",new_lnL_data,cur_lnL_data); */
+          /*     Generic_Exit(__FILE__,__LINE__,__FUNCTION__); */
+          /*   } */
+	  tree->mcmc->acc_move[move_num]++;
+	}
+
+      /* printf("\n. %f",new_lnL_data); fflush(NULL); */
+
+      if(t1_new < t0)
+	{
+	  t1_new = t0+1.E-4;
+	  PhyML_Printf("\n");
+	  PhyML_Printf("\n== a is root -> %s",(a == tree->n_root)?("YES"):("NO"));
+	  PhyML_Printf("\n== t0 = %f t1_new = %f",t0,t1_new);
+	  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"); */
+	}
+      if(t1_new > MIN(t2,t3))
+	{
+	  PhyML_Printf("\n");
+	  PhyML_Printf("\n== a is root -> %s",(a == tree->n_root)?("YES"):("NO"));
+	  PhyML_Printf("\n== t0 = %f t1_new = %f t1 = %f t2 = %f t3 = %f MIN(t2,t3)=%f",t0,t1_new,t1_cur,t2,t3,MIN(t2,t3));
+	  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"); */
+	}
+      
+      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__);
+	}
+    }
+  
+  tree->mcmc->run_move[move_num]++;
+
+  if(traversal == YES)
+    {
+      if(d->tax == YES) return;
+      else
+	{
+          for(i=0;i<3;i++)
+            if(d->v[i] != a && d->b[i] != tree->e_root)
+              {
+                Update_Partial_Lk(tree,d->b[i],d);
+                MCMC_Time_Recur(d,d->v[i],YES,tree);
+              }
+          Update_Partial_Lk(tree,b1,d);
+        }
+    }	    
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void MCMC_Jump_Calibration(t_tree *tree)
 {
 #ifdef INVITEE
   phydbl u;
@@ -1346,7 +1614,7 @@ void MCMC_Jump_Calibration(t_tree *tree)
       u = Uni();
       if(u < 0.5)
         {
-          For(i,tot_num_of_calib_comb) uniform_prob[i] = calib_prior_prob[i] > .0 ? 1. : 0.;
+          for(i=0;i<tot_num_of_calib_comb;i++) uniform_prob[i] = calib_prior_prob[i] > .0 ? 1. : 0.;
           new_calib_comb_num = Sample_i_With_Proba_pi(uniform_prob,tot_num_of_calib_comb);
         }
       else
@@ -1354,7 +1622,7 @@ void MCMC_Jump_Calibration(t_tree *tree)
           buff_calib_num = (int *)mCalloc(tot_num_of_calib_comb,sizeof(int));
           
           n_pos_probs = 0;
-          For(i,tot_num_of_calib_comb) 
+          for(i=0;i<tot_num_of_calib_comb;i++) 
             if(calib_prior_prob[i] > 1.E-10)
               {
                 buff_calib_num[n_pos_probs] = i;
@@ -1436,13 +1704,11 @@ void MCMC_Jump_Calibration(t_tree *tree)
               PhyML_Printf("\n== There is a problem with calibration information.\n");
               Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
             }
-          
-          For(i,2*tree->n_otu-2) tree->rates->br_do_updt[i] = YES;
           RATES_Update_Cur_Bl(tree);
-          if(tree->mcmc->use_data) new_lnL_data = Lk(NULL,tree);
+          new_lnL_data = Lk(NULL,tree);
           
           new_lnL_rate = RATES_Lk_Rates(tree);
-          new_lnL_time = TIMES_Lk_Times(tree);
+          new_lnL_time = TIMES_Lk_Times(NO,tree);
           
           /* printf("\n. JUMP cur_lnL_time: %f new_lnL_time: %f",cur_lnL_time,new_lnL_time); */
           /* for(i = tree -> n_otu; i < 2 * tree -> n_otu -1; i++) printf("\nJUMP1 Node number:[%d] Lower bound:[%f] Upper bound:[%f] Node time:[%f].", i, */
@@ -1451,15 +1717,15 @@ void MCMC_Jump_Calibration(t_tree *tree)
           /*                                                          tree -> rates -> nd_t[i]); */
 
           /* Likelihood ratio */
-          if(tree->mcmc->use_data) ratio += (new_lnL_data - cur_lnL_data);
+          ratio += (new_lnL_data - cur_lnL_data);
           
           /* Prior ratio */
           ratio += (new_lnL_rate - cur_lnL_rate);
           ratio += (new_lnL_time - cur_lnL_time);
-          ratio += (LOG(calib_prior_prob[new_calib_comb_num]) - LOG(calib_prior_prob[cur_calib_comb_num]));
+          ratio += (log(calib_prior_prob[new_calib_comb_num]) - log(calib_prior_prob[cur_calib_comb_num]));
           ratio += times_log_hastings_ratio;
           
-          ratio = EXP(ratio);
+          ratio = exp(ratio);
           alpha = MIN(1.,ratio);
           u = Uni();
           
@@ -1515,9 +1781,9 @@ void MCMC_Jump_Calibration(t_tree *tree)
 
 #endif
 }
-//////////////////////////////////////////////////////////////
 
 //////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
 
 void MCMC_Root_Time(t_tree *tree)
 {
@@ -1535,25 +1801,22 @@ 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;
-
-  Record_Br_Len(tree);
-  RATES_Record_Rates(tree);
-  RATES_Record_Times(tree);
   
-  move_num       = root->num-tree->n_otu+tree->mcmc->num_move_nd_t;
-  K              = tree->mcmc->tune_move[move_num];
-  cur_lnL_data   = tree->c_lnL;
-  cur_lnL_rate   = tree->rates->c_lnL_rates;
-  t1_cur         = tree->rates->nd_t[root->num];
-  new_lnL_data   = cur_lnL_data;
-  new_lnL_rate   = cur_lnL_rate;
-  ratio          = 0.0;
-  cur_lnL_time   = tree->rates->c_lnL_times;
-  new_lnL_time   = cur_lnL_time;
-
+  move_num     = tree->mcmc->num_move_root_time;
+  K            = tree->mcmc->tune_move[move_num];
+  t1_cur       = tree->rates->nd_t[root->num];
+  ratio        = 0.0;
+  cur_lnL_data = tree->c_lnL;
+  new_lnL_data = UNLIKELY;
+  cur_lnL_rate = tree->rates->c_lnL_rates;
+  new_lnL_rate = UNLIKELY;
+  cur_lnL_time = tree->rates->c_lnL_times;
+  new_lnL_time = UNLIKELY;
 
   v2 = root->v[2];
   v3 = root->v[1];
@@ -1563,10 +1826,8 @@ void MCMC_Root_Time(t_tree *tree)
   t0 = tree->rates->t_prior_min[root->num];
   t2 = tree->rates->nd_t[v2->num];
   t3 = tree->rates->nd_t[v3->num];
-  /* printf("\n %d t0= %f %d t2= %f %d t3= %f \n", root -> num, t0, v2 -> num, t2, v3 -> num, t3);  */
 
-  t_min = t0;
-  /* t_max = MIN(MIN(t2,t3),tree->rates->t_prior_max[root->num]); */
+  t_min = -INFINITY;
   t_max = MIN(t2,t3);
 
   t_min += tree->rates->min_dt;
@@ -1574,79 +1835,85 @@ void MCMC_Root_Time(t_tree *tree)
 
   if(t_min > t_max) 
     {
+      PhyML_Printf("\n== glnL:%f",TIMES_Lk_Times(NO,tree));
+      PhyML_Printf("\n== t:%f",tree->rates->nd_t[tree->n_root->num]);
       PhyML_Printf("\n== t0 = %f t2 = %f t3 = %f",t0,t2,t3);
       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[root->num],tree->rates->t_prior_max[root->num]);
       Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
     }
 
-  MCMC_Make_Move(&t1_cur,&t1_new,t_min,t_max,&ratio,K,tree->mcmc->move_type[move_num]);
- 
+  u = Uni();
+  t1_new = t_max - (t_max - t1_cur)*exp(K*(u-.5));
+  ratio += log((t1_new - t_max) / (t1_cur - t_max));
+  /* MCMC_Make_Move(&t1_cur,&t1_new,t_min,t_max,&ratio,K,tree->mcmc->move_type[move_num]); */
+  /* t1_new = Uni()*(t_max-t_min) + t_min; */
+  
+  /* PhyML_Printf("\n. K: %f t1: %f->%f acc.num: %d run: %d acc.rate: %f", */
+  /*              K,t1_cur,t1_new, */
+  /*              tree->mcmc->acc_move[move_num], */
+  /*              tree->mcmc->run_move[move_num], */
+  /*              tree->mcmc->run_move[move_num] > 0 ? (phydbl)tree->mcmc->acc_move[move_num]/tree->mcmc->run_move[move_num] : -1.); */
+
   if(t1_new > t_min && t1_new < t_max) 
     {
+      RATES_Record_Times(tree);
+
       tree->rates->nd_t[root->num] = t1_new;
 
-      /* Update branch lengths */
       RATES_Update_Cur_Bl(tree);
 
-      if(tree->mcmc->use_data) new_lnL_data = Lk(b1,tree);
-
-      new_lnL_rate = RATES_Lk_Rates(tree);
-      new_lnL_time = TIMES_Lk_Times(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);
+      new_lnL_time = TIMES_Lk_Times(NO,tree); 
 
-      ratio = EXP(ratio);
+      if(new_lnL_time > UNLIKELY)
+        {
+          /* !!!!!! What if model==GUINDON? */
+          new_lnL_data = Lk(b1,tree);
+          new_lnL_rate = RATES_Lk_Rates(tree);
+        }
+      
+      ratio += (new_lnL_data - cur_lnL_data);
+      ratio += (new_lnL_rate - cur_lnL_rate);
+      ratio += (new_lnL_time - cur_lnL_time);
+
+      ratio = exp(ratio);
       alpha = MIN(1.,ratio);
       u = Uni();
          
+      /* printf("\n. alnL:%f->%f tlnL: %f->%f rlnL: %f->%f ratio: %f", */
+      /*        cur_lnL_data,new_lnL_data, */
+      /*        cur_lnL_time,new_lnL_time, */
+      /*        cur_lnL_rate,new_lnL_rate, */
+      /*        ratio); */
+
       if(u > alpha) /* Reject */
 	{
-	  tree->rates->nd_t[root->num] = t1_cur;
+	  RATES_Reset_Times(tree);
+          RATES_Update_Cur_Bl(tree);
+          if(tree->eval_alnL == YES) Update_PMat_At_Given_Edge(b1,tree);
+
 	  tree->c_lnL              = cur_lnL_data;
 	  tree->rates->c_lnL_rates = cur_lnL_rate;
 	  tree->rates->c_lnL_times = cur_lnL_time;
-	  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
 	{
 	  tree->mcmc->acc_move[move_num]++;
 	}
-      
-      if(t1_new < t0)
-	{
-	  t1_new = t0+1.E-4;
-	  PhyML_Printf("\n");
-	  PhyML_Printf("\n== t0 = %f t1_new = %f",t0,t1_new);
-	  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"); */
-	}
-      if(t1_new > MIN(t2,t3))
-	{
-	  PhyML_Printf("\n");
-	  PhyML_Printf("\n== t0 = %f t1_new = %f t1 = %f t2 = %f t3 = %f MIN(t2,t3)=%f",t0,t1_new,t1_cur,t2,t3,MIN(t2,t3));
-	  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"); */
-	}
-      
-      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"); */
-	}
-    }
-  
-  tree->mcmc->run_move[move_num]++;
 
+      // Ignore boundaries when updating tuning parameter
+      tree->mcmc->run_move[move_num]+=1;
+
+    }
 }
 
 //////////////////////////////////////////////////////////////
@@ -1654,108 +1921,79 @@ void MCMC_Root_Time(t_tree *tree)
 
 void MCMC_Tree_Height(t_tree *tree)
 {
-  int i;
   phydbl K,mult,u,alpha,ratio;
   phydbl cur_lnL_data,new_lnL_data;
   phydbl cur_lnL_rate,new_lnL_rate;
   phydbl cur_lnL_time,new_lnL_time;
   phydbl floor;
   int n_nodes;
-  
+      
+
   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);
-  Record_Br_Len(tree);
 
   K            = tree->mcmc->tune_move[tree->mcmc->num_move_tree_height];
-  cur_lnL_data = tree->c_lnL;
-  new_lnL_data = tree->c_lnL;
   ratio        = 0.0;
+  cur_lnL_data = tree->c_lnL;
+  new_lnL_data = UNLIKELY;
   cur_lnL_rate = tree->rates->c_lnL_rates;
-  new_lnL_rate = tree->rates->c_lnL_rates;
+  new_lnL_rate = UNLIKELY;
   cur_lnL_time = tree->rates->c_lnL_times;
+  new_lnL_time = UNLIKELY;
   
   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
-  */
-  /* floor = 0.0; */
-  floor = tree->rates->t_floor[tree->n_root->num];
-  /* floor = tree->rates->t_prior_max[tree->n_root->num]; */
+  mult = exp(K*(u-0.5));
 
+  floor = 0.0;
   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);
-  if(tree->mcmc->use_data) new_lnL_data = Lk(NULL,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. 
-  */
-  /* ratio += LOG(mult); */
-  ratio += (phydbl)(n_nodes)*LOG(mult);
+  new_lnL_time = TIMES_Lk_Times(NO,tree);
 
-  /* Likelihood ratio */
-  if(tree->mcmc->use_data) ratio += (new_lnL_data - cur_lnL_data);
+  if(new_lnL_time > UNLIKELY)
+    {
+      new_lnL_data = Lk(NULL,tree);
+      new_lnL_rate = RATES_Lk_Rates(tree);
+    }
+  
+  ratio += (phydbl)(n_nodes)*log(mult);
 
-  /* Prior ratio */
+  ratio += (new_lnL_data - cur_lnL_data);
   ratio += (new_lnL_rate - cur_lnL_rate);
   ratio += (new_lnL_time - cur_lnL_time);
 
-  /* phydbl diff = (new_lnL_time - cur_lnL_time)+(phydbl)(n_nodes-1.)*LOG(mult); */
-  /* printf("\n. diff_lk = %12f -(n-1)*log(mult) = %12f n_nodes=%d [%12f] log(mult)=%f", */
-  /* 	 (new_lnL_time - cur_lnL_time), */
-  /* 	 -(phydbl)(n_nodes-1.)*LOG(mult), */
-  /* 	 n_nodes, */
-  /* 	 diff, */
-  /* 	 LOG(mult)); */
+  /* printf("\n. data: %f %f times: %f %f rates: %f %f", */
+  /*        new_lnL_data,cur_lnL_data, */
+  /*        new_lnL_time,cur_lnL_time, */
+  /*        new_lnL_rate,cur_lnL_rate); */
 
-  /* !!!!!!!!!!!! */
-  /* ratio += LOG(Dexp(FABS(new_height-floor),1./10.) / Dexp(FABS(cur_height-floor),1./10.)); */
-  
-  ratio = EXP(ratio);
+
+  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); */
   
   if(u > alpha)
     {
       RATES_Reset_Times(tree);
-      Restore_Br_Len(tree);
-      tree->c_lnL = cur_lnL_data;
+      RATES_Update_Cur_Bl(tree);
+      tree->rates->c_lnL_times = TIMES_Lk_Times(NO,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__);
+        }
     }
   else
     {
       tree->mcmc->acc_move[tree->mcmc->num_move_tree_height]++;
-      tree->mcmc->acc_move[tree->mcmc->num_move_nd_t+tree->n_root->num-tree->n_otu]++;
-      /* printf("\n. ACCEPT\n"); */
     }
 
   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]++;
 }
 
 //////////////////////////////////////////////////////////////
@@ -1769,84 +2007,55 @@ void MCMC_Updown_T_Cr(t_tree *tree)
   
   int i;
   phydbl K,mult,u,alpha,ratio;
-  phydbl cur_lnL_data,new_lnL_data;
   phydbl cur_lnL_rate,new_lnL_rate;
   phydbl cur_lnL_time,new_lnL_time;
   phydbl floor;
   int n_nodes;
 
   /*! Check that sequences are isochronous. */
-  For(i,tree->n_otu-1) if(!Are_Equal(tree->rates->nd_t[i+1],tree->rates->nd_t[i],1.E-10)) return; 
+  for(i=0;i<tree->n_otu-1;i++) if(!Are_Equal(tree->rates->nd_t[i+1],tree->rates->nd_t[i],1.E-10)) return; 
 
   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);
-  Record_Br_Len(tree);
 
   K            = tree->mcmc->tune_move[tree->mcmc->num_move_updown_t_cr];
-  cur_lnL_data = tree->c_lnL;
-  new_lnL_data = tree->c_lnL;
   ratio        = 0.0;
   cur_lnL_rate = tree->rates->c_lnL_rates;
-  new_lnL_rate = tree->rates->c_lnL_rates;
+  new_lnL_rate = UNLIKELY;
   cur_lnL_time = tree->rates->c_lnL_times;
+  new_lnL_time = UNLIKELY;
+
 
   u = Uni();
-  mult = EXP(K*(u-0.5));
+  mult = exp(K*(u-0.5));
 
   floor = 0.0;
-
   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_updown_t_cr]++;
-  	  return;
-  	}
-    }
-
-  if(RATES_Check_Node_Times(tree)) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
-
   tree->rates->clock_r /= mult;
   if(tree->rates->clock_r < tree->rates->min_clock || tree->rates->clock_r > tree->rates->max_clock)
     {
       tree->rates->clock_r *= mult;
       RATES_Reset_Times(tree);
-      Restore_Br_Len(tree);
       tree->mcmc->run_move[tree->mcmc->num_move_updown_t_cr]++;
       return;
     }
   
-  For(i,2*tree->n_otu-2) tree->rates->br_do_updt[i] = YES;
-  RATES_Update_Cur_Bl(tree);
-  if(tree->mcmc->use_data) new_lnL_data = Lk(NULL,tree);
-
   new_lnL_rate = RATES_Lk_Rates(tree);
-  new_lnL_time = TIMES_Lk_Times(tree);
+  new_lnL_time = TIMES_Lk_Times(NO,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. 
   */
-  ratio += (n_nodes - 1)*LOG(mult);
-  /* ratio += -LOG(mult) + LOG(Dgamma(1./mult,1./K,K)/Dgamma(mult,1./K,K)); */
-
-  /* Likelihood ratio */
-  if(tree->mcmc->use_data) ratio += (new_lnL_data - cur_lnL_data);
+  ratio += (n_nodes - 1)*log(mult);
 
-  /* Prior ratio */
   ratio += (new_lnL_rate - cur_lnL_rate);
   ratio += (new_lnL_time - cur_lnL_time);
 
-  /* !!!!!!!!!!!!1 */
-  /* ratio += LOG(Dexp(FABS(new_height-floor),1./10.) / Dexp(FABS(cur_height-floor),1./10.)); */
   
-  ratio = EXP(ratio);
+  ratio = exp(ratio);
   alpha = MIN(1.,ratio);
   u = Uni();
   
@@ -1858,15 +2067,15 @@ void MCMC_Updown_T_Cr(t_tree *tree)
 
   if(u > alpha)
     {
+      /* printf(" reject"); */
       RATES_Reset_Times(tree);
       tree->rates->clock_r *= mult;
-      Restore_Br_Len(tree);
-      tree->c_lnL = cur_lnL_data;
       tree->rates->c_lnL_rates = cur_lnL_rate;
       tree->rates->c_lnL_times = cur_lnL_time;
     }
   else
     {
+      /* printf("\ accept"); */
       tree->mcmc->acc_move[tree->mcmc->num_move_updown_t_cr]++;
     }
 
@@ -1885,31 +2094,31 @@ void MCMC_Updown_T_Br(t_tree *tree)
   phydbl cur_lnL_rate,new_lnL_rate;
   phydbl cur_lnL_time,new_lnL_time;
   phydbl floor;
-  int n_nodes;
+  int n_nodes, target;
 
   /*! Check that sequences are isochronous. */
-  For(i,tree->n_otu-1) if(!Are_Equal(tree->rates->nd_t[i+1],tree->rates->nd_t[i],1.E-10)) return; 
+  for(i=0;i<tree->n_otu-1;i++) if(!Are_Equal(tree->rates->nd_t[i+1],tree->rates->nd_t[i],1.E-10)) return; 
 
   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);
-  Record_Br_Len(tree);
 
   K            = tree->mcmc->tune_move[tree->mcmc->num_move_updown_t_br];
-  cur_lnL_data = tree->c_lnL;
-  new_lnL_data = tree->c_lnL;
   ratio        = 0.0;
+  cur_lnL_data = tree->c_lnL;
+  new_lnL_data = UNLIKELY;
   cur_lnL_rate = tree->rates->c_lnL_rates;
-  new_lnL_rate = tree->rates->c_lnL_rates;
+  new_lnL_rate = UNLIKELY;
   cur_lnL_time = tree->rates->c_lnL_times;
+  new_lnL_time = UNLIKELY;
 
   u = Uni();
-  mult = EXP(K*(u-0.5));
+  mult = exp(K*(u-0.5));
 
 
+  target = Rand_Int(tree->n_otu,2*tree->n_otu-3);
   floor = 0.0;
-
-  Scale_Subtree_Height(tree->n_root,mult,floor,&n_nodes,tree);
+  Scale_Subtree_Height(tree->a_nodes[target],mult,floor,&n_nodes,tree);
 
   For(i,2*tree->n_otu-1)
     {
@@ -1917,65 +2126,33 @@ void MCMC_Updown_T_Br(t_tree *tree)
   	 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_updown_t_br]++;
   	  return;
   	}
     }
 
   if(RATES_Check_Node_Times(tree)) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
-
-  tree->rates->birth_rate /= mult;
-
-  if(tree->rates->birth_rate < tree->rates->birth_rate_min || tree->rates->birth_rate > tree->rates->birth_rate_max)
-    {
-      tree->rates->birth_rate *= mult;
-      RATES_Reset_Times(tree);
-      Restore_Br_Len(tree);
-      tree->mcmc->run_move[tree->mcmc->num_move_updown_t_br]++;
-      return;
-    }
   
-  For(i,2*tree->n_otu-2) tree->rates->br_do_updt[i] = YES;
-  RATES_Update_Cur_Bl(tree);
-  if(tree->mcmc->use_data) new_lnL_data = Lk(NULL,tree);
-
+  new_lnL_data = Lk(NULL,tree);
   new_lnL_rate = RATES_Lk_Rates(tree);
-  new_lnL_time = TIMES_Lk_Times(tree);
+  new_lnL_time = TIMES_Lk_Times(NO,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. 
-  */
-  ratio += (n_nodes - 1)*LOG(mult);
-  /* ratio += -LOG(mult) + LOG(Dgamma(1./mult,1./K,K)/Dgamma(mult,1./K,K)); */
+  ratio += n_nodes*log(mult);
 
   /* Likelihood ratio */
-  if(tree->mcmc->use_data) ratio += (new_lnL_data - cur_lnL_data);
-
-  /* Prior ratio */
+  ratio += (new_lnL_data - cur_lnL_data);
   ratio += (new_lnL_rate - cur_lnL_rate);
   ratio += (new_lnL_time - cur_lnL_time);
-
-  /* !!!!!!!!!!!!1 */
-  /* ratio += LOG(Dexp(FABS(new_height-floor),1./10.) / Dexp(FABS(cur_height-floor),1./10.)); */
   
-  ratio = EXP(ratio);
+  ratio = exp(ratio);
   alpha = MIN(1.,ratio);
   u = Uni();
   
-  /* printf("\n. t_old = %f t_new = %f br_old = %f br_new = %f mult = %f K=%f", */
-  /*        tree->rates->nd_t[tree->n_root->num]/mult, */
-  /*        tree->rates->nd_t[tree->n_root->num], */
-  /*        tree->rates->birth_rate*mult, */
-  /*        tree->rates->birth_rate,mult,K); */
 
   if(u > alpha)
     {
       RATES_Reset_Times(tree);
-      tree->rates->birth_rate *= mult;
-      Restore_Br_Len(tree);
-      tree->c_lnL = cur_lnL_data;
+      tree->c_lnL              = cur_lnL_data;
       tree->rates->c_lnL_rates = cur_lnL_rate;
       tree->rates->c_lnL_times = cur_lnL_time;
     }
@@ -1992,7 +2169,6 @@ void MCMC_Updown_T_Br(t_tree *tree)
 
 void MCMC_Subtree_Height(t_tree *tree)
 {
-  int i;
   phydbl K,mult,u,alpha,ratio;
   phydbl cur_lnL_data,new_lnL_data;
   phydbl cur_lnL_rate,new_lnL_rate;
@@ -2002,78 +2178,55 @@ void MCMC_Subtree_Height(t_tree *tree)
   int n_nodes;
 
   RATES_Record_Times(tree);
-  Record_Br_Len(tree);
 
   K = tree->mcmc->tune_move[tree->mcmc->num_move_subtree_height];
+  ratio        = 0.0;
   cur_lnL_data = tree->c_lnL;
-  new_lnL_data = tree->c_lnL;
+  new_lnL_data = UNLIKELY;
   cur_lnL_rate = tree->rates->c_lnL_rates;
-  new_lnL_rate = tree->rates->c_lnL_rates;
-  ratio        = 0.0;
+  new_lnL_rate = UNLIKELY;
   cur_lnL_time = tree->rates->c_lnL_times;
+  new_lnL_time = UNLIKELY;
 
   u = Uni();
-  mult = EXP(K*(u-0.5));
-  /* mult = Rgamma(1./K,K); */
+  mult = exp(K*(u-0.5));
 
   target = Rand_Int(tree->n_otu,2*tree->n_otu-3);
-
-  floor = tree->rates->t_floor[target];
-
+  floor = 0.0;
   if(tree->a_nodes[target] == tree->n_root) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
 
   if(!Scale_Subtree_Height(tree->a_nodes[target],mult,floor,&n_nodes,tree))
     {
       RATES_Reset_Times(tree);
-      Restore_Br_Len(tree);
       tree->mcmc->run_move[tree->mcmc->num_move_subtree_height]++;
       return;
     }
 
-  
-  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_subtree_height]++;
-  	  return;
-  	}
-    }
-
-     
-  For(i,2*tree->n_otu-2) tree->rates->br_do_updt[i] = YES;
-  RATES_Update_Cur_Bl(tree);
-  if(tree->mcmc->use_data) new_lnL_data = Lk(NULL,tree);
-
-  new_lnL_rate = RATES_Lk_Rates(tree);
-  new_lnL_time = TIMES_Lk_Times(tree);
-
-  /* The Hastings ratio here is mult^(n_nodes) and the ratio of the prior joint densities
-     of the modified node heigths given the unchanged one is 1. This is different from the 
-     case where all the nodes, including the root node, are scaled. 
-  */
-  ratio += (phydbl)(n_nodes)*LOG(mult);
+  if(RATES_Check_Node_Times(tree)) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
 
-  /* Likelihood ratio */
-  if(tree->mcmc->use_data) ratio += (new_lnL_data - cur_lnL_data);
+  new_lnL_time = TIMES_Lk_Times(NO,tree);
 
-  /* Prior ratio */
+  if(new_lnL_time > UNLIKELY)
+    {
+      new_lnL_data = Lk(NULL,tree);
+      new_lnL_rate = RATES_Lk_Rates(tree);
+    }
+  
+  ratio += (phydbl)(n_nodes)*log(mult);
+  ratio += (new_lnL_data - cur_lnL_data);
   ratio += (new_lnL_rate - cur_lnL_rate);
   ratio += (new_lnL_time - cur_lnL_time);
 
 
-  ratio = EXP(ratio);
+  ratio = exp(ratio);
   alpha = MIN(1.,ratio);
   u = Uni();
   
   if(u > alpha)
     {
       RATES_Reset_Times(tree);
-      Restore_Br_Len(tree);
-      tree->c_lnL = cur_lnL_data;
+      RATES_Update_Cur_Bl(tree);
+      tree->c_lnL              = cur_lnL_data;
       tree->rates->c_lnL_rates = cur_lnL_rate;
       tree->rates->c_lnL_times = cur_lnL_time;
     }
@@ -2089,38 +2242,33 @@ void MCMC_Subtree_Height(t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void MCMC_Tree_Rates(t_tree *tree)
 {
   phydbl K,mult,u,alpha,ratio;
   phydbl cur_lnL_rate,new_lnL_rate;
-  phydbl cur_lnL_data,new_lnL_data;
+  /* phydbl cur_lnL_data,new_lnL_data; */
   int n_nodes;
   phydbl init_clock;
   
   if(tree->rates->model == STRICTCLOCK) return;
 
   RATES_Record_Rates(tree);
-  Record_Br_Len(tree);
+
+  tree->mcmc->run_move[tree->mcmc->num_move_tree_rates]++;
 
   K             = tree->mcmc->tune_move[tree->mcmc->num_move_tree_rates];
-  cur_lnL_data  = tree->c_lnL;
-  new_lnL_data  = tree->c_lnL;
   cur_lnL_rate  = tree->rates->c_lnL_rates;
-  new_lnL_rate  = tree->rates->c_lnL_rates;
+  new_lnL_rate  = UNLIKELY;
   init_clock    = tree->rates->clock_r;
   ratio         = 0.0;
 
   u = Uni();
-  mult = EXP(K*(u-0.5));
-  /* mult = Rgamma(1./K,K); */
+  mult = exp(K*(u-0.5));
     
   /* Multiply branch rates (or add to log of rates) */
   if(!Scale_Subtree_Rates(tree->n_root,mult,&n_nodes,tree))
     {
       RATES_Reset_Rates(tree);
-      Restore_Br_Len(tree);
-      tree->mcmc->run_move[tree->mcmc->num_move_tree_rates]++;
       return;
     }
 
@@ -2132,64 +2280,42 @@ void MCMC_Tree_Rates(t_tree *tree)
     {
       tree->rates->clock_r = init_clock;
       RATES_Reset_Rates(tree);
-      Restore_Br_Len(tree);
-      tree->mcmc->run_move[tree->mcmc->num_move_tree_rates]++;
       return;
     }
 
 /*   if(tree->rates->model == GUINDON) */
 /*     { */
-      int i;
-      For(i,2*tree->n_otu-2) tree->rates->br_do_updt[i] = YES;
-      RATES_Update_Cur_Bl(tree);
-      if(tree->mcmc->use_data) new_lnL_data = Lk(NULL,tree);
+      /* int i; */
+      /* For(i,2*tree->n_otu-2) tree->rates->br_do_updt[i] = YES; */
+      /* RATES_Update_Cur_Bl(tree); */
+      /* new_lnL_data = Lk(NULL,tree); */
 /*     } */
 
   new_lnL_rate = RATES_Lk_Rates(tree);
 
-
-  /* Proposal ratio: 2n-2=> number of multiplications, 1=>number of divisions */
-  ratio += (+(2*tree->n_otu-2)-1)*LOG(mult);
-  /* ratio += (+(2*tree->n_otu-2)-1-2)*LOG(mult) + LOG(Dgamma(1./mult,1./K,K)/Dgamma(mult,1./K,K)); */
-
-  /* If modelling log of rates instead of rates */
-  if(tree->rates->model_log_rates == YES) ratio -= (2*tree->n_otu-2)*LOG(mult);
-
-  /* Prior density ratio */
+  ratio += (n_nodes-1)*log(mult);
   ratio += (new_lnL_rate - cur_lnL_rate);
 
-  /* Likelihood density ratio */
-  ratio += (new_lnL_data - cur_lnL_data);
-
-  ratio = EXP(ratio);
+  ratio = exp(ratio);
   alpha = MIN(1.,ratio);
   u = Uni();
   
-/*   printf("\n. cur_lnL=%f new_lnL=%f ratio=%f mult=%f %f [%f %f]", */
-/*   	 cur_lnL_rate,new_lnL_rate,ratio,mult,(+(2*tree->n_otu-2)-1-2)*LOG(mult) + LOG(Dgamma(1./mult,1./K,K)/Dgamma(mult,1./K,K)),new_lnL_data,cur_lnL_data); */
 
   if(u > alpha)
     {
-/*       PhyML_Printf("\n. Reject mult=%f",mult); */
       tree->rates->clock_r = init_clock;
       RATES_Reset_Rates(tree);
-      Restore_Br_Len(tree);
       tree->rates->c_lnL_rates = cur_lnL_rate;
-      tree->c_lnL        = cur_lnL_data;
     }
   else
     {
-/*       PhyML_Printf("\n. Accept mult=%f",mult); */
       tree->mcmc->acc_move[tree->mcmc->num_move_tree_rates]++;
     }
-
-  tree->mcmc->run_move[tree->mcmc->num_move_tree_rates]++;
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void MCMC_Subtree_Rates(t_tree *tree)
 {  phydbl K,mult,u,alpha,ratio;
   phydbl cur_lnL_rate,new_lnL_rate;
@@ -2210,7 +2336,7 @@ void MCMC_Subtree_Rates(t_tree *tree)
   ratio         = 0.0;
 
   u = Uni();
-  mult = EXP(K*(u-0.5));
+  mult = exp(K*(u-0.5));
   /* mult = Rgamma(1./K,K); */
 
   target = Rand_Int(tree->n_otu,2*tree->n_otu-3);
@@ -2225,23 +2351,20 @@ void MCMC_Subtree_Rates(t_tree *tree)
     }
 
   new_lnL_rate = RATES_Lk_Rates(tree);
-  if(tree->mcmc->use_data) new_lnL_data = Lk(NULL,tree);
+  new_lnL_data = Lk(NULL,tree);
 
   /* Proposal ratio: 2n-2=> number of multiplications, 1=>number of divisions */
-  ratio += (+n_nodes)*LOG(mult);
-  /* ratio += (n_nodes-2)*LOG(mult) + LOG(Dgamma(1./mult,1./K,K)/Dgamma(mult,1./K,K)); */
+  ratio += (+n_nodes)*log(mult);
+  /* ratio += (n_nodes-2)*log(mult) + log(Dgamma(1./mult,1./K,K)/Dgamma(mult,1./K,K)); */
   
   /* If modelling log of rates instead of rates */
-  if(tree->rates->model_log_rates == YES) ratio -= (n_nodes)*LOG(mult);
+  if(tree->rates->model_log_rates == YES) ratio -= (n_nodes)*log(mult);
 
-  /* Prior density ratio */
   ratio += (new_lnL_rate - cur_lnL_rate);
-
-  /* Likelihood density ratio */
   ratio += (new_lnL_data - cur_lnL_data);
 
 
-  ratio = EXP(ratio);
+  ratio = exp(ratio);
   alpha = MIN(1.,ratio);
   u = Uni();
   
@@ -2263,7 +2386,6 @@ void MCMC_Subtree_Rates(t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void MCMC_Swing(t_tree *tree)
 {
   int i;
@@ -2285,7 +2407,7 @@ void MCMC_Swing(t_tree *tree)
   ratio         = 0.0;
 
   u = Uni();
-  /* mult = EXP(K*(u-0.5)); */
+  /* mult = exp(K*(u-0.5)); */
   mult = u*(K - 1./K) + 1./K;
 
 
@@ -2319,17 +2441,16 @@ void MCMC_Swing(t_tree *tree)
         }
     }
 
-  For(i,2*tree->n_otu-2) tree->rates->br_do_updt[i] = YES;
   RATES_Update_Cur_Bl(tree);
-  if(tree->mcmc->use_data) new_lnL_data = Lk(NULL,tree);
+  new_lnL_data = Lk(NULL,tree);
 
   new_lnL_rate = RATES_Lk_Rates(tree);
 
-  ratio += (-(tree->n_otu-1.)-2.)*LOG(mult);
+  ratio += (-(tree->n_otu-1.)-2.)*log(mult);
   ratio += (new_lnL_rate - cur_lnL_rate);
-  if(tree->mcmc->use_data) ratio += (new_lnL_data - cur_lnL_data);
+  ratio += (new_lnL_data - cur_lnL_data);
 
-  ratio = EXP(ratio);
+  ratio = exp(ratio);
   alpha = MIN(1.,ratio);
   u = Uni();
 
@@ -2353,13 +2474,11 @@ void MCMC_Swing(t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void MCMC_Updown_Nu_Cr(t_tree *tree)
 {
   phydbl K,mult,u,alpha,ratio;
   phydbl cur_lnL_rate,new_lnL_rate;
   phydbl cur_lnL_data,new_lnL_data;
-  int i;
   
   RATES_Record_Rates(tree);
   Record_Br_Len(tree);
@@ -2371,7 +2490,7 @@ void MCMC_Updown_Nu_Cr(t_tree *tree)
   new_lnL_rate  = tree->rates->c_lnL_rates;
   
   u = Uni();
-  mult = EXP(K*(u-0.5));
+  mult = exp(K*(u-0.5));
 
   /* Multiply branch rates */
   /* if(!Scale_Subtree_Rates(tree->n_root,mult,&n_nodes,tree)) */
@@ -2403,22 +2522,21 @@ void MCMC_Updown_Nu_Cr(t_tree *tree)
       return;
     }
   
-  For(i,2*tree->n_otu-2) tree->rates->br_do_updt[i] = YES;
   RATES_Update_Cur_Bl(tree);
-  if(tree->mcmc->use_data) new_lnL_data = Lk(NULL,tree);
+  new_lnL_data = Lk(NULL,tree);
 
   new_lnL_rate = RATES_Lk_Rates(tree);
 
   ratio = 0.0;
   /* Proposal ratio: 2n-2=> number of multiplications, 1=>number of divisions */
-  /* ratio += n_nodes*LOG(mult); /\* (1-1)*LOG(mult); *\/ */
-  ratio += 0.0*LOG(mult); /* (1-1)*LOG(mult); */
+  /* ratio += n_nodes*log(mult); /\* (1-1)*log(mult); *\/ */
+  ratio += 0.0*log(mult); /* (1-1)*log(mult); */
   /* Prior density ratio */
   ratio += (new_lnL_rate - cur_lnL_rate);
   /* Likelihood density ratio */
   ratio += (new_lnL_data - cur_lnL_data);
 
-  ratio = EXP(ratio);
+  ratio = exp(ratio);
   alpha = MIN(1.,ratio);
   u = Uni();
   
@@ -2442,34 +2560,115 @@ void MCMC_Updown_Nu_Cr(t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
-void MCMC_Print_Param_Stdin(t_mcmc *mcmc, t_tree *tree)
+void MCMC_Time_Slice(t_tree *tree)
 {
-  time_t cur_time;
-  phydbl min;
   int i;
-  time(&cur_time);
+  phydbl K,mult,u,alpha,ratio;
+  phydbl cur_lnL_data,new_lnL_data;
+  phydbl cur_lnL_rate,new_lnL_rate;
+  phydbl cur_lnL_time,new_lnL_time;
+  phydbl floor;
+  int n_nodes;
   
-  min = MDBL_MAX;
-  For(i,tree->n_otu-1)
-    {
-      /*       printf("\n. %d %f %f %f %f",i, */
-      /* 	     tree->mcmc->new_param_val[tree->mcmc->num_move_nd_t+i], */
-      /* 	     tree->mcmc->old_param_val[tree->mcmc->num_move_nd_t+i], */
-      /* 	     tree->mcmc->ess[tree->mcmc->num_move_nd_t+i], */
-      /* 	     tree->mcmc->sum_val[tree->mcmc->num_move_nd_t+i]); */
+  /*! Check that sequences are isochronous. */
+  for(i=0;i<tree->n_otu-1;i++) if(!Are_Equal(tree->rates->nd_t[i+1],tree->rates->nd_t[i],1.E-10)) return; 
+  
+  RATES_Record_Times(tree);
+  
+  K            = tree->mcmc->tune_move[tree->mcmc->num_move_time_slice];
+  cur_lnL_data = tree->c_lnL;
+  new_lnL_data = UNLIKELY;
+  cur_lnL_rate = tree->rates->c_lnL_rates;
+  new_lnL_rate = UNLIKELY;
+  cur_lnL_time = tree->rates->c_lnL_times;
+  new_lnL_time = UNLIKELY;
+  ratio        = 0.0;
+  
+  u = Uni();
+  mult = exp(K*(u-0.5));
 
-      if(tree->mcmc->ess[tree->mcmc->num_move_nd_t+i] < min)
-	min = tree->mcmc->ess[tree->mcmc->num_move_nd_t+i];
-    }
+  floor = Uni()*tree->rates->nd_t[tree->n_root->num];
 
+  Scale_Subtree_Height(tree->n_root,mult,floor,&n_nodes,tree);
 
-  if(mcmc->run == 1)
+  if(TIMES_Check_Node_Height_Ordering(tree) != NO)
     {
-      PhyML_Printf("\n\n");
-      PhyML_Printf("%9s","Run");
-      PhyML_Printf("  %5s","Time");
-      PhyML_Printf("  %10s","Likelihood");
+      RATES_Update_Cur_Bl(tree);
+      
+      new_lnL_time = TIMES_Lk_Times(NO,tree);
+
+      if(new_lnL_time > UNLIKELY)
+        {
+          new_lnL_data = Lk(NULL,tree);      
+          new_lnL_rate = RATES_Lk_Rates(tree);
+        }
+      
+      ratio += (phydbl)(n_nodes)*log(mult);
+
+      /* Likelihood ratio */
+      ratio += (new_lnL_data - cur_lnL_data);
+      
+      /* Prior ratio */
+      ratio += (new_lnL_rate - cur_lnL_rate);
+      ratio += (new_lnL_time - cur_lnL_time);
+      
+      /* printf("\n. data: %f<-%f times: %f<-%f rates: %f<-%f acc.: [%d/%d] k: %f t: %f x: %f", */
+      /*        new_lnL_data,cur_lnL_data, */
+      /*        new_lnL_time,cur_lnL_time, */
+      /*        new_lnL_rate,cur_lnL_rate, */
+      /*        tree->mcmc->acc_move[tree->mcmc->num_move_time_slice], */
+      /*        tree->mcmc->run_move[tree->mcmc->num_move_time_slice], */
+      /*        K,floor,mult); */
+      
+      ratio = exp(ratio);
+    }
+  else
+    {
+      ratio = 0.0;
+    }
+
+  alpha = MIN(1.,ratio);
+  u = Uni();
+  
+  if(u > alpha)
+    {
+      RATES_Reset_Times(tree);
+      RATES_Update_Cur_Bl(tree);
+      tree->rates->c_lnL_times = TIMES_Lk_Times(NO,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;
+
+      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__);
+        }
+    }
+  else
+    {
+      tree->mcmc->acc_move[tree->mcmc->num_move_time_slice]++;
+    }
+
+  tree->mcmc->run_move[tree->mcmc->num_move_time_slice]++;
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void MCMC_Print_Param_Stdin(t_mcmc *mcmc, t_tree *tree)
+{
+  time_t cur_time;
+
+  time(&cur_time);
+  
+
+
+  if(mcmc->run == 1)
+    {
+      PhyML_Printf("\n\n");
+      PhyML_Printf("%9s","Run");
+      PhyML_Printf("  %5s","Time");
+      PhyML_Printf("  %10s","Likelihood");
       PhyML_Printf("  %10s","Prior");
       PhyML_Printf("  %19s","SubstRate[ ESS ]");
       PhyML_Printf("  %17s","TreeHeight[ ESS ]");    
@@ -2489,16 +2688,12 @@ void MCMC_Print_Param_Stdin(t_mcmc *mcmc, t_tree *tree)
       PhyML_Printf("  %10.2f",(tree->rates ? tree->rates->c_lnL_rates+tree->rates->c_lnL_times : +1));
       PhyML_Printf("  %12.6f[%5.0f]",RATES_Average_Substitution_Rate(tree),tree->mcmc->ess[tree->mcmc->num_move_clock_r]);
       /* PhyML_Printf("\t%12.6f[%5.0f]",tree->rates->clock_r,tree->mcmc->ess[tree->mcmc->num_move_clock_r]); */
-      PhyML_Printf("  %10.1f[%5.0f]",
-                   (tree->rates ? tree->rates->nd_t[tree->n_root->num] : -1.),
-                   tree->mcmc->ess[tree->mcmc->num_move_nd_t+tree->n_root->num-tree->n_otu]);
       PhyML_Printf("  %9f[%5.0f]",
                    (tree->rates ? tree->rates->nu : -1.),
                    tree->mcmc->ess[tree->mcmc->num_move_nu]);
       PhyML_Printf("  %8f[%5.0f]",
                    (tree->rates ? tree->rates->birth_rate : -1.),
                    tree->mcmc->ess[tree->mcmc->num_move_birth_rate]);
-      PhyML_Printf("  %8.0f",min);
     }
 }
 
@@ -2549,7 +2744,7 @@ void MCMC_Print_Param(t_mcmc *mcmc, t_tree *tree)
     {
       MCMC_Copy_To_New_Param_Val(tree->mcmc,tree);
 
-      For(i,tree->mcmc->n_moves)
+      for(i=0;i<tree->mcmc->n_moves;i++)
 	{
 	  if((tree->mcmc->acc_rate[i] > .1) && (tree->mcmc->start_ess[i] == NO)) tree->mcmc->start_ess[i] = YES;
 	  if(tree->mcmc->start_ess[i] == YES) MCMC_Update_Effective_Sample_Size(i,tree->mcmc,tree);
@@ -2568,19 +2763,19 @@ void MCMC_Print_Param(t_mcmc *mcmc, t_tree *tree)
 	  /* PhyML_Fprintf(fp,"MeanRate\t"); */
 /* 	  PhyML_Fprintf(fp,"NormFact\t"); */
 
-	  /* For(i,mcmc->n_moves) */
+	  /* for(i=0;i<mcmc->n_moves;i++) */
 	  /*   { */
 	  /*     strcpy(s,"Acc."); */
 	  /*     PhyML_Fprintf(fp,"%s%d\t",strcat(s,mcmc->move_name[i]),i); */
 	  /*   } */
 
-	  /* For(i,mcmc->n_moves) */
+	  /* for(i=0;i<mcmc->n_moves;i++) */
 	  /*   { */
 	  /*     strcpy(s,"Tune."); */
 	  /*     PhyML_Fprintf(fp,"%s%d\t",strcat(s,mcmc->move_name[i]),i); */
 	  /*   } */
 
-	  /* For(i,mcmc->n_moves) */
+	  /* for(i=0;i<mcmc->n_moves;i++) */
 	  /*   { */
 	  /*     strcpy(s,"Run."); */
 	  /*     PhyML_Fprintf(fp,"%s\t",strcat(s,mcmc->move_name[i])); */
@@ -2603,16 +2798,16 @@ void MCMC_Print_Param(t_mcmc *mcmc, t_tree *tree)
 	      if(tree->mod->ras->free_mixt_rates == NO) PhyML_Fprintf(fp,"Alpha\t");
 	      else
 		{
-		  For(i,tree->mod->ras->n_catg) PhyML_Fprintf(fp,"p%d\t",i);
-		  For(i,tree->mod->ras->n_catg) PhyML_Fprintf(fp,"r%d\t",i);
+		  for(i=0;i<tree->mod->ras->n_catg;i++) PhyML_Fprintf(fp,"p%d\t",i);
+		  for(i=0;i<tree->mod->ras->n_catg;i++) PhyML_Fprintf(fp,"r%d\t",i);
 		}
 	    }
 
 
 	  if(tree->mod->m4mod->n_h > 1 && tree->mod->use_m4mod == YES)
 	    {
-	      For(i,tree->mod->m4mod->n_h) PhyML_Fprintf(fp,"cov_p%d\t",i);
-	      For(i,tree->mod->m4mod->n_h) PhyML_Fprintf(fp,"cov_r%d\t",i);
+	      for(i=0;i<tree->mod->m4mod->n_h;i++) PhyML_Fprintf(fp,"cov_p%d\t",i);
+	      for(i=0;i<tree->mod->m4mod->n_h;i++) PhyML_Fprintf(fp,"cov_r%d\t",i);
 	      PhyML_Fprintf(fp,"cov_switch\t");
 	    }
 
@@ -2699,7 +2894,7 @@ void MCMC_Print_Param(t_mcmc *mcmc, t_tree *tree)
 	  PhyML_Fprintf(mcmc->out_fp_trees,"#NEXUS\n");
 	  PhyML_Fprintf(mcmc->out_fp_trees,"BEGIN TREES;\n");
 	  PhyML_Fprintf(mcmc->out_fp_trees,"\tTRANSLATE\n");
-	  For(i,tree->n_otu-1) PhyML_Fprintf(mcmc->out_fp_trees,"\t%3d\t%s,\n",tree->a_nodes[i]->num+1,tree->a_nodes[i]->name);
+	  for(i=0;i<tree->n_otu-1;i++) PhyML_Fprintf(mcmc->out_fp_trees,"\t%3d\t%s,\n",tree->a_nodes[i]->num+1,tree->a_nodes[i]->name);
 	  PhyML_Fprintf(mcmc->out_fp_trees,"\t%3d\t%s;\n",tree->a_nodes[i]->num+1,tree->a_nodes[i]->name);
 	  tree->write_tax_names = NO;
 	}
@@ -2715,18 +2910,18 @@ void MCMC_Print_Param(t_mcmc *mcmc, t_tree *tree)
 /*       PhyML_Fprintf(fp,"%f\t",RATES_Check_Mean_Rates(tree)); */
 
 /*       PhyML_Fprintf(fp,"%f\t",tree->rates->norm_fact); */
-      /* For(i,tree->mcmc->n_moves) PhyML_Fprintf(fp,"%f\t",tree->mcmc->acc_rate[i]); */
-      /* For(i,tree->mcmc->n_moves) PhyML_Fprintf(fp,"%f\t",(phydbl)(tree->mcmc->tune_move[i])); */
-/*       For(i,tree->mcmc->n_moves) PhyML_Fprintf(fp,"%d\t",(int)(tree->mcmc->run_move[i])); */
+      /* for(i=0;i<tree->mcmc->n_moves;i++) PhyML_Fprintf(fp,"%f\t",tree->mcmc->acc_rate[i]); */
+      /* for(i=0;i<tree->mcmc->n_moves;i++) PhyML_Fprintf(fp,"%f\t",(phydbl)(tree->mcmc->tune_move[i])); */
+/*       for(i=0;i<tree->mcmc->n_moves;i++) PhyML_Fprintf(fp,"%d\t",(int)(tree->mcmc->run_move[i])); */
 
       orig_approx = tree->io->lk_approx;
       orig_lnL = tree->c_lnL;
       tree->io->lk_approx = EXACT;
-      if(tree->mcmc->use_data)  Lk(NULL,tree);  else tree->c_lnL = 0.0;
+      Lk(NULL,tree);
       PhyML_Fprintf(fp,"%.1f\t",tree->c_lnL);
       tree->io->lk_approx = NORMAL;
       tree->c_lnL = 0.0;
-      if(tree->mcmc->use_data)  Lk(NULL,tree);  else tree->c_lnL = 0.0;
+      Lk(NULL,tree);
       PhyML_Fprintf(fp,"%.1f\t",tree->c_lnL);
       tree->io->lk_approx = orig_approx;
       tree->c_lnL = orig_lnL;
@@ -2748,17 +2943,17 @@ void MCMC_Print_Param(t_mcmc *mcmc, t_tree *tree)
 	    PhyML_Fprintf(fp,"%G\t",tree->mod->ras->alpha->v);
 	  else
 	    {
-	      For(i,tree->mod->ras->n_catg) PhyML_Fprintf(fp,"%G\t",tree->mod->ras->gamma_r_proba->v[i]);
-	      For(i,tree->mod->ras->n_catg) PhyML_Fprintf(fp,"%G\t",tree->mod->ras->gamma_rr->v[i]);
-	      /* For(i,tree->mod->ras->n_catg) PhyML_Fprintf(fp,"%G\t",tree->mod->ras->gamma_r_proba_unscaled[i]); */
-	      /* For(i,tree->mod->ras->n_catg) PhyML_Fprintf(fp,"%G\t",tree->mod->ras->gamma_rr_unscaled[i]); */
+	      for(i=0;i<tree->mod->ras->n_catg;i++) PhyML_Fprintf(fp,"%G\t",tree->mod->ras->gamma_r_proba->v[i]);
+	      for(i=0;i<tree->mod->ras->n_catg;i++) PhyML_Fprintf(fp,"%G\t",tree->mod->ras->gamma_rr->v[i]);
+	      /* for(i=0;i<tree->mod->ras->n_catg;i++) PhyML_Fprintf(fp,"%G\t",tree->mod->ras->gamma_r_proba_unscaled[i]); */
+	      /* for(i=0;i<tree->mod->ras->n_catg;i++) PhyML_Fprintf(fp,"%G\t",tree->mod->ras->gamma_rr_unscaled[i]); */
 	    }
 	}
 
       if(tree->mod->m4mod->n_h > 1 && tree->mod->use_m4mod == YES)
 	{
-	  For(i,tree->mod->m4mod->n_h) PhyML_Fprintf(fp,"%G\t",tree->mod->m4mod->h_fq[i]);
-	  For(i,tree->mod->m4mod->n_h) PhyML_Fprintf(fp,"%G\t",tree->mod->m4mod->multipl[i]);
+	  for(i=0;i<tree->mod->m4mod->n_h;i++) PhyML_Fprintf(fp,"%G\t",tree->mod->m4mod->h_fq[i]);
+	  for(i=0;i<tree->mod->m4mod->n_h;i++) PhyML_Fprintf(fp,"%G\t",tree->mod->m4mod->multipl[i]);
 	  PhyML_Fprintf(fp,"%G\t",tree->mod->m4mod->delta);
 	}
 
@@ -2768,7 +2963,7 @@ void MCMC_Print_Param(t_mcmc *mcmc, t_tree *tree)
       for(i=tree->n_otu;i<2*tree->n_otu-1;i++) PhyML_Fprintf(fp,format,tree->rates->nd_t[i]);
       Free(format);
 
-      /* for(i=0;i<2*tree->n_otu-1;i++) PhyML_Fprintf(fp,"%.4f\t",LOG(tree->rates->nd_r[i])); */
+      /* for(i=0;i<2*tree->n_otu-1;i++) PhyML_Fprintf(fp,"%.4f\t",log(tree->rates->nd_r[i])); */
       
       // Average rate along edges: length divided by elapsed time
       For(i,2*tree->n_otu-2)
@@ -2777,7 +2972,7 @@ void MCMC_Print_Param(t_mcmc *mcmc, t_tree *tree)
 
       /* fp_pred = fopen("predict.txt","a");       */
       /* for(i=0;i<2*tree->n_otu-2;i++)  */
-      /* 	PhyML_Fprintf(fp_pred,"B%d\t%12f\t%12f\t%4d\n",i,EXP(tree->rates->br_r[i]),tree->rates->nd_t[i],tree->rates->has_survived[i]); */
+      /* 	PhyML_Fprintf(fp_pred,"B%d\t%12f\t%12f\t%4d\n",i,exp(tree->rates->br_r[i]),tree->rates->nd_t[i],tree->rates->has_survived[i]); */
       /* fclose(fp_pred); */
 
 
@@ -2794,14 +2989,14 @@ void MCMC_Print_Param(t_mcmc *mcmc, t_tree *tree)
 
       /* for(i=0;i<2*tree->n_otu-2;i++) PhyML_Fprintf(fp,"%.4f\t",tree->rates->cur_gamma_prior_mean[i]); */
       /* if(fp != stdout) for(i=tree->n_otu;i<2*tree->n_otu-1;i++) PhyML_Fprintf(fp,"%G\t",tree->rates->t_prior[i]); */
-/*       For(i,2*tree->n_otu-3) PhyML_Fprintf(fp,"%f\t",EXP(tree->a_edges[i]->l->v)); */
+/*       For(i,2*tree->n_otu-3) PhyML_Fprintf(fp,"%f\t",exp(tree->a_edges[i]->l->v)); */
 
 
       /* RATES_Update_Cur_Bl(tree); */
       /* For(i,2*tree->n_otu-3) PhyML_Fprintf(fp,"%f\t",tree->a_edges[i]->l->v); */
 
 
-      For(i,2*tree->n_otu-2) tree->rates->mean_r[i] = EXP(tree->rates->br_r[i]);
+      For(i,2*tree->n_otu-2) tree->rates->mean_r[i] = exp(tree->rates->br_r[i]);
       For(i,2*tree->n_otu-1) tree->rates->mean_t[i] = tree->rates->nd_t[i];
       
       /* Time_To_Branch(tree); */
@@ -2835,7 +3030,7 @@ void MCMC_Print_Param(t_mcmc *mcmc, t_tree *tree)
       /* 	    { */
       /* 	      d = tree->a_nodes[i]; */
       /* 	      v1 = v2 = NULL; */
-      /* 	      For(j,3) */
+      /* 	      for(j=0;j<3;j++) */
       /* 		{ */
       /* 		  if(d->v[j] != d->anc && d->b[j] != tree->e_root) */
       /* 		    { */
@@ -2844,25 +3039,25 @@ void MCMC_Print_Param(t_mcmc *mcmc, t_tree *tree)
       /* 		    } */
       /* 		} */
 
-      /* 	      For(j,3) */
+      /* 	      for(j=0;j<3;j++) */
       /* 		{ */
       /* 		  if(v1->v[j] && v1->v[j] == d) */
       /* 		    { */
       /* 		      n1 = v1->bip_size[j]; */
       /* 		      /\* r1 = RATES_Get_Mean_Rate_In_Subtree(v1,tree); *\/ */
-      /* 		      r1 = EXP(tree->rates->br_r[v1->num]); */
+      /* 		      r1 = exp(tree->rates->br_r[v1->num]); */
       /* 		      break; */
       /* 		    } */
       /* 		} */
 
 
-      /* 	      For(j,3) */
+      /* 	      for(j=0;j<3;j++) */
       /* 		{ */
       /* 		  if(v2->v[j] && v2->v[j] == d) */
       /* 		    { */
       /* 		      n2 = v2->bip_size[j]; */
       /* 		      /\* r2 = RATES_Get_Mean_Rate_In_Subtree(v2,tree); *\/ */
-      /* 		      r2 = EXP(tree->rates->br_r[v2->num]); */
+      /* 		      r2 = exp(tree->rates->br_r[v2->num]); */
       /* 		      break; */
       /* 		    } */
       /* 		} */
@@ -3041,11 +3236,9 @@ void MCMC_Pause(t_mcmc *mcmc)
 
 }
 
-
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void MCMC_Terminate()
 {
   char choice;
@@ -3070,7 +3263,6 @@ void MCMC_Copy_MCMC_Struct(t_mcmc *ori, t_mcmc *cpy, char *filename)
   int pid;
   int i;
   
-  cpy->use_data           = ori->use_data        ;
   cpy->sample_interval    = ori->sample_interval ;
   cpy->chain_len          = ori->chain_len       ;
   cpy->randomize          = ori->randomize       ;
@@ -3086,7 +3278,7 @@ void MCMC_Copy_MCMC_Struct(t_mcmc *ori, t_mcmc *cpy, char *filename)
   cpy->nd_t_digits        = ori->nd_t_digits     ;
   cpy->max_lag            = ori->max_lag         ;
 
-  For(i,cpy->n_moves) 
+  for(i=0;i<cpy->n_moves;i++) 
     {
       cpy->start_ess[i]          = ori->start_ess[i];
       cpy->ess_run[i]            = ori->ess_run[i];
@@ -3158,7 +3350,6 @@ void MCMC_Close_MCMC(t_mcmc *mcmc)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void MCMC_Randomize_Kappa(t_tree *tree)
 {
   tree->mod->kappa->v = Uni()*5.;
@@ -3167,7 +3358,6 @@ void MCMC_Randomize_Kappa(t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void MCMC_Randomize_Rate_Across_Sites(t_tree *tree)
 {
   if(tree->mod->ras->n_catg == 1) return;
@@ -3175,9 +3365,10 @@ void MCMC_Randomize_Rate_Across_Sites(t_tree *tree)
   if(tree->mod->ras->free_mixt_rates == YES)
     {
       int i;
-      For(i,tree->mod->ras->n_catg-1) tree->mod->ras->gamma_r_proba_unscaled->v[i] = Uni()*100.;
-      tree->mod->ras->gamma_r_proba_unscaled->v[tree->mod->ras->n_catg-1] = 100.;
-      For(i,tree->mod->ras->n_catg) tree->mod->ras->gamma_rr_unscaled->v[i] = (phydbl)i+1.; /* Do not randomize those as their ordering matter */
+      for(i=0;i<tree->mod->ras->n_catg-1;i++) tree->mod->ras->gamma_r_proba_unscaled->v[i] = Uni();
+      tree->mod->ras->gamma_r_proba_unscaled->v[tree->mod->ras->n_catg-1] = 1.;
+      for(i=0;i<tree->mod->ras->n_catg-1;i++) tree->mod->ras->gamma_rr_unscaled->v[i] = (phydbl)i+0.1; /* Do not randomize those as their ordering matter */
+      tree->mod->ras->gamma_rr_unscaled->v[tree->mod->ras->n_catg-1] = (phydbl)tree->mod->ras->n_catg;
     }
   else
     {
@@ -3197,7 +3388,7 @@ void MCMC_Randomize_Covarion_Rates(t_tree *tree)
   
   int i;
 
-  For(i,tree->mod->m4mod->n_h)
+  for(i=0;i<tree->mod->m4mod->n_h;i++)
     {
       tree->mod->m4mod->multipl_unscaled[i] = (phydbl)i+1.;
       tree->mod->m4mod->h_fq_unscaled[i] = Uni()*(100.-0.01) + 0.01;
@@ -3232,7 +3423,6 @@ void MCMC_Randomize_Branch_Lengths(t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void MCMC_Randomize_Node_Rates(t_tree *tree)
 {
 
@@ -3253,7 +3443,6 @@ void MCMC_Randomize_Node_Rates(t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void MCMC_Randomize_Rates(t_tree *tree)
 {
 
@@ -3284,23 +3473,23 @@ void MCMC_Randomize_Rates(t_tree *tree)
 void MCMC_Randomize_Rates_Pre(t_node *a, t_node *d, t_tree *tree)
 {
   int i;
-  phydbl mean_r, var_r;
+  phydbl mean_r, sd_r;
   phydbl min_r, max_r;
   int err;
 
 /*   mean_r = tree->rates->br_r[a->num]; */
 /*   var_r  = tree->rates->nu * (tree->rates->nd_t[d->num] - tree->rates->nd_t[a->num]); */
   mean_r = 1.0;
-  var_r  = 0.5;
+  sd_r   = 10.0;
   min_r  = tree->rates->min_rate;
   max_r  = tree->rates->max_rate;
   
-  tree->rates->br_r[d->num] = Rnorm_Trunc(mean_r,SQRT(var_r),min_r,max_r,&err);
+  tree->rates->br_r[d->num] = Rnorm_Trunc(mean_r,sd_r,min_r,max_r,&err);
 
   if(d->tax) return;
   else
     {
-      For(i,3)
+      for(i=0;i<3;i++)
 	if(d->v[i] != a && d->b[i] != tree->e_root)
 	  MCMC_Randomize_Rates_Pre(d,d->v[i],tree);
     }
@@ -3324,6 +3513,22 @@ void MCMC_Randomize_Birth(t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
+void MCMC_Randomize_Death(t_tree *tree)
+{
+  phydbl min_d,max_d;
+  phydbl u;
+
+  min_d = tree->rates->death_rate_min;
+  max_d = MIN(MIN(0.5,tree->rates->death_rate_max),tree->rates->birth_rate);
+  
+  u = Uni();
+  tree->rates->death_rate = (max_d - min_d) * u + min_d;
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+
 void MCMC_Randomize_Nu(t_tree *tree)
 {
   phydbl min_nu,max_nu;
@@ -3353,7 +3558,7 @@ void MCMC_Randomize_Clock_Rate(t_tree *tree)
 {
   phydbl u;
   u = Uni();
-  tree->rates->clock_r = u * (tree->rates->max_clock - tree->rates->min_clock) + tree->rates->min_clock;
+  tree->rates->clock_r = u * (1.0 - tree->rates->min_clock) + tree->rates->min_clock;
 }
 
 //////////////////////////////////////////////////////////////
@@ -3390,10 +3595,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 +3635,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);
@@ -3467,7 +3673,7 @@ void MCMC_Randomize_Node_Times_Bottom_Up(t_node *a, t_node *d, t_tree *tree)
       t_node *v1, *v2;
 
 
-      For(i,3)
+      for(i=0;i<3;i++)
 	{
 	  if((d->v[i] != a) && (d->b[i] != tree->e_root))
 	    {
@@ -3476,7 +3682,7 @@ void MCMC_Randomize_Node_Times_Bottom_Up(t_node *a, t_node *d, t_tree *tree)
 	}
 
       v1 = v2 = NULL;
-      For(i,3)
+      for(i=0;i<3;i++)
       	{
       	  if(d->v[i] != a && d->b[i] != tree->e_root)
       	    {
@@ -3520,7 +3726,7 @@ void MCMC_Randomize_Node_Times_Top_Down(t_node *a, t_node *d, t_tree *tree)
       
       tree->rates->nd_t[d->num] = u;
 
-      For(i,3)
+      for(i=0;i<3;i++)
 	{
 	  if((d->v[i] != a) && (d->b[i] != tree->e_root))
 	    {
@@ -3545,7 +3751,7 @@ void MCMC_Get_Acc_Rates(t_mcmc *mcmc)
 
   eps = 1.E-6;
 
-  For(i,mcmc->n_moves)
+  for(i=0;i<mcmc->n_moves;i++)
     {
       if(mcmc->run_move[i] - mcmc->prev_run_move[i] > lag)
 	{
@@ -3568,7 +3774,7 @@ void MCMC_Get_Acc_Rates(t_mcmc *mcmc)
 
 void MCMC_Adjust_Tuning_Parameter(int move, t_mcmc *mcmc)
 {
-  if(mcmc->adjust_tuning[move])
+  if(mcmc->adjust_tuning[move] == YES)
     {
       phydbl scale;
       phydbl rate;
@@ -3579,8 +3785,8 @@ void MCMC_Adjust_Tuning_Parameter(int move, t_mcmc *mcmc)
 
       if(!strcmp(mcmc->move_name[move],"tree_height"))
 	{
-	  rate_inf = 0.1;
-	  rate_sup = 0.1;
+	  rate_inf = 0.234;
+	  rate_sup = 0.234;
 	}
       else if(!strcmp(mcmc->move_name[move],"subtree_height"))
 	{
@@ -3594,8 +3800,8 @@ void MCMC_Adjust_Tuning_Parameter(int move, t_mcmc *mcmc)
 	}
       else if(!strcmp(mcmc->move_name[move],"clock"))
 	{
-	  rate_inf = 0.1;
-	  rate_sup = 0.1;
+	  rate_inf = 0.234;
+	  rate_sup = 0.234;
 	}
 
       /* if(!strcmp(mcmc->move_name[move],"tree_rates")) */
@@ -3654,14 +3860,12 @@ void MCMC_Adjust_Tuning_Parameter(int move, t_mcmc *mcmc)
 
       if(mcmc->tune_move[move] > mcmc->max_tune) mcmc->tune_move[move] = mcmc->max_tune;
       if(mcmc->tune_move[move] < mcmc->min_tune) mcmc->tune_move[move] = mcmc->min_tune;
-	  
     }
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void MCMC_One_Length(t_edge *b, t_tree *tree)
 {
   phydbl u;
@@ -3676,7 +3880,7 @@ void MCMC_One_Length(t_edge *b, t_tree *tree)
   K            = 0.1;
   
   u = Uni();
-  mult = EXP(K*(u-0.5));
+  mult = exp(K*(u-0.5));
   /* mult = u*(K-1./K)+1./K; */
   new_l = cur_l * mult;
 
@@ -3690,10 +3894,10 @@ void MCMC_One_Length(t_edge *b, t_tree *tree)
 
   ratio =
     (new_lnL_data - cur_lnL_data) +
-    (LOG(mult));
+    (log(mult));
 
 
-  ratio = EXP(ratio);
+  ratio = exp(ratio);
   alpha = MIN(1.,ratio);
   
   u = Uni();
@@ -3739,9 +3943,9 @@ void MCMC_Scale_Br_Lens(t_tree *tree)
 
   ratio =
     (new_lnL_data - cur_lnL_data) +
-    (2*tree->n_otu-5) * (LOG(mult));
+    (2*tree->n_otu-5) * (log(mult));
 
-  ratio = EXP(ratio);
+  ratio = exp(ratio);
   alpha = MIN(1.,ratio);
   
   u = Uni();
@@ -3784,45 +3988,82 @@ void MCMC_Br_Lens_Pre(t_node *a, t_node *d, t_edge *b, t_tree *tree)
   if(d->tax) return;
   else 
     {
-      For(i,3) 
+      for(i=0;i<3;i++) 
 	if(d->v[i] != a)
 	  {
-	    Update_P_Lk(tree,d->b[i],d);
+	    Update_Partial_Lk(tree,d->b[i],d);
 	    MCMC_Br_Lens_Pre(d,d->v[i],d->b[i],tree);
 	  }
-      Update_P_Lk(tree,b,d);
+      Update_Partial_Lk(tree,b,d);
     }  
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
-
-void MCMC_Kappa(t_tree *tree)
+// Potentially one kappa parameter for each tree in a mixture -> update each of them
+void MCMC_Kappa(t_tree *mixt_tree)
 {
-  int change,i;
+  t_tree *tree;
+  phydbl cur_kappa,new_kappa;
+  phydbl u,alpha,ratio;
+  phydbl min_kappa,max_kappa;
+  phydbl K;
+  phydbl cur_lnL_data, new_lnL_data;
 
-  change = NO;
+  Switch_Eigen(YES,mixt_tree->mod);
 
-  Switch_Eigen(YES,tree->mod);
-		
-  if(tree->io->lk_approx == NORMAL)
+  tree = mixt_tree->next;
+  do
     {
-      tree->io->lk_approx = EXACT;
-      if(tree->mcmc->use_data == YES) Lk(NULL,tree);
-      change = YES;
+      if(tree->is_mixt_tree == YES) tree = tree->next;
+      
+      cur_kappa     = -1.0;
+      new_kappa     = -1.0;
+      ratio         =  0.0;
+      
+      K = mixt_tree->mcmc->tune_move[mixt_tree->mcmc->num_move_kappa];
+
+      cur_lnL_data = mixt_tree->c_lnL;
+      new_lnL_data = UNLIKELY;
+      
+      cur_kappa    = tree->mod->kappa->v;
+      
+      min_kappa = 0.1;
+      max_kappa = 10.;
+
+      MCMC_Make_Move(&cur_kappa,&new_kappa,min_kappa,max_kappa,&ratio,K,mixt_tree->mcmc->move_type[mixt_tree->mcmc->num_move_kappa]);
+      
+      if(new_kappa < max_kappa && new_kappa > min_kappa) 
+        {
+          tree->mod->kappa->v = new_kappa;
+          
+          new_lnL_data = Lk(NULL,mixt_tree);
+          
+          ratio += (new_lnL_data - cur_lnL_data);
+          
+          /* printf("\n. cur_k: %f new_k: %f cur: %f new: %f",cur_kappa,new_kappa,cur_lnL_data,new_lnL_data); */
+          
+          ratio = exp(ratio);
+          alpha = MIN(1.,ratio);
+          
+          u = Uni();
+          if(u > alpha) /* Reject */
+            {
+              tree->mod->kappa->v = cur_kappa;
+              mixt_tree->c_lnL    = cur_lnL_data;
+              Update_Eigen(mixt_tree->mod);
+            }
+          else
+            {
+              mixt_tree->mcmc->acc_move[mixt_tree->mcmc->num_move_kappa]++;
+            }
+        }
+      mixt_tree->mcmc->run_move[mixt_tree->mcmc->num_move_kappa]++;
+      tree = tree->next;
     }
+  while(tree != NULL);
   
-  For(i,2*tree->n_otu-2) tree->rates->br_do_updt[i] = NO;
-  MCMC_Single_Param_Generic(&(tree->mod->kappa->v),0.,100.,tree->mcmc->num_move_kappa,
-			    NULL,&(tree->c_lnL),
-			    NULL,Wrap_Lk,tree->mcmc->move_type[tree->mcmc->num_move_kappa],NO,NULL,tree,NULL);
-	  
-  if(change == YES)
-    {
-      tree->io->lk_approx = NORMAL;
-      if(tree->mcmc->use_data == YES) Lk(NULL,tree);
-    }
-  Switch_Eigen(NO,tree->mod);
+  Switch_Eigen(NO,mixt_tree->mod);
 }
 
 //////////////////////////////////////////////////////////////
@@ -3830,22 +4071,20 @@ void MCMC_Kappa(t_tree *tree)
 
 void MCMC_Rate_Across_Sites(t_tree *tree)
 {
+  int i;
+
   if(tree->mod->ras->n_catg == 1) return;
 
-  if(tree->mod->ras->free_mixt_rates == YES)
-    {
-      MCMC_Free_Mixt_Rate(tree);
-    }
-  else
+  for(i=0;i<tree->mod->ras->n_catg;i++)
     {
-      MCMC_Alpha(tree);
+      if(tree->mod->ras->free_mixt_rates == YES) MCMC_Free_Mixt_Rate(tree);
+      else                                       MCMC_Alpha(tree);
     }
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void MCMC_Alpha(t_tree *tree)
 {
   int i;
@@ -3859,11 +4098,9 @@ void MCMC_Alpha(t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void MCMC_Free_Mixt_Rate(t_tree *tree)
 {
   phydbl num,denom;
-  phydbl Jnow,Jthen;
   phydbl *z,*y;
   phydbl y_cur,z_cur;
   phydbl low_bound,up_bound;
@@ -3875,19 +4112,17 @@ void MCMC_Free_Mixt_Rate(t_tree *tree)
   phydbl cur_lnL_data, new_lnL_data;
   phydbl ratio,alpha;
   
+  tree->mod->ras->sort_rate_classes = YES;
+  tree->mod->ras->normalise_rr      = YES;
+
   cur_lnL_data = tree->c_lnL;
-  new_lnL_data = tree->c_lnL;
+  new_lnL_data = UNLIKELY;
 
   c = tree->mod->ras->n_catg;
 
   z = tree->mod->ras->gamma_rr_unscaled->v;
   y = tree->mod->ras->gamma_r_proba_unscaled->v;
 
-  num = z[c-1]*(y[c-1]-y[c-2]);
-  denom = z[0]*y[0];
-  for(i=1;i<c;i++) denom += z[i]*(y[i]-y[i-1]);
-  denom = POW(denom,c);
-  Jthen = num/denom;
 
   n_moves = 0;
   do
@@ -3897,51 +4132,44 @@ void MCMC_Free_Mixt_Rate(t_tree *tree)
       // Update frequencies
 
       // Choose the class freq to update at random.
-      c2updt = Rand_Int(0,c-2); 
-
+      // Last class never chosen and corresponding
+      // unscaled freq should always be equal to 1.0
+      c2updt = Rand_Int(0,c-1); 
+            
       // Proposal is uniform. Determine upper and lower bounds.
       u = Uni();
       low_bound = (c2updt==0)?(.0):(y[c2updt-1]);
-      up_bound = (c2updt==c-1)?(100.0):(y[c2updt+1]);
+      up_bound  = (c2updt==c-1)?(2.*y[c-2]):(y[c2updt+1]);
       y_cur = y[c2updt];
       y[c2updt] = low_bound + u*(up_bound - low_bound);
+            
+      // Hastings ratio
+      if(c2updt == c-1)
+        hr = POW(y_cur/y[c-1],c-1);
+      else
+        hr = 1.0;
       
-      // Calculate the Jacobian for the change of variable from unscaled 
-      // frequencies to the frequencies themselves.
-      num = z[c-1]*(y[c-1]-y[c-2]);
-      denom = z[0]*y[0];
-      for(i=1;i<c;i++) denom += z[i]*(y[i]-y[i-1]);
-      denom = POW(denom,c);
-      Jnow = num/denom;
- 
-      hr = Jnow/Jthen;
-
       new_lnL_data = Lk(NULL,tree);
 
       /* Metropolis-Hastings step */
       ratio = 0.;
-      if(tree->mcmc->use_data == YES) ratio += (new_lnL_data - cur_lnL_data);
-      ratio += LOG(hr);
-      ratio = EXP(ratio);
+      ratio += (new_lnL_data - cur_lnL_data);
+      ratio += log(hr);
+      ratio = exp(ratio);
       alpha = MIN(1.,ratio);
       
-      /* printf("\n. class=%d new_val=%f cur_val=%f ratio=%f hr=%f y=%f denom=%f",c2updt,y[c2updt],y_cur,ratio,Jthen/Jnow,y[c-1],denom); */
+      /* printf("\nf class=%d new_val=%f cur_val=%f cur: %f -> new: %f",c2updt,y[c2updt],y_cur,cur_lnL_data,new_lnL_data); */
 
       u = Uni();
       if(u > alpha) /* Reject */
  	{
 	  y[c2updt] = y_cur;
+          Update_RAS(tree->mod);
 	  tree->c_lnL = cur_lnL_data;
 	}
       else /* Accept */
 	{
 	  cur_lnL_data = new_lnL_data;
-	  /* Update the Jacobian */
-	  num = z[c-1]*(y[c-1]-y[c-2]);
-	  denom = z[0]*y[0];
-	  for(i=1;i<c;i++) denom += z[i]*(y[i]-y[i-1]);
-	  denom = POW(denom,c);
-	  Jthen = num/denom;
 	}
       
 
@@ -3949,70 +4177,61 @@ void MCMC_Free_Mixt_Rate(t_tree *tree)
 
       // Update rates
 
-      // Choose the class freq to update at random.
-      c2updt = Rand_Int(0,tree->mod->ras->n_catg-1);
+      // Choose the class unscaled rate to update at random.
+      // Last unscaled rate fixed to c throughout (hence c-2)      
+      c2updt = Rand_Int(0,c-1);
+      
+      denom = 0.0;
+      for(i=0;i<c;i++) denom += z[i]*y[i];
+      denom = POW(denom,c);
 
       // Proposal move.
       u = Uni();
-
-      /* K = tree->mcmc->tune_move[tree->mcmc->num_move_ras+c2updt+c]; */
-      /* z_cur = z[c2updt]; */
-      /* mult = EXP(K*(u-0.5)); */
-      /* z[c2updt] *= mult; */
-
-      u = Uni();
       low_bound = (c2updt==0)?(.0):(z[c2updt-1]);
-      up_bound = (c2updt==c-1)?(100.0):(z[c2updt+1]);
+      up_bound = (c2updt==c-1)?(2.*z[c2updt-2]):(z[c2updt+1]);
       z_cur = z[c2updt];
       z[c2updt] = low_bound + u*(up_bound - low_bound);
 
       
-      // Calculate the Jacobian for the change of variable from unscaled 
-      // frequencies to the frequencies themselves.
-      num = z[c-1]*(y[c-1]-y[c-2]);
-      denom = z[0]*y[0];
-      for(i=1;i<c;i++) denom += z[i]*(y[i]-y[i-1]);
-      denom = POW(denom,c);
-      Jnow = num/denom;
-
-      hr = Jnow/Jthen;
+      // Hastings ratio (remaining part)
+      num = 0.0;
+      for(i=0;i<c;i++) num += z[i]*y[i];
+      num = POW(num,c);
+      
+      hr = num/denom;
+      if(c2updt == c-1) hr *= z[c-1]/z_cur;
       
       new_lnL_data = Lk(NULL,tree);
 
       // Metropolis-Hastings step
       ratio = 0.;
-      if(tree->mcmc->use_data == YES) ratio += (new_lnL_data - cur_lnL_data);
-      ratio += LOG(hr);
-      /* ratio += LOG(mult); */
+      ratio += (new_lnL_data - cur_lnL_data);
+      ratio += log(hr);
 
-      ratio = EXP(ratio);
+      ratio = exp(ratio);
       alpha = MIN(1.,ratio);
 
+      /* printf("\nr class=%d new_val=%f cur_val=%f cur: %f -> new: %f",c2updt,y[c2updt],y_cur,cur_lnL_data,new_lnL_data); */
+
       u = Uni();
       if(u > alpha)
 	{
 	  z[c2updt] = z_cur;
+          Update_RAS(tree->mod);
 	  tree->c_lnL = cur_lnL_data;
 	}
       else
 	{
 	  cur_lnL_data = new_lnL_data;
-
-	  // Update the Jacobian
-	  num = z[c-1]*(y[c-1]-y[c-2]);
-	  denom = z[0]*y[0];
-	  for(i=1;i<c;i++) denom += z[i]*(y[i]-y[i-1]);
-	  denom = POW(denom,c);
-	  Jthen = num/denom;
 	}
 
-    }while(n_moves != c);
+    }
+  while(n_moves != c);
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void MCMC_Covarion_Rates(t_tree *tree)
 {
   int i, class;
@@ -4084,183 +4303,1711 @@ void MCMC_Covarion_Switch(t_tree *tree)
 
 void MCMC_Birth_Rate(t_tree *tree)
 {
+  /* 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); */
  
-  /* printf("\n. BIRTH cur_lnL_time: %f ",tree->rates->c_lnL_times); */
+  phydbl cur_birth_rate,new_birth_rate;
+  phydbl cur_lnL_time,new_lnL_time;
+  phydbl cur_lnL_time_ghost,new_lnL_time_ghost;
+  /* phydbl cur_lnL_time_pivot,new_lnL_time_pivot; */
+  phydbl u,alpha,ratio;
+  phydbl birth_rate_min,birth_rate_max;
+  phydbl K;
+  int i,n_mcmc_steps,move;
 
-#ifdef INVITEE
-  tree->rates->update_time_norm_const = YES;
-#endif
+  cur_birth_rate = -1.0;
+  new_birth_rate = -1.0;
+  ratio          =  0.0;
+  n_mcmc_steps   =  tree->mcmc->run_move[tree->mcmc->num_move_birth_rate] == 1 ? 1000 : 100;
+  move           = -1;
 
-  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); 
+  K = tree->mcmc->tune_move[tree->mcmc->num_move_birth_rate];
 
-#ifdef INVITEE
-  TIMES_Lk_Times(tree); 
-  tree->rates->update_time_norm_const = NO;
-#endif
+  cur_lnL_time = tree->rates->c_lnL_times;
+  new_lnL_time = tree->rates->c_lnL_times;
+
+  cur_lnL_time_ghost = UNLIKELY;
+  new_lnL_time_ghost = UNLIKELY;
+
+  /* cur_lnL_time_pivot = UNLIKELY; */
+  /* new_lnL_time_pivot = UNLIKELY; */
+
+  cur_birth_rate = tree->rates->birth_rate;
+
+  birth_rate_min = MAX(tree->rates->birth_rate_min,tree->rates->death_rate);
+  birth_rate_max = tree->rates->birth_rate_max;
+  
+  MCMC_Make_Move(&cur_birth_rate,&new_birth_rate,birth_rate_min,birth_rate_max,&ratio,K,tree->mcmc->move_type[tree->mcmc->num_move_birth_rate]);
+  /* new_birth_rate = Uni()*(birth_rate_max - birth_rate_min) + birth_rate_min; */
+  
+  if(new_birth_rate < birth_rate_max && new_birth_rate > birth_rate_min && new_birth_rate > tree->rates->death_rate)
+    {
+      tree->rates->birth_rate = new_birth_rate;
+      new_lnL_time = TIMES_Lk_Times(NO,tree);
+      ratio += (new_lnL_time - cur_lnL_time);
+      
+      if(tree->mcmc->run_move[tree->mcmc->num_move_birth_rate] == 500)
+        {
+          tree->rates->birth_rate_pivot = tree->rates->birth_rate;
+          tree->rates->death_rate_pivot = tree->rates->death_rate;
+        }
+      
+      if(tree->mcmc->run_move[tree->mcmc->num_move_birth_rate] >= 0)
+        {
+          /* if(tree->mcmc->run_move[tree->mcmc->num_move_birth_rate] >= 500) */
+          /*   { */
+          /*     tree->extra_tree->rates->birth_rate = tree->rates->birth_rate_pivot; */
+          /*     tree->extra_tree->rates->death_rate = tree->rates->death_rate_pivot; */
+          /*     cur_lnL_time_pivot = TIMES_Lk_Times(NO,tree->extra_tree); */
+          /*   } */
+          
+          /* tree->extra_tree->rates->birth_rate = cur_birth_rate; */
+          /* tree->extra_tree->rates->death_rate = tree->rates->death_rate; */
+          /* cur_lnL_time_ghost = TIMES_Lk_Times(NO,tree->extra_tree); */
+          
+          /* Copy_Tree(tree->extra_tree,tree->extra_tree->extra_tree); */
+          /* RATES_Copy_Rate_Struct(tree->extra_tree->rates,tree->extra_tree->extra_tree->rates,tree->n_otu); */
+          /* DATE_Assign_Primary_Calibration(tree->extra_tree->extra_tree); */
+          
+
+
+          tree->extra_tree->eval_alnL          = NO;
+          tree->extra_tree->eval_rlnL          = NO;
+          tree->extra_tree->eval_glnL          = YES;
+          tree->extra_tree->rates->birth_rate  = new_birth_rate;
+          tree->extra_tree->rates->c_lnL_rates = UNLIKELY;
+          tree->extra_tree->c_lnL              = UNLIKELY;
+          
+          TIMES_Randomize_Tree_With_Time_Constraints(tree->extra_tree->rates->a_cal[0],tree->extra_tree);
+          tree->extra_tree->rates->birth_rate = new_birth_rate;
+          tree->extra_tree->rates->death_rate = tree->rates->death_rate;
+          TIMES_Lk_Times(NO,tree->extra_tree);
+          
+          if(!(tree->extra_tree->rates->c_lnL_times > UNLIKELY))
+            {
+              PhyML_Printf("\n== glnL=%f",tree->extra_tree->rates->c_lnL_times);
+              PhyML_Printf("\n== birth=%G death=%G [%G]",new_birth_rate,tree->rates->death_rate,tree->extra_tree->rates->death_rate);
+              TIMES_Lk_Times(YES,tree->extra_tree);
+              Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
+            }
+          
+          i = 0;
+          do
+            {
+              u = Uni();
+              for(move=0;move<tree->mcmc->n_moves;move++) if(tree->mcmc->move_weight[move] > u-1.E-10) break;
+              
+              /* PhyML_Printf("\n<< Move '%s' %f",tree->mcmc->move_name[move],tree->extra_tree->rates->c_lnL_times); */
+              
+              if(!strcmp(tree->mcmc->move_name[move],"tree_height")) { MCMC_Tree_Height(tree->extra_tree); i++; }
+              if(!strcmp(tree->mcmc->move_name[move],"times"))       { MCMC_Times_All(tree->extra_tree); i++; }
+              if(!strcmp(tree->mcmc->move_name[move],"spr"))         { MCMC_Prune_Regraft(tree->extra_tree); i++; }
+              if(!strcmp(tree->mcmc->move_name[move],"spr_local"))   { MCMC_Prune_Regraft_Local(tree->extra_tree); i++; }
+              
+              if(!(tree->extra_tree->rates->c_lnL_times > UNLIKELY))
+                {
+                  PhyML_Printf("\n== move: %s",tree->mcmc->move_name[move]);
+                  PhyML_Printf("\n== glnL=%f",tree->extra_tree->rates->c_lnL_times);
+                  TIMES_Lk_Times(YES,tree->extra_tree);
+                  Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
+                }
+              /* PhyML_Printf("\n==> %4d %15f",i,tree->extra_tree->rates->c_lnL_times); */
+            }
+          while(i < n_mcmc_steps);
+          
+          tree->extra_tree->rates->birth_rate = cur_birth_rate;
+          tree->extra_tree->rates->death_rate = tree->rates->death_rate;
+          cur_lnL_time_ghost = TIMES_Lk_Times(NO,tree->extra_tree);
+
+          tree->extra_tree->rates->birth_rate = new_birth_rate;
+          tree->extra_tree->rates->death_rate = tree->rates->death_rate;
+          new_lnL_time_ghost = TIMES_Lk_Times(NO,tree->extra_tree);
+
+          ratio += (cur_lnL_time_ghost - new_lnL_time_ghost);
+
+          
+
+          /* if(tree->mcmc->run_move[tree->mcmc->num_move_birth_rate] >= 500) */
+          /*   { */
+          /*     tree->extra_tree->rates->birth_rate = tree->rates->birth_rate_pivot; */
+          /*     tree->extra_tree->rates->death_rate = tree->rates->death_rate_pivot; */
+          /*     new_lnL_time_pivot = TIMES_Lk_Times(NO,tree->extra_tree); */
+          /*     ratio += (new_lnL_time_pivot - cur_lnL_time_pivot); */
+          /*   } */
+        }
+      
+      ratio = exp(ratio);
+      alpha = MIN(1.,ratio);
+      
+      /* printf("\n.  b :%4d: %12G -> %12G ratio : %12G [ghost: %12G %12G -- real: %12G %12G]", */
+      /*        tree->mcmc->run_move[tree->mcmc->num_move_birth_rate], */
+      /*        cur_birth_rate, */
+      /*        new_birth_rate, */
+      /*        ratio, */
+      /*        cur_lnL_time_ghost, */
+      /*        new_lnL_time_ghost, */
+      /*        cur_lnL_time, */
+      /*        new_lnL_time); */
+            
+      u = Uni();
+      if(u > alpha) /* Reject */
+        {
+          /* PhyML_Printf("  reject"); */
+          tree->rates->birth_rate  = cur_birth_rate;
+          tree->rates->c_lnL_times = cur_lnL_time;
+
+          /* Copy_Tree(tree->extra_tree->extra_tree,tree->extra_tree); */
+          /* RATES_Copy_Rate_Struct(tree->extra_tree->extra_tree->rates,tree->extra_tree->rates,tree->n_otu); */
+          /* DATE_Assign_Primary_Calibration(tree->extra_tree); */
+        }
+      else
+        {
+          /* PhyML_Printf("  accept"); */
+          tree->mcmc->acc_move[tree->mcmc->num_move_birth_rate]++;
+        }
+    }
+  tree->mcmc->run_move[tree->mcmc->num_move_birth_rate]++;
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-void MCMC_Nu(t_tree *tree)
+void MCMC_Death_Rate(t_tree *tree)
 {
-  phydbl cur_nu,new_nu,cur_lnL_rate,new_lnL_rate;
+  
+  /* MCMC_Single_Param_Generic(&(tree->rates->death_rate), */
+  /*       		    0.0, // instead of tree->rates->death_rate_min as death rate can be equal to 0 (Yule model) */
+  /*       		    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); */
+ 
+  phydbl cur_death_rate,new_death_rate;
+  phydbl cur_lnL_time,new_lnL_time;
+  phydbl cur_lnL_time_ghost,new_lnL_time_ghost;
+  /* phydbl cur_lnL_time_pivot,new_lnL_time_pivot; */
   phydbl u,alpha,ratio;
-  phydbl min_nu,max_nu;
+  phydbl death_rate_min,death_rate_max;
   phydbl K;
-  phydbl cur_lnL_data, new_lnL_data;
-  int i;
+  int i,n_mcmc_steps,move;
+
+  cur_death_rate = -1.0;
+  new_death_rate = -1.0;
+  ratio          =  0.0;
+  n_mcmc_steps   =  tree->mcmc->run_move[tree->mcmc->num_move_death_rate] == 1 ? 1000 : 100;
+  move           = -1;
+
+  K = tree->mcmc->tune_move[tree->mcmc->num_move_death_rate];
+
+  cur_lnL_time = tree->rates->c_lnL_times;
+  new_lnL_time = tree->rates->c_lnL_times;
+
+  cur_lnL_time_ghost = UNLIKELY;
+  new_lnL_time_ghost = UNLIKELY;
+
+  /* cur_lnL_time_pivot = UNLIKELY; */
+  /* new_lnL_time_pivot = UNLIKELY; */
+  
+  cur_death_rate = tree->rates->death_rate;
+
+  death_rate_min = tree->rates->death_rate_min;
+  death_rate_max = MIN(tree->rates->death_rate_max,tree->rates->birth_rate);
+
+  MCMC_Make_Move(&cur_death_rate,&new_death_rate,death_rate_min,death_rate_max,&ratio,K,tree->mcmc->move_type[tree->mcmc->num_move_death_rate]);
+  /* new_death_rate = Uni()*(death_rate_max - death_rate_min) + death_rate_min; */
+  
+  if(new_death_rate < death_rate_max && new_death_rate > death_rate_min && new_death_rate < tree->rates->birth_rate)
+    {
+      tree->rates->death_rate = new_death_rate;
+      new_lnL_time = TIMES_Lk_Times(NO,tree);
+      ratio += (new_lnL_time - cur_lnL_time);
+
+      if(tree->mcmc->run_move[tree->mcmc->num_move_birth_rate] >= 0)
+        {
+          /* if(tree->mcmc->run_move[tree->mcmc->num_move_birth_rate] >= 500) */
+          /*   { */
+          /*     tree->extra_tree->rates->birth_rate = tree->rates->birth_rate_pivot; */
+          /*     tree->extra_tree->rates->death_rate = tree->rates->death_rate_pivot; */
+          /*     cur_lnL_time_pivot = TIMES_Lk_Times(NO,tree->extra_tree); */
+          /*   } */
+          
+          /* tree->extra_tree->rates->death_rate = cur_death_rate; */
+          /* tree->extra_tree->rates->birth_rate = tree->rates->birth_rate; */
+          /* cur_lnL_time_ghost = TIMES_Lk_Times(NO,tree->extra_tree); */
+          
+          /* Copy_Tree(tree->extra_tree,tree->extra_tree->extra_tree); */
+          /* RATES_Copy_Rate_Struct(tree->extra_tree->rates,tree->extra_tree->extra_tree->rates,tree->n_otu); */
+          /* DATE_Assign_Primary_Calibration(tree->extra_tree->extra_tree); */
+          
+
+
+          tree->extra_tree->eval_alnL          = NO;
+          tree->extra_tree->eval_rlnL          = NO;
+          tree->extra_tree->eval_glnL          = YES;
+          tree->extra_tree->rates->c_lnL_rates = UNLIKELY;
+          tree->extra_tree->c_lnL              = UNLIKELY;
+          
+          TIMES_Randomize_Tree_With_Time_Constraints(tree->extra_tree->rates->a_cal[0],tree->extra_tree);
+          tree->extra_tree->rates->birth_rate = tree->rates->birth_rate;
+          tree->extra_tree->rates->death_rate = new_death_rate;
+          TIMES_Lk_Times(NO,tree->extra_tree);
+          
+          if(!(tree->extra_tree->rates->c_lnL_times > UNLIKELY))
+            {
+              PhyML_Printf("\n== glnL=%f",tree->extra_tree->rates->c_lnL_times);
+              PhyML_Printf("\n== death=%G birth=%G [%G]",new_death_rate,tree->rates->birth_rate,tree->extra_tree->rates->birth_rate);
+              TIMES_Lk_Times(YES,tree->extra_tree);
+              Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
+            }
+                    
+          i = 0;
+          do
+            {
+              u = Uni();
+              for(move=0;move<tree->mcmc->n_moves;move++) if(tree->mcmc->move_weight[move] > u-1.E-10) break;
+              
+              /* PhyML_Printf("\n>> Move '%s' %f %f b:%f d:%f-%f", */
+              /*              tree->mcmc->move_name[move], */
+              /*              tree->extra_tree->rates->c_lnL_times, */
+              /*              tree->rates->c_lnL_times, */
+              /*              tree->rates->birth_rate, */
+              /*              cur_death_rate, */
+              /*              new_death_rate); */
+              
+              if(!strcmp(tree->mcmc->move_name[move],"tree_height")) { MCMC_Tree_Height(tree->extra_tree); i++; }
+              if(!strcmp(tree->mcmc->move_name[move],"times"))       { MCMC_Times_All(tree->extra_tree); i++; }
+              if(!strcmp(tree->mcmc->move_name[move],"spr"))         { MCMC_Prune_Regraft(tree->extra_tree); i++; }
+              if(!strcmp(tree->mcmc->move_name[move],"spr_local"))   { MCMC_Prune_Regraft_Local(tree->extra_tree); i++; }
+              
+              if(!(tree->extra_tree->rates->c_lnL_times > UNLIKELY))
+                {
+                  PhyML_Printf("\n== move: %s",tree->mcmc->move_name[move]);
+                  PhyML_Printf("\n== glnL=%f",tree->extra_tree->rates->c_lnL_times);
+                  TIMES_Lk_Times(YES,tree->extra_tree);
+                  Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
+                }
+            }
+          while(i < n_mcmc_steps);
+          
+          tree->extra_tree->rates->death_rate = cur_death_rate;
+          tree->extra_tree->rates->birth_rate = tree->rates->birth_rate;
+          cur_lnL_time_ghost = TIMES_Lk_Times(NO,tree->extra_tree);
+
+          tree->extra_tree->rates->birth_rate = tree->rates->birth_rate;
+          tree->extra_tree->rates->death_rate = new_death_rate;
+          new_lnL_time_ghost = TIMES_Lk_Times(NO,tree->extra_tree);
+
+          ratio += (cur_lnL_time_ghost - new_lnL_time_ghost);
+
+
+
+          
+          /* if(tree->mcmc->run_move[tree->mcmc->num_move_birth_rate] >= 500) */
+          /*   { */
+          /*     tree->extra_tree->rates->birth_rate = tree->rates->birth_rate_pivot; */
+          /*     tree->extra_tree->rates->death_rate = tree->rates->death_rate_pivot; */
+          /*     new_lnL_time_pivot = TIMES_Lk_Times(NO,tree->extra_tree); */
+          /*     ratio += (new_lnL_time_pivot - cur_lnL_time_pivot); */
+          /*   } */
+        }
+      
+      ratio = exp(ratio);
+      alpha = MIN(1.,ratio);
+      
+      /* printf("\n.  d :%4d: %12G -> %12G ratio : %12G [ghost: %12G %12G -- real: %12G %12G]", */
+      /*        tree->mcmc->run_move[tree->mcmc->num_move_death_rate], */
+      /*        cur_death_rate, */
+      /*        new_death_rate, */
+      /*        ratio, */
+      /*        cur_lnL_time_ghost, */
+      /*        new_lnL_time_ghost, */
+      /*        cur_lnL_time, */
+      /*        new_lnL_time); */
+
+
+      u = Uni();
+      if(u > alpha) /* Reject */
+        {
+          /* PhyML_Printf("  reject"); */
+          tree->rates->death_rate  = cur_death_rate;
+          tree->rates->c_lnL_times = cur_lnL_time;
+
+          /* Copy_Tree(tree->extra_tree->extra_tree,tree->extra_tree); */
+          /* RATES_Copy_Rate_Struct(tree->extra_tree->extra_tree->rates,tree->extra_tree->rates,tree->n_otu); */
+          /* DATE_Assign_Primary_Calibration(tree->extra_tree); */
+        }
+      else
+        {
+          /* PhyML_Printf("  accept"); */
+          tree->mcmc->acc_move[tree->mcmc->num_move_death_rate]++;
+        }
+    }
+  tree->mcmc->run_move[tree->mcmc->num_move_death_rate]++;
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void MCMC_Birth_Death_Updown(t_tree *tree)
+{ 
+  phydbl cur_death_rate,new_death_rate;
+  phydbl cur_birth_rate,new_birth_rate;
+  phydbl cur_lnL_time,new_lnL_time;
+  phydbl cur_lnL_time_ghost,new_lnL_time_ghost;
+  /* phydbl cur_lnL_time_pivot,new_lnL_time_pivot; */
+  phydbl u,alpha,ratio;
+  phydbl death_rate_min,death_rate_max;
+  phydbl birth_rate_min,birth_rate_max;
+  phydbl K,scale;
+  int i,n_mcmc_steps,move;
+
+  cur_death_rate = -1.0;
+  new_death_rate = -1.0;
+  cur_birth_rate = -1.0;
+  new_birth_rate = -1.0;
+  ratio          =  0.0;
+  n_mcmc_steps   =  tree->mcmc->run_move[tree->mcmc->num_move_birth_death_updown] == 1 ? 1000 : 100;
+  move           = -1;
+
+  K = tree->mcmc->tune_move[tree->mcmc->num_move_birth_death_updown];
+
+  cur_lnL_time = tree->rates->c_lnL_times;
+  new_lnL_time = tree->rates->c_lnL_times;
+
+  cur_lnL_time_ghost = UNLIKELY;
+  new_lnL_time_ghost = UNLIKELY;
+
+  /* cur_lnL_time_pivot = UNLIKELY; */
+  /* new_lnL_time_pivot = UNLIKELY; */
+  
+  cur_death_rate = tree->rates->death_rate;
+  cur_birth_rate = tree->rates->birth_rate;
+
+  death_rate_min = tree->rates->death_rate_min;
+  death_rate_max = tree->rates->death_rate_max;
+
+  birth_rate_min = tree->rates->birth_rate_min;
+  birth_rate_max = tree->rates->birth_rate_max;
+
+  scale = exp(K*(Uni()-.5));
+  new_birth_rate = cur_birth_rate * scale;
+  new_death_rate = cur_death_rate * scale;
+  ratio += 2.*log(scale);
+  
+  if(new_death_rate < death_rate_max && new_death_rate > death_rate_min &&
+     new_birth_rate < birth_rate_max && new_birth_rate > birth_rate_min &&
+     new_death_rate < new_birth_rate)
+    {
+      tree->rates->death_rate = new_death_rate;
+      tree->rates->birth_rate = new_birth_rate;      
+      new_lnL_time = TIMES_Lk_Times(NO,tree);
+      ratio += (new_lnL_time - cur_lnL_time);      
+
+      if(tree->mcmc->run_move[tree->mcmc->num_move_birth_rate] >= 0)
+        {
+          /* if(tree->mcmc->run_move[tree->mcmc->num_move_birth_rate] >= 500) */
+          /*   { */
+          /*     tree->extra_tree->rates->death_rate = tree->rates->death_rate_pivot; */
+          /*     tree->extra_tree->rates->birth_rate = tree->rates->birth_rate_pivot; */
+          /*     cur_lnL_time_pivot = TIMES_Lk_Times(NO,tree->extra_tree); */
+          /*   } */
+          
+          /* tree->extra_tree->rates->death_rate = cur_death_rate; */
+          /* tree->extra_tree->rates->birth_rate = cur_birth_rate; */
+          /* cur_lnL_time_ghost = TIMES_Lk_Times(NO,tree->extra_tree); */
+          
+          /* Copy_Tree(tree->extra_tree,tree->extra_tree->extra_tree); */
+          /* RATES_Copy_Rate_Struct(tree->extra_tree->rates,tree->extra_tree->extra_tree->rates,tree->n_otu); */
+          /* DATE_Assign_Primary_Calibration(tree->extra_tree->extra_tree); */
+          
+
+
+          tree->extra_tree->eval_alnL          = NO;
+          tree->extra_tree->eval_rlnL          = NO;
+          tree->extra_tree->eval_glnL          = YES;
+          tree->extra_tree->rates->c_lnL_rates = UNLIKELY;
+          tree->extra_tree->c_lnL              = UNLIKELY;
+          
+          TIMES_Randomize_Tree_With_Time_Constraints(tree->extra_tree->rates->a_cal[0],tree->extra_tree);
+          tree->extra_tree->rates->death_rate = new_death_rate;
+          tree->extra_tree->rates->birth_rate = new_birth_rate;
+          TIMES_Lk_Times(NO,tree->extra_tree);
+          
+          if(!(tree->extra_tree->rates->c_lnL_times > UNLIKELY))
+            {
+              PhyML_Printf("\n== glnL=%f",tree->extra_tree->rates->c_lnL_times);
+              PhyML_Printf("\n== death=%G birth=%G [%G]",new_death_rate,tree->rates->birth_rate,tree->extra_tree->rates->birth_rate);
+              TIMES_Lk_Times(YES,tree->extra_tree);
+              Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
+            }
+          
+          
+          i = 0;
+          do
+            {
+              u = Uni();
+              for(move=0;move<tree->mcmc->n_moves;move++) if(tree->mcmc->move_weight[move] > u-1.E-10) break;
+              
+              /* PhyML_Printf("\n>> Move '%s' %f %f b:%f d:%f-%f", */
+              /*              tree->mcmc->move_name[move], */
+              /*              tree->extra_tree->rates->c_lnL_times, */
+              /*              tree->rates->c_lnL_times, */
+              /*              tree->rates->birth_rate, */
+              /*              cur_death_rate, */
+              /*              new_death_rate); */
+              
+              if(!strcmp(tree->mcmc->move_name[move],"tree_height")) { MCMC_Tree_Height(tree->extra_tree); i++; }
+              if(!strcmp(tree->mcmc->move_name[move],"times"))       { MCMC_Times_All(tree->extra_tree); i++; }
+              if(!strcmp(tree->mcmc->move_name[move],"spr"))         { MCMC_Prune_Regraft(tree->extra_tree); i++; }
+              if(!strcmp(tree->mcmc->move_name[move],"spr_local"))   { MCMC_Prune_Regraft_Local(tree->extra_tree); i++; }
+              
+              if(!(tree->extra_tree->rates->c_lnL_times > UNLIKELY))
+                {
+                  PhyML_Printf("\n== move: %s",tree->mcmc->move_name[move]);
+                  PhyML_Printf("\n== glnL=%f",tree->extra_tree->rates->c_lnL_times);
+                  TIMES_Lk_Times(YES,tree->extra_tree);
+                  Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
+                }
+            }
+          while(i < n_mcmc_steps);
+          
+          tree->extra_tree->rates->death_rate = cur_death_rate;
+          tree->extra_tree->rates->birth_rate = cur_birth_rate;
+          cur_lnL_time_ghost = TIMES_Lk_Times(NO,tree->extra_tree);
+
+          tree->extra_tree->rates->death_rate = new_death_rate;
+          tree->extra_tree->rates->birth_rate = new_birth_rate;
+          new_lnL_time_ghost = TIMES_Lk_Times(NO,tree->extra_tree);
+
+          ratio += (cur_lnL_time_ghost - new_lnL_time_ghost);
+
+          
+          
+          /* if(tree->mcmc->run_move[tree->mcmc->num_move_birth_rate] == 500) */
+          /*   { */
+          /*     tree->extra_tree->rates->death_rate = tree->rates->death_rate_pivot; */
+          /*     tree->extra_tree->rates->birth_rate = tree->rates->birth_rate_pivot; */
+          /*     new_lnL_time_pivot = TIMES_Lk_Times(NO,tree->extra_tree); */
+          /*     ratio += (new_lnL_time_pivot - cur_lnL_time_pivot); */
+          /*   } */
+        }
+      
+      ratio = exp(ratio);
+      alpha = MIN(1.,ratio);
+      
+      /* printf("\n. bd :%4d: %12G -> %12G ratio : %12G [ghost: %12G %12G -- real: %12G %12G]", */
+      /*        tree->mcmc->run_move[tree->mcmc->num_move_birth_death_updown], */
+      /*        cur_death_rate, */
+      /*        new_death_rate, */
+      /*        ratio, */
+      /*        cur_lnL_time_ghost, */
+      /*        new_lnL_time_ghost, */
+      /*        cur_lnL_time, */
+      /*        new_lnL_time); */
+      
+      
+      u = Uni();
+      if(u > alpha) /* Reject */
+        {
+          /* PhyML_Printf("  reject"); */
+          tree->rates->death_rate  = cur_death_rate;
+          tree->rates->birth_rate  = cur_birth_rate;
+          tree->rates->c_lnL_times = cur_lnL_time;
+
+          /* Copy_Tree(tree->extra_tree->extra_tree,tree->extra_tree); */
+          /* RATES_Copy_Rate_Struct(tree->extra_tree->extra_tree->rates,tree->extra_tree->rates,tree->n_otu); */
+          /* DATE_Assign_Primary_Calibration(tree->extra_tree); */
+        }
+      else
+        {
+          /* PhyML_Printf("  accept"); */
+          tree->mcmc->acc_move[tree->mcmc->num_move_birth_death_updown]++;
+        }
+    }
+  tree->mcmc->run_move[tree->mcmc->num_move_birth_death_updown]++;
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void MCMC_Nu(t_tree *tree)
+{
+  phydbl cur_nu,new_nu,cur_lnL_rate,new_lnL_rate;
+  phydbl u,alpha,ratio;
+  phydbl min_nu,max_nu;
+  phydbl K;
+  phydbl cur_lnL_data, new_lnL_data;
+  int i;
+
+  Record_Br_Len(tree);
+
+  cur_nu        = -1.0;
+  new_nu        = -1.0;
+  ratio         =  0.0;
+
+  K = tree->mcmc->tune_move[tree->mcmc->num_move_nu];
+
+  cur_lnL_rate = tree->rates->c_lnL_rates;
+  new_lnL_rate = tree->rates->c_lnL_rates;
+
+  cur_lnL_data = tree->c_lnL;
+  new_lnL_data = tree->c_lnL;
+  
+  cur_nu       = tree->rates->nu;
+
+  min_nu = tree->rates->min_nu;
+  max_nu = tree->rates->max_nu;
+
+  MCMC_Make_Move(&cur_nu,&new_nu,min_nu,max_nu,&ratio,K,tree->mcmc->move_type[tree->mcmc->num_move_nu]);
+  
+  if(new_nu < max_nu && new_nu > min_nu) 
+    {
+      tree->rates->nu = new_nu;
+      
+      new_lnL_rate = RATES_Lk_Rates(tree);      
+
+      if(tree->rates->model == GUINDON)
+	{
+	  For(i,2*tree->n_otu-2) tree->rates->br_do_updt[i] = YES;
+	  new_lnL_data = Lk(NULL,tree);
+	}
+      
+      ratio +=
+      	(new_lnL_rate - cur_lnL_rate);
+
+      ratio +=
+	(new_lnL_data - cur_lnL_data);
+
+
+      /* !!!!!!!!!!!!!!!! */
+      /* Modelling exp(nu) and making move on nu */
+      /* ratio += (new_nu - cur_nu); */
+	 
+      /* Exponential prior on nu */
+      /* ratio += log(Dexp(new_nu,10.) / Dexp(cur_nu,10.)); */
+
+ 
+      ratio = exp(ratio);
+      alpha = MIN(1.,ratio);
+      
+      u = Uni();
+      if(u > alpha) /* Reject */
+	{
+	  tree->rates->nu    = cur_nu;
+	  tree->rates->c_lnL_rates = cur_lnL_rate;
+	  tree->c_lnL        = cur_lnL_data;
+	  Restore_Br_Len(tree);
+	}
+      else
+	{
+	  tree->mcmc->acc_move[tree->mcmc->num_move_nu]++;
+	}
+    }
+  tree->mcmc->run_move[tree->mcmc->num_move_nu]++;
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void MCMC_All_Rates(t_tree *tree)
+{
+  phydbl cur_lnL_data, new_lnL_data, cur_lnL_rate;
+  phydbl u, ratio, alpha;
+
+  new_lnL_data = tree->c_lnL;
+  cur_lnL_data = tree->c_lnL;
+  cur_lnL_rate = tree->rates->c_lnL_rates;
+  ratio        = 0.0;
+  
+  Record_Br_Len(tree);
+  RATES_Record_Rates(tree);
+  
+  MCMC_Sim_Rate(tree->n_root,tree->n_root->v[2],tree);
+  MCMC_Sim_Rate(tree->n_root,tree->n_root->v[1],tree);
+
+  new_lnL_data = Lk(NULL,tree);
+  
+  ratio += (new_lnL_data - cur_lnL_data);
+  ratio = exp(ratio);
+
+  alpha = MIN(1.,ratio);
+  u = Uni();
+
+  if(u > alpha) /* Reject */
+    {
+      Restore_Br_Len(tree);
+      RATES_Reset_Rates(tree);
+      tree->rates->c_lnL_rates = cur_lnL_rate;
+    }
+  else
+    {
+      tree->rates->c_lnL_rates = RATES_Lk_Rates(tree);;
+    }
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+
+/* Only works when simulating from prior */
+void MCMC_Sim_Rate(t_node *a, t_node *d, t_tree *tree)
+{
+  int err;
+  phydbl mean,sd,br_r_a,dt_d;
+
+  br_r_a = tree->rates->br_r[a->num];
+  dt_d   = tree->rates->nd_t[d->num] - tree->rates->nd_t[a->num];
+  sd     = SQRT(dt_d*tree->rates->nu);
+  
+  if(tree->rates->model_log_rates == YES)
+    {
+      mean = br_r_a - .5*sd*sd;
+    }
+  else
+    {
+      mean = br_r_a;
+    }
+      
+  if(tree->rates->model == STRICTCLOCK) tree->rates->br_r[d->num] = 1.0;
+  else
+    tree->rates->br_r[d->num] = Rnorm_Trunc(mean,sd,tree->rates->min_rate,tree->rates->max_rate,&err);
+
+  if(d->tax) return;
+  else
+    {
+      int i;
+
+      for(i=0;i<3;i++)
+	if(d->v[i] != a && d->b[i] != tree->e_root)
+	  MCMC_Sim_Rate(d,d->v[i],tree);
+    }
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void MCMC_Prune_Regraft(t_tree *tree)
+{
+  phydbl u,alpha,ratio;
+  phydbl t_min,t_max;
+  phydbl cur_lnL_seq,new_lnL_seq;
+  phydbl cur_lnL_rate,new_lnL_rate;
+  phydbl cur_lnL_time,new_lnL_time;
+  phydbl new_t;
+  int i,prune_idx,n_iter,n_regraft_nd,regraft_idx,dir_prune;
+  phydbl *times;
+  int rnd_dir,dir_v1,dir_v2;
+  t_node *prune,*prune_daughter,*new_regraft_nd,*cur_regraft_nd;
+  t_ll *regraft_nd_list;
+  t_edge *target, *ori_target, *residual,*regraft_edge;
+  phydbl regraft_t_min,regraft_t_max;
+  /* phydbl *prob_idx; */
+  /* phydbl r,sum,prob_select_fwd,prob_select_bwd; */
+  
+  n_iter = MAX(1,(int)(tree->n_otu/5));
+  /* n_iter = tree->n_otu-2; */
+  times = tree->rates->nd_t;
+
+  /* prob_idx = (phydbl *)mCalloc(tree->n_otu-1,sizeof(phydbl)); */
+
+  // Shallowest node has probability proportional to r to be
+  // to be selected as prune node while deepest a proba prop to 1.
+  /* r = 0.5; */
+  /* for(i=0;i<tree->n_otu-1;i++) prob_idx[i] = i*(r-1.0)/(tree->n_otu-2) + 1.0; */
+
+  /* sum = .0; */
+  /* for(i=0;i<tree->n_otu-1;i++) sum += prob_idx[i]; */
+  /* for(i=0;i<tree->n_otu-1;i++) prob_idx[i] /= sum; */
+
+  
+  while(n_iter--)
+    {
+      TIMES_Update_Node_Ordering(tree);
+      
+      tree->mcmc->run_move[tree->mcmc->num_move_spr]++;
+      
+      RATES_Record_Times(tree);
+      
+      cur_lnL_seq  = tree->c_lnL;
+      new_lnL_seq  = UNLIKELY;
+      cur_lnL_rate = tree->rates->c_lnL_rates;
+      new_lnL_rate = UNLIKELY;
+      cur_lnL_time = tree->rates->c_lnL_times;
+      new_lnL_time = UNLIKELY;
+
+      ratio          = 0.0;
+      regraft_edge   = NULL;
+      new_regraft_nd = NULL;
+      cur_regraft_nd = NULL;
+      new_t          = 0.0;
+
+      // Select prune node (any internal node)
+      prune_idx = Rand_Int(tree->n_otu,2*tree->n_otu-2);
+
+      /* prune_idx = Sample_i_With_Proba_pi(prob_idx,tree->n_otu-1); */
+      /* prob_select_fwd = prob_idx[prune_idx]; */
+      /* ratio -= log(prob_select_fwd); */
+      /* prune_idx = tree->rates->t_rank[prune_idx]; */
+      
+      prune = tree->a_nodes[prune_idx];
+
+      
+      assert(prune && prune->tax == NO);
+
+      // Select a daughter of prune node
+      dir_v1 = dir_v2 = -1;
+      for(i=0;i<3;i++) 
+        if(prune->v[i] != prune->anc && prune->b[i] != tree->e_root)
+          {
+            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];
+      cur_regraft_nd = prune->v[rnd_dir == dir_v1 ? dir_v2 : dir_v1];            
+
+      if(prune == tree->n_root)
+        {
+          if(prune_daughter == prune->v[dir_v1] && prune->v[dir_v2]->tax == YES)
+            {
+              prune_daughter = prune->v[dir_v2];
+              cur_regraft_nd = prune->v[dir_v1];
+            }
+
+          if(prune_daughter == prune->v[dir_v2] && prune->v[dir_v1]->tax == YES)
+            {
+              prune_daughter = prune->v[dir_v1];
+              cur_regraft_nd = prune->v[dir_v2];
+            }
+        }
+           
+      assert(prune_daughter->anc == prune);
+
+      dir_prune = -1;
+      for(i=0;i<3;i++)
+        {
+          if(prune_daughter->v[i] == prune || prune_daughter->b[i] == tree->e_root)
+            {
+              dir_prune = i;
+              break;
+            }
+        }
+      assert(dir_prune > -1);
+            
+
+      // Get the list of potential regraft nodes (oldest node on regraft edge)
+      regraft_nd_list = DATE_List_Of_Regraft_Nodes(prune_daughter->v[dir_prune],prune_daughter,&regraft_t_min,&regraft_t_max,NO,tree);
+      assert(regraft_nd_list);
+      if(prune == tree->n_root) Push_Bottom_Linked_List(prune,&regraft_nd_list,YES);
+
+      // Number of regraft nodes
+      n_regraft_nd = Linked_List_Len(regraft_nd_list);
+
+      if(!(n_regraft_nd > 0)) // Should be at least 1, since original graft site is in the list
+        {
+          printf("\n\n. prune: %d [%d-%d-%d] [%s-%s-%s] [%f-%f;%f] prune_daughter: %d [%f-%f;%f] prune->anc: %d [%f-%f;%f] effective: %d glnL: %f",
+                 prune->num,
+                 prune->v[0] ? prune->v[0]->num : -1,
+                 prune->v[1]->num,
+                 prune->v[2]->num,
+                 prune->v[0] ? prune->v[0]->tax ? prune->v[0]->name : "XXX" : "XXX",
+                 prune->v[1]->tax ? prune->v[1]->name : "XXX",
+                 prune->v[2]->tax ? prune->v[2]->name : "XXX",
+                 tree->rates->nd_t[prune->num],
+                 tree->rates->t_prior_min[prune->num],
+                 tree->rates->t_prior_max[prune->num],
+                 prune_daughter->num,
+                 tree->rates->nd_t[prune_daughter->num],
+                 tree->rates->t_prior_min[prune_daughter->num],
+                 tree->rates->t_prior_max[prune_daughter->num],
+                 prune->anc ? prune->anc->num : -1,
+                 prune->anc ? tree->rates->nd_t[prune->anc->num] : -1,
+                 prune->anc ? tree->rates->t_prior_min[prune->anc->num] : -1,
+                 prune->anc ? tree->rates->t_prior_max[prune->anc->num] : -1,
+                 prune_daughter->v[dir_prune]->num,
+                 tree->rates->c_lnL_times); fflush(NULL);
+
+          regraft_nd_list = DATE_List_Of_Regraft_Nodes(prune_daughter->v[dir_prune],prune_daughter,&regraft_t_min,&regraft_t_max,YES,tree);
+
+          assert(FALSE);
+        }
+      
+      // Randomly select one (uniform)
+      regraft_idx = Rand_Int(0,n_regraft_nd-1);      
+      new_regraft_nd = Linked_List_Elem(regraft_idx,regraft_nd_list);      
+      Free_Linked_List(regraft_nd_list);
+            
+      // Time of regraft node and corresponding (partial) Hastings ratio
+      t_max = MIN(times[prune_daughter->num],times[cur_regraft_nd->num]);      
+      if(prune == tree->n_root) t_min = 10.0*t_max;
+      else t_min = times[prune->anc->num];
+      t_min = MAX(t_min,regraft_t_min);
+      ratio += log(1./(t_max - t_min));
+
+      t_max = MIN(times[prune_daughter->num],times[new_regraft_nd->num]);      
+      if(new_regraft_nd == tree->n_root) t_min = 10.0*t_max;
+      else t_min = times[new_regraft_nd->anc->num];
+      t_min = MAX(t_min,regraft_t_min);
+      ratio -= log(1./(t_max - t_min));
+      
+      new_t = Uni()*(t_max-t_min) + t_min;
+
+      // Age of root node changes when pruned subtree is on one side of that node
+      // Change here, not after the prune and regraft move
+      /* if(prune == tree->n_root) */
+      /*   { */
+      /*     if(prune_daughter == tree->n_root->v[1]) */
+      /*       times[tree->n_root->num] = times[tree->n_root->v[2]->num]; */
+      /*     else if(prune_daughter == tree->n_root->v[2]) */
+      /*       times[tree->n_root->num] = times[tree->n_root->v[1]->num]; */
+      /*     else assert(false); */
+      /*   } */
+      
+          
+      // New age
+      if(prune == tree->n_root || new_regraft_nd == tree->n_root)
+        {
+          if(prune == tree->n_root)
+            {
+              if(prune_daughter == tree->n_root->v[1]) times[tree->n_root->num] = times[tree->n_root->v[2]->num];
+              else                                     times[tree->n_root->num] = times[tree->n_root->v[1]->num];
+              times[prune_daughter->v[dir_prune]->num] = new_t;
+            }
+          if(new_regraft_nd == tree->n_root)
+            {
+              times[prune_daughter->v[dir_prune]->num] = times[tree->n_root->num];
+              times[tree->n_root->num] = new_t;
+            }
+        }
+      else
+        {
+          times[prune->num] = new_t;
+        }
+
+
+      // Prune
+      target = residual = NULL;
+      Prune_Subtree(prune_daughter->v[dir_prune],
+                    prune_daughter,
+                    &target,&residual,tree);
+      ori_target = target;
+      
+
+      // Regraft edge is the one sitting above regraft_nd
+      if(new_regraft_nd == tree->n_root->v[1] ||
+         new_regraft_nd == tree->n_root->v[2] ||
+         new_regraft_nd == tree->n_root) regraft_edge = tree->e_root;
+      else
+        {
+          for(i=0;i<3;i++) if(new_regraft_nd->v[i] == new_regraft_nd->anc) break;
+          assert(i!=3);
+          regraft_edge = new_regraft_nd->b[i];
+        }
+
+      assert(regraft_edge);      
+      
+
+      // Regraft
+      Graft_Subtree(regraft_edge,
+                    prune_daughter->v[dir_prune],
+                    prune_daughter,
+                    residual,
+                    new_regraft_nd,tree);
+      
+
+
+      /* TIMES_Update_Node_Ordering(tree); */
+      /* For(i,2*tree->n_otu-2) if(prune->num == tree->rates->t_rank[i]) break; */
+      /* prob_select_bwd = prob_idx[i]; */
+      /* ratio += log(prob_select_bwd); */
+
+
+
+      if(!TIMES_Check_Node_Height_Ordering(tree))
+        {
+          printf("\n== prune[%d]->t:%.3f daughter[%d]->t:%.3f prune_anc[%d]->t:%.3f regraft[%d]->t:%.3f regraft_anc[%d]->t:%.3f [effective:%d] t_prior_min/max: [prune:[%.3f %.3f] regraft:[%.3f %.3f]] ",
+                 prune->num,
+                 times[prune->num],
+                 prune_daughter->num,
+                 times[prune_daughter->num],
+                 prune->anc ? prune->anc->num : -1,
+                 prune->anc ? times[prune->anc->num] : -1.,
+                 new_regraft_nd->num,
+                 times[new_regraft_nd->num],
+                 new_regraft_nd->anc ? new_regraft_nd->anc->num : -1,
+                 new_regraft_nd->anc ? times[new_regraft_nd->anc->num] : +1.,
+                 prune->num,
+                 tree->rates->t_prior_min[prune->num],
+                 tree->rates->t_prior_max[prune->num],
+                 tree->rates->t_prior_min[new_regraft_nd->num],
+                 tree->rates->t_prior_max[new_regraft_nd->num]);
+          PhyML_Printf("\n== root: %d %d %d",tree->n_root->num,tree->n_root->v[1]->num,tree->n_root->v[2]->num);
+          Generic_Exit(__FILE__,__LINE__,__FUNCTION__);    
+        }
+
+      DATE_Assign_Primary_Calibration(tree);
+      new_lnL_time = TIMES_Lk_Times(NO,tree); 
+
+      if(new_lnL_time > UNLIKELY)
+        {
+          Set_Both_Sides(NO,tree);
+          new_lnL_seq = Lk(NULL,tree);
+          new_lnL_rate = RATES_Lk_Rates(tree);
+        }
+      
+      ratio += (new_lnL_seq - cur_lnL_seq);
+      ratio += (new_lnL_rate - cur_lnL_rate);
+      ratio += (new_lnL_time - cur_lnL_time);
+
+
+      
+      ratio = exp(ratio);
+      alpha = MIN(1.,ratio);
+
+
+
+      /* Always accept move */
+      if(tree->mcmc->always_yes == YES && new_lnL_time > UNLIKELY) alpha = 1.0;
+      
+      u = Uni();
+
+      if(u > alpha)
+        {
+          // Reject
+          Prune_Subtree(prune_daughter->v[dir_prune],
+                        prune_daughter,
+                        &target,&residual,tree);
+          Graft_Subtree(ori_target,
+                        prune_daughter->v[dir_prune],
+                        prune_daughter,residual,prune == tree->n_root ? tree->n_root : cur_regraft_nd,tree);
+
+          RATES_Reset_Times(tree);
+          RATES_Update_Cur_Bl(tree);
+          DATE_Assign_Primary_Calibration(tree);
+          TIMES_Lk_Times(NO,tree); 
+
+          
+          if(!(tree->rates->c_lnL_times > UNLIKELY))
+            {
+              printf("\n== time prune: %f",times[prune->num]);
+              printf("\n== time prune_daughter: %f",times[prune_daughter->num]);
+              printf("\n== prune: %d prune_daughter: %d prune_daughter->v[dir_prune]: %d cur_regraft_nd: %d new_regraft_nd: %d",
+                     prune->num,
+                     prune_daughter->num,
+                     prune_daughter->v[dir_prune]->num,
+                     cur_regraft_nd->num,
+                     new_regraft_nd->num);
+              TIMES_Lk_Times(YES,tree); 
+              fflush(NULL);
+            }
+          assert(tree->rates->c_lnL_times > UNLIKELY);
+          
+          tree->c_lnL              = cur_lnL_seq;
+          tree->rates->c_lnL_times = cur_lnL_time;
+          tree->rates->c_lnL_rates = cur_lnL_rate;
+        }
+      else
+        {
+          tree->mcmc->acc_move[tree->mcmc->num_move_spr]++;
+        }      
+    }
+  /* Free(prob_idx); */
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void MCMC_Prune_Regraft_Weighted(t_tree *tree)
+{
+  phydbl u,alpha,ratio;
+  phydbl cur_lnL_seq,new_lnL_seq;
+  phydbl cur_lnL_rate,new_lnL_rate;
+  phydbl cur_lnL_time,new_lnL_time;  
+  phydbl new_t;
+  int i,prune_idx,n_iter,dir_prune;
+  phydbl *times;
+  int rnd_dir,dir_v1,dir_v2;
+  t_node *prune,*prune_daughter,*new_regraft_nd,*cur_regraft_nd;
+  t_edge *target, *ori_target, *residual,*regraft_edge;
+  phydbl radius;
+  
+  n_iter = MAX(1,(int)(tree->n_otu/5));
+  times  = tree->rates->nd_t;
+  
+  while(n_iter--)
+    {      
+      tree->mcmc->run_move[tree->mcmc->num_move_spr_weighted]++;
+      
+      RATES_Record_Times(tree);
+      
+      cur_lnL_seq  = tree->c_lnL;
+      new_lnL_seq  = UNLIKELY;
+      cur_lnL_rate = tree->rates->c_lnL_rates;
+      new_lnL_rate = UNLIKELY;
+      cur_lnL_time = tree->rates->c_lnL_times;
+      new_lnL_time = UNLIKELY;
+
+      ratio          = 0.0;
+      regraft_edge   = NULL;
+      new_regraft_nd = NULL;
+      cur_regraft_nd = NULL;
+      new_t          = 0.0;
+
+      // Select prune node (any internal node)
+      prune_idx = Rand_Int(tree->n_otu,2*tree->n_otu-2);      
+      prune = tree->a_nodes[prune_idx];
+
+      assert(prune && prune->tax == NO);
+
+      // Select a daughter of prune node
+      dir_v1 = dir_v2 = -1;
+      for(i=0;i<3;i++) 
+        if(prune->v[i] != prune->anc && prune->b[i] != tree->e_root)
+          {
+            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];
+      cur_regraft_nd = prune->v[rnd_dir == dir_v1 ? dir_v2 : dir_v1];            
+
+      if(prune == tree->n_root)
+        {
+          if(prune_daughter == prune->v[dir_v1] && prune->v[dir_v2]->tax == YES)
+            {
+              prune_daughter = prune->v[dir_v2];
+              cur_regraft_nd = prune->v[dir_v1];
+            }
+
+          if(prune_daughter == prune->v[dir_v2] && prune->v[dir_v1]->tax == YES)
+            {
+              prune_daughter = prune->v[dir_v1];
+              cur_regraft_nd = prune->v[dir_v2];
+            }
+        }
+           
+      assert(prune_daughter->anc == prune);
+
+      dir_prune = -1;
+      for(i=0;i<3;i++)
+        {
+          if(prune_daughter->v[i] == prune || prune_daughter->b[i] == tree->e_root)
+            {
+              dir_prune = i;
+              break;
+            }
+        }
+      assert(dir_prune > -1);
+            
+      
+      
+      radius = Rnorm(0.0,0.05);
+      radius = FABS(radius);
+      radius += tree->rates->cur_l[prune_daughter->num]; // valid too when prune == tree->n_root
+      
+      /* printf("\n. radius: %f %p %p %p", */
+      /*        radius, */
+      /*        prune_daughter, */
+      /*        prune_daughter->v[dir_prune],                                        */
+      /*        prune_daughter->b[dir_prune]); */
+      /* fflush(NULL); */
+      
+      // Get the list of potential regraft nodes (oldest node on regraft edge)
+      Random_Walk_Along_Tree_On_Radius(prune_daughter,
+                                       prune_daughter->v[dir_prune],                                       
+                                       prune_daughter->b[dir_prune],
+                                       &radius,
+                                       &regraft_edge,
+                                       &new_regraft_nd,
+                                       &new_t,
+                                       tree);
+      
+      /* printf("\n. new_regraft_edge: %d, new_regraft_nd: %d time: %f K: %f cur_regraft_nd: %d", */
+      /*        regraft_edge ? regraft_edge->num : -1, */
+      /*        new_regraft_nd ? new_regraft_nd->num : -1, */
+      /*        new_t,K, */
+      /*        cur_regraft_nd->num, */
+      /*        prune->num, */
+      /*        prune_daughter->num); fflush(NULL); */
+
+      if(new_regraft_nd == NULL) continue;
+      if(new_regraft_nd == prune) continue;
+      if(new_regraft_nd == cur_regraft_nd) continue;
+      if(new_t > times[prune_daughter->num]) continue;
+      
+          
+      // New age
+      if(prune == tree->n_root || new_regraft_nd == tree->n_root)
+        {
+          if(prune == tree->n_root)
+            {
+              if(prune_daughter == tree->n_root->v[1]) times[tree->n_root->num] = times[tree->n_root->v[2]->num];
+              else                                     times[tree->n_root->num] = times[tree->n_root->v[1]->num];
+              times[prune_daughter->v[dir_prune]->num] = new_t;
+            }
+          if(new_regraft_nd == tree->n_root)
+            {
+              times[prune_daughter->v[dir_prune]->num] = times[tree->n_root->num];
+              times[tree->n_root->num] = new_t;
+            }
+        }
+      else
+        {
+          times[prune->num] = new_t;
+        }
+
+
+      // Prune
+      target = residual = NULL;
+      Prune_Subtree(prune_daughter->v[dir_prune],
+                    prune_daughter,
+                    &target,&residual,tree);
+      ori_target = target;
+      
+
+      // Regraft edge is the one sitting above regraft_nd
+      if(new_regraft_nd == tree->n_root->v[1] ||
+         new_regraft_nd == tree->n_root->v[2] ||
+         new_regraft_nd == tree->n_root) regraft_edge = tree->e_root;
+      else
+        {
+          for(i=0;i<3;i++) if(new_regraft_nd->v[i] == new_regraft_nd->anc) break;
+          assert(i!=3);
+          regraft_edge = new_regraft_nd->b[i];
+        }
+
+      assert(regraft_edge);      
+      
+
+      // Regraft
+      Graft_Subtree(regraft_edge,
+                    prune_daughter->v[dir_prune],
+                    prune_daughter,
+                    residual,
+                    new_regraft_nd,tree);
+      
+
+      if(!TIMES_Check_Node_Height_Ordering(tree))
+        {
+          printf("\n== prune[%d]->t:%.3f daughter[%d]->t:%.3f prune_anc[%d]->t:%.3f regraft[%d]->t:%.3f regraft_anc[%d]->t:%.3f [effective:%d] t_prior_min/max: [prune:[%.3f %.3f] regraft:[%.3f %.3f]] ",
+                 prune->num,
+                 times[prune->num],
+                 prune_daughter->num,
+                 times[prune_daughter->num],
+                 prune->anc ? prune->anc->num : -1,
+                 prune->anc ? times[prune->anc->num] : -1.,
+                 new_regraft_nd->num,
+                 times[new_regraft_nd->num],
+                 new_regraft_nd->anc ? new_regraft_nd->anc->num : -1,
+                 new_regraft_nd->anc ? times[new_regraft_nd->anc->num] : +1.,
+                 prune->num,
+                 tree->rates->t_prior_min[prune->num],
+                 tree->rates->t_prior_max[prune->num],
+                 tree->rates->t_prior_min[new_regraft_nd->num],
+                 tree->rates->t_prior_max[new_regraft_nd->num]);
+          PhyML_Printf("\n== root: %d %d %d",tree->n_root->num,tree->n_root->v[1]->num,tree->n_root->v[2]->num);
+          Generic_Exit(__FILE__,__LINE__,__FUNCTION__);    
+        }
+
+      DATE_Assign_Primary_Calibration(tree);
+      new_lnL_time = TIMES_Lk_Times(NO,tree); 
+
+      if(new_lnL_time > UNLIKELY)
+        {
+          Set_Both_Sides(NO,tree);
+          new_lnL_seq = Lk(NULL,tree);
+          new_lnL_rate = RATES_Lk_Rates(tree);
+        }
+      
+      ratio += (new_lnL_seq - cur_lnL_seq);
+      ratio += (new_lnL_rate - cur_lnL_rate);
+      ratio += (new_lnL_time - cur_lnL_time);
+      
+      ratio = exp(ratio);
+      alpha = MIN(1.,ratio);
+
+      /* Always accept move */
+      if(tree->mcmc->always_yes == YES && new_lnL_time > UNLIKELY) alpha = 1.0;
+      
+      u = Uni();
+
+      if(u > alpha)
+        {
+          // Reject
+          Prune_Subtree(prune_daughter->v[dir_prune],
+                        prune_daughter,
+                        &target,&residual,tree);
+          Graft_Subtree(ori_target,
+                        prune_daughter->v[dir_prune],
+                        prune_daughter,residual,prune == tree->n_root ? tree->n_root : cur_regraft_nd,tree);
+
+          RATES_Reset_Times(tree);
+          RATES_Update_Cur_Bl(tree);
+          DATE_Assign_Primary_Calibration(tree);
+          TIMES_Lk_Times(NO,tree); 
+
+          
+          if(!(tree->rates->c_lnL_times > UNLIKELY))
+            {
+              printf("\n== time prune: %f",times[prune->num]);
+              printf("\n== time prune_daughter: %f",times[prune_daughter->num]);
+              printf("\n== prune: %d prune_daughter: %d prune_daughter->v[dir_prune]: %d cur_regraft_nd: %d new_regraft_nd: %d",
+                     prune->num,
+                     prune_daughter->num,
+                     prune_daughter->v[dir_prune]->num,
+                     cur_regraft_nd->num,
+                     new_regraft_nd->num);
+              TIMES_Lk_Times(YES,tree); 
+              fflush(NULL);
+            }
+          assert(tree->rates->c_lnL_times > UNLIKELY);
+          
+          tree->c_lnL              = cur_lnL_seq;
+          tree->rates->c_lnL_times = cur_lnL_time;
+          tree->rates->c_lnL_rates = cur_lnL_rate;
+        }
+      else
+        {
+          tree->mcmc->acc_move[tree->mcmc->num_move_spr_weighted]++;
+        }
+    }
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void MCMC_Prune_Regraft_Local(t_tree *tree)
+{
+  phydbl u,alpha,ratio;
+  phydbl t_min,t_max;
+  phydbl cur_lnL_seq,new_lnL_seq;
+  phydbl cur_lnL_rate,new_lnL_rate;
+  phydbl cur_lnL_time,new_lnL_time;
+  phydbl new_t;
+  int i,prune_idx,n_iter,n_regraft_nd,regraft_idx,dir_prune;
+  phydbl *times;
+  int rnd_dir,dir_v1,dir_v2;
+  t_node *prune,*prune_daughter,*new_regraft_nd,*cur_regraft_nd;
+  t_ll *regraft_nd_list;
+  t_edge *target, *ori_target, *residual,*regraft_edge;
+  t_node *a, *b, *c, *d, *e;
+  
+  n_iter = MAX(1,(int)(tree->n_otu/5));
+  times = tree->rates->nd_t;
+
+  while(n_iter--)
+    {
+      tree->mcmc->run_move[tree->mcmc->num_move_spr_local]++;
+      
+      RATES_Record_Times(tree);
+      
+      cur_lnL_seq  = tree->c_lnL;
+      new_lnL_seq  = UNLIKELY;
+      cur_lnL_rate = tree->rates->c_lnL_rates;
+      new_lnL_rate = UNLIKELY;
+      cur_lnL_time = tree->rates->c_lnL_times;
+      new_lnL_time = UNLIKELY;
+
+      ratio          = 0.0;
+      regraft_edge   = NULL;
+      new_regraft_nd = NULL;
+      cur_regraft_nd = NULL;
+      new_t          = 0.0;
+
+      // Select prune node (any internal node)
+      prune_idx = Rand_Int(tree->n_otu,2*tree->n_otu-2);
+      /* prune_idx = tree->n_otu+n_iter; */
+
+      prune = tree->a_nodes[prune_idx];
+
+      assert(prune && prune->tax == NO);
+
+      // Select a daughter of prune node
+      dir_v1 = dir_v2 = -1;
+      for(i=0;i<3;i++) 
+        if(prune->v[i] != prune->anc && prune->b[i] != tree->e_root)
+          {
+            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];
+      cur_regraft_nd = prune->v[rnd_dir == dir_v1 ? dir_v2 : dir_v1];            
+
+      if(prune == tree->n_root)
+        {
+          if(prune_daughter == prune->v[dir_v1] && prune->v[dir_v2]->tax == YES)
+            {
+              prune_daughter = prune->v[dir_v2];
+              cur_regraft_nd = prune->v[dir_v1];
+            }
+
+          if(prune_daughter == prune->v[dir_v2] && prune->v[dir_v1]->tax == YES)
+            {
+              prune_daughter = prune->v[dir_v1];
+              cur_regraft_nd = prune->v[dir_v2];
+            }
+        }
+           
+      assert(prune_daughter->anc == prune);
+
+      dir_prune = -1;
+      for(i=0;i<3;i++)
+        {
+          if(prune_daughter->v[i] == prune || prune_daughter->b[i] == tree->e_root)
+            {
+              dir_prune = i;
+              break;
+            }
+        }
+      assert(dir_prune > -1);
+            
+      /*
+
+          |
+          |
+          d
+         / \
+        /   \c
+       / \
+    e /   \prune_daughter
+     /\
+    /  \
+    a   b
+      
+      */
+
+
+      // Probability of forward move
+      regraft_nd_list = NULL;
+      a = b = c = d = e = NULL;
+      e = cur_regraft_nd;
+
+      if(e->tax == NO && times[e->num] < times[prune_daughter->num])
+        {
+          for(i=0;i<3;i++)
+            {
+              if(e->v[i] != e->anc && e->b[i] != tree->e_root)
+                {
+                  if(a == NULL) a = e->v[i];
+                  else          b = e->v[i];
+                }
+            }
+          Push_Bottom_Linked_List(a,&regraft_nd_list,YES);
+          Push_Bottom_Linked_List(b,&regraft_nd_list,YES);
+        }
+
+      if(prune_daughter->anc != tree->n_root)
+        {          
+          d = prune_daughter->anc->anc;      
+
+          for(i=0;i<3;i++)
+            {
+              if(d->v[i] != d->anc && d->b[i] != tree->e_root && d->v[i] != prune)
+                {
+                  c = d->v[i];
+                  break;
+                }
+            }
+          Push_Bottom_Linked_List(c,&regraft_nd_list,YES);
+          Push_Bottom_Linked_List(d,&regraft_nd_list,YES);
+        }
+      
+      n_regraft_nd = Linked_List_Len(regraft_nd_list);
+      
+      if(n_regraft_nd == 0)
+        {
+          Free_Linked_List(regraft_nd_list);
+          continue;
+        }
 
-  Record_Br_Len(tree);
+      assert(n_regraft_nd > 0);
+      ratio -= log(1./n_regraft_nd);
 
-  cur_nu        = -1.0;
-  new_nu        = -1.0;
-  ratio         =  0.0;
+      // Randomly select one node among potential regraft sites (uniform)
+      regraft_idx = Rand_Int(0,n_regraft_nd-1);
+      new_regraft_nd = Linked_List_Elem(regraft_idx,regraft_nd_list);      
+      Free_Linked_List(regraft_nd_list);
 
-  K = tree->mcmc->tune_move[tree->mcmc->num_move_nu];
+            
+      // Time of regraft node and corresponding (partial) Hastings ratio
+      t_max = MIN(times[prune_daughter->num],times[cur_regraft_nd->num]);      
+      if(prune == tree->n_root) t_min = 10.0*t_max;
+      else t_min = times[prune->anc->num];
+      ratio += log(1./(t_max - t_min));
 
-  cur_lnL_rate = tree->rates->c_lnL_rates;
-  new_lnL_rate = tree->rates->c_lnL_rates;
 
-  cur_lnL_data = tree->c_lnL;
-  new_lnL_data = tree->c_lnL;
-  
-  cur_nu       = tree->rates->nu;
+      t_max = MIN(times[prune_daughter->num],times[new_regraft_nd->num]);      
+      if(new_regraft_nd == tree->n_root) t_min = 10.0*t_max;
+      else t_min = times[new_regraft_nd->anc->num];
+      ratio -= log(1./(t_max - t_min));
+      
+      new_t = Uni()*(t_max-t_min) + t_min;
 
-  min_nu = tree->rates->min_nu;
-  max_nu = tree->rates->max_nu;
+            
+      // Age of root node changes when pruned substree is on one side of that node
+      // Change here, not after the prune and regraft move
+      /* if(prune == tree->n_root) */
+      /*   { */
+      /*     if(prune_daughter == tree->n_root->v[1]) */
+      /*       times[tree->n_root->num] = times[tree->n_root->v[2]->num]; */
+      /*     else if(prune_daughter == tree->n_root->v[2]) */
+      /*       times[tree->n_root->num] = times[tree->n_root->v[1]->num]; */
+      /*     else assert(false); */
+      /*   } */
 
-  MCMC_Make_Move(&cur_nu,&new_nu,min_nu,max_nu,&ratio,K,tree->mcmc->move_type[tree->mcmc->num_move_nu]);
-  
-  if(new_nu < max_nu && new_nu > min_nu) 
-    {
-      tree->rates->nu = new_nu;
+      /* printf("\n-> prune: %d prune_daughter: %d prune_daughter->v[dir_prune]: %d cur_regraft_nd: %d new_regraft_nd: %d", */
+      /*        prune->num, */
+      /*        prune_daughter->num, */
+      /*        prune_daughter->v[dir_prune]->num, */
+      /*        cur_regraft_nd->num, */
+      /*        new_regraft_nd->num); */
+
+      /* printf("\n. a:%d b:%d c:%d d:%d e:%d", */
+      /*        a ? a->num : -1, */
+      /*        b ? b->num : -1, */
+      /*        c ? c->num : -1, */
+      /*        d ? d->num : -1, */
+      /*        e ? e->num : -1); */
+      /* fflush(NULL); */
+             
+      
+      // New age
+     if(prune == tree->n_root || new_regraft_nd == tree->n_root)
+        {
+          if(prune == tree->n_root)
+            {
+              if(prune_daughter == tree->n_root->v[1]) times[tree->n_root->num] = times[tree->n_root->v[2]->num];
+              else                                     times[tree->n_root->num] = times[tree->n_root->v[1]->num];
+              times[prune_daughter->v[dir_prune]->num] = new_t;
+            }
+          if(new_regraft_nd == tree->n_root)
+            {
+              times[prune_daughter->v[dir_prune]->num] = times[tree->n_root->num];
+              times[tree->n_root->num] = new_t;
+            }
+        }
+      else
+        {
+          times[prune->num] = new_t;
+        }
+
+
+
+      // Prune
+      target = residual = NULL;
+      Prune_Subtree(prune_daughter->v[dir_prune],
+                    prune_daughter,
+                    &target,&residual,tree);
+      ori_target = target;
       
-      new_lnL_rate = RATES_Lk_Rates(tree);      
+      // Regraft edge is the one sitting above regraft_nd
+      if(new_regraft_nd == tree->n_root->v[1] ||
+         new_regraft_nd == tree->n_root->v[2] ||
+         new_regraft_nd == tree->n_root) regraft_edge = tree->e_root;
+      else
+        {
+          for(i=0;i<3;i++) if(new_regraft_nd->v[i] == new_regraft_nd->anc) break;
+          assert(i!=3);
+          regraft_edge = new_regraft_nd->b[i];
+        }
 
-      if((tree->rates->model == GUINDON) && (tree->mcmc->use_data))
-	{
-	  For(i,2*tree->n_otu-2) tree->rates->br_do_updt[i] = YES;
-	  new_lnL_data = Lk(NULL,tree);
-	}
+      assert(regraft_edge);      
       
-      ratio +=
-      	(new_lnL_rate - cur_lnL_rate);
+      // Regraft
+      Graft_Subtree(regraft_edge,
+                    prune_daughter->v[dir_prune],
+                    prune_daughter,
+                    residual,
+                    new_regraft_nd,tree);
+      
+      a = b = c = d = e = NULL;
+      regraft_nd_list = NULL;
+      e = new_regraft_nd;
+      if(new_regraft_nd == tree->n_root)
+        {
+          if(prune_daughter == tree->n_root->v[1])
+            e = tree->n_root->v[2];
+          else if(prune_daughter == tree->n_root->v[2])
+            e = tree->n_root->v[1];
+          else assert(false);
+        }
+      
+      if(e->tax == NO && times[e->num] < times[prune_daughter->num])
+        {
+          for(i=0;i<3;i++)
+            {
+              if(e->v[i] != e->anc && e->b[i] != tree->e_root)
+                {
+                  if(a == NULL) a = e->v[i];
+                  else          b = e->v[i];
+                }
+            }
+          Push_Bottom_Linked_List(a,&regraft_nd_list,YES);
+          Push_Bottom_Linked_List(b,&regraft_nd_list,YES);
+        }
 
-      ratio +=
-	(new_lnL_data - cur_lnL_data);
+      // prune is different from prune_daughter->anc here if prune == tree->n_root
+      if(prune_daughter->anc != tree->n_root)
+        {          
+          d = prune_daughter->anc->anc;      
 
+          for(i=0;i<3;i++)
+            {
+              if(d->v[i] != d->anc && d->b[i] != tree->e_root && d->v[i] != prune)
+                {
+                  c = d->v[i];
+                  break;
+                }
+            }
+          Push_Bottom_Linked_List(c,&regraft_nd_list,YES);
+          Push_Bottom_Linked_List(d,&regraft_nd_list,YES);
+        }
 
-      /* !!!!!!!!!!!!!!!! */
-      /* Modelling exp(nu) and making move on nu */
-      /* ratio += (new_nu - cur_nu); */
-	 
-      /* Exponential prior on nu */
-      /* ratio += LOG(Dexp(new_nu,10.) / Dexp(cur_nu,10.)); */
+      /* printf("\n+ a:%d b:%d c:%d d:%d e:%d", */
+      /*        a ? a->num : -1, */
+      /*        b ? b->num : -1, */
+      /*        c ? c->num : -1, */
+      /*        d ? d->num : -1, */
+      /*        e ? e->num : -1); */
+      /* fflush(NULL); */
+
+      // Number of regraft nodes
+      n_regraft_nd = Linked_List_Len(regraft_nd_list);
+      assert(n_regraft_nd > 0);
+      ratio += log(1./n_regraft_nd);
+      Free_Linked_List(regraft_nd_list);
+      
+      // New age
+      /* if(new_regraft_nd == tree->n_root) */
+      /*   { */
+      /*     if(prune_daughter == tree->n_root->v[1]) */
+      /*       times[tree->n_root->v[2]->num] = times[tree->n_root->num]; */
+      /*     else if(prune_daughter == tree->n_root->v[2]) */
+      /*       times[tree->n_root->v[1]->num] = times[tree->n_root->num]; */
+      /*     else assert(false); */
 
- 
-      ratio = EXP(ratio);
-      alpha = MIN(1.,ratio);
-      
-      u = Uni();
-      if(u > alpha) /* Reject */
-	{
-	  tree->rates->nu    = cur_nu;
-	  tree->rates->c_lnL_rates = cur_lnL_rate;
-	  tree->c_lnL        = cur_lnL_data;
-	  Restore_Br_Len(tree);
-	}
-      else
-	{
-	  tree->mcmc->acc_move[tree->mcmc->num_move_nu]++;
-	}
-    }
-  tree->mcmc->run_move[tree->mcmc->num_move_nu]++;
-}
+      /*     times[tree->n_root->num] = new_t; */
+      /*   } */
+      /* else if(prune == tree->n_root) */
+      /*   { */
+      /*     times[prune_daughter->v[dir_prune]->num] = new_t; */
+      /*   } */
+      /* else */
+      /*   { */
+      /*     times[prune->num] = new_t; */
+      /*   } */
 
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
 
 
-void MCMC_All_Rates(t_tree *tree)
-{
-  phydbl cur_lnL_data, new_lnL_data, cur_lnL_rate;
-  phydbl u, ratio, alpha;
 
-  new_lnL_data = tree->c_lnL;
-  cur_lnL_data = tree->c_lnL;
-  cur_lnL_rate = tree->rates->c_lnL_rates;
-  ratio        = 0.0;
-  
-  Record_Br_Len(tree);
-  RATES_Record_Rates(tree);
-  
-  MCMC_Sim_Rate(tree->n_root,tree->n_root->v[2],tree);
-  MCMC_Sim_Rate(tree->n_root,tree->n_root->v[1],tree);
 
-  new_lnL_data = Lk(NULL,tree);
-  
-  ratio += (new_lnL_data - cur_lnL_data);
-  ratio = EXP(ratio);
+      if(!TIMES_Check_Node_Height_Ordering(tree))
+        {
+          printf("\n== prune[%d]->t:%.3f daughter[%d]->t:%.3f prune_anc[%d]->t:%.3f regraft[%d]->t:%.3f regraft_anc[%d]->t:%.3f [effective:%d] t_prior_min/max: [prune:[%.3f %.3f] regraft:[%.3f %.3f]] ",
+                 prune->num,
+                 times[prune->num],
+                 prune_daughter->num,
+                 times[prune_daughter->num],
+                 prune->anc ? prune->anc->num : -1,
+                 prune->anc ? times[prune->anc->num] : -1.,
+                 new_regraft_nd->num,
+                 times[new_regraft_nd->num],
+                 new_regraft_nd->anc ? new_regraft_nd->anc->num : -1,
+                 new_regraft_nd->anc ? times[new_regraft_nd->anc->num] : +1.,
+                 prune->num,
+                 tree->rates->t_prior_min[prune->num],
+                 tree->rates->t_prior_max[prune->num],
+                 tree->rates->t_prior_min[new_regraft_nd->num],
+                 tree->rates->t_prior_max[new_regraft_nd->num]);
+          PhyML_Printf("\n== root: %d %d %d",tree->n_root->num,tree->n_root->v[1]->num,tree->n_root->v[2]->num);
+          Generic_Exit(__FILE__,__LINE__,__FUNCTION__);    
+        }
 
-  alpha = MIN(1.,ratio);
-  u = Uni();
+      DATE_Assign_Primary_Calibration(tree);
+      new_lnL_time = TIMES_Lk_Times(NO,tree); 
 
-  if(u > alpha) /* Reject */
-    {
-      Restore_Br_Len(tree);
-      RATES_Reset_Rates(tree);
-      tree->rates->c_lnL_rates = cur_lnL_rate;
-    }
-  else
-    {
-      tree->rates->c_lnL_rates = RATES_Lk_Rates(tree);;
-    }
-}
+      if(new_lnL_time > UNLIKELY)
+        {
+          Set_Both_Sides(NO,tree);
+          new_lnL_seq = Lk(NULL,tree);
+          new_lnL_rate = RATES_Lk_Rates(tree);
+        }
+      
+      ratio += (new_lnL_seq - cur_lnL_seq);
+      ratio += (new_lnL_rate - cur_lnL_rate);
+      ratio += (new_lnL_time - cur_lnL_time);
 
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
 
+      
+      ratio = exp(ratio);
+      alpha = MIN(1.,ratio);
 
-/* Only works when simulating from prior */
-void MCMC_Sim_Rate(t_node *a, t_node *d, t_tree *tree)
-{
-  int err;
-  phydbl mean,sd,br_r_a,dt_d;
 
-  br_r_a = tree->rates->br_r[a->num];
-  dt_d   = tree->rates->nd_t[d->num] - tree->rates->nd_t[a->num];
-  sd     = SQRT(dt_d*tree->rates->nu);
-  
-  if(tree->rates->model_log_rates == YES)
-    {
-      mean = br_r_a - .5*sd*sd;
-    }
-  else
-    {
-      mean = br_r_a;
-    }
+
+      /* Always accept move */
+      if(tree->mcmc->always_yes == YES && new_lnL_time > UNLIKELY) alpha = 1.0;
       
-  if(tree->rates->model == STRICTCLOCK) tree->rates->br_r[d->num] = 1.0;
-  else
-    tree->rates->br_r[d->num] = Rnorm_Trunc(mean,sd,tree->rates->min_rate,tree->rates->max_rate,&err);
+      u = Uni();
 
-  if(d->tax) return;
-  else
-    {
-      int i;
+      if(u > alpha)
+        {
+          // Reject
+          Prune_Subtree(prune_daughter->v[dir_prune],
+                        prune_daughter,
+                        &target,&residual,tree);
+          Graft_Subtree(ori_target,
+                        prune_daughter->v[dir_prune],
+                        prune_daughter,residual,prune == tree->n_root ? tree->n_root : cur_regraft_nd,tree);
 
-      For(i,3)
-	if(d->v[i] != a && d->b[i] != tree->e_root)
-	  MCMC_Sim_Rate(d,d->v[i],tree);
+          RATES_Reset_Times(tree);
+          RATES_Update_Cur_Bl(tree);
+          DATE_Assign_Primary_Calibration(tree);
+          TIMES_Lk_Times(NO,tree); 
+
+          
+          if(!(tree->rates->c_lnL_times > UNLIKELY))
+            {
+              printf("\n== time prune: %f",times[prune->num]);
+              printf("\n== time prune_daughter: %f",times[prune_daughter->num]);
+              printf("\n== prune: %d prune_daughter: %d prune_daughter->v[dir_prune]: %d cur_regraft_nd: %d new_regraft_nd: %d",
+                     prune->num,
+                     prune_daughter->num,
+                     prune_daughter->v[dir_prune]->num,
+                     cur_regraft_nd->num,
+                     new_regraft_nd->num);
+              TIMES_Lk_Times(YES,tree); 
+              fflush(NULL);
+            }
+          assert(tree->rates->c_lnL_times > UNLIKELY);
+          
+          tree->c_lnL              = cur_lnL_seq;
+          tree->rates->c_lnL_times = cur_lnL_time;
+          tree->rates->c_lnL_rates = cur_lnL_rate;
+        }
+      else
+        {
+          tree->mcmc->acc_move[tree->mcmc->num_move_spr_local]++;
+        }      
     }
 }
-
+  
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
@@ -4272,28 +6019,33 @@ void MCMC_Complete_MCMC(t_mcmc *mcmc, t_tree *tree)
   mcmc->io      = tree->io;
   mcmc->n_moves = 0;
 
-  mcmc->num_move_nd_r = mcmc->n_moves;
-  mcmc->n_moves += 2*tree->n_otu-1;
-
-  mcmc->num_move_br_r = mcmc->n_moves;
-  mcmc->n_moves += 2*tree->n_otu-2;
-
-  mcmc->num_move_nd_t = mcmc->n_moves;
-  mcmc->n_moves += tree->n_otu-1;
 
+  mcmc->num_move_nd_r                     = mcmc->n_moves; mcmc->n_moves += 1;
+  mcmc->num_move_br_r                     = mcmc->n_moves; mcmc->n_moves += 1;
+  mcmc->num_move_times                    = mcmc->n_moves; mcmc->n_moves += 1;
+  mcmc->num_move_times_and_rates          = mcmc->n_moves; mcmc->n_moves += 1;
+  mcmc->num_move_times_and_rates_root     = mcmc->n_moves; mcmc->n_moves += 1;
+  mcmc->num_move_root_time                = mcmc->n_moves; mcmc->n_moves += 1;
   mcmc->num_move_nu                       = mcmc->n_moves; mcmc->n_moves += 1;
   mcmc->num_move_clock_r                  = mcmc->n_moves; mcmc->n_moves += 1;
   mcmc->num_move_tree_height              = mcmc->n_moves; mcmc->n_moves += 1;
+  mcmc->num_move_time_slice               = mcmc->n_moves; mcmc->n_moves += 1;
   mcmc->num_move_subtree_height           = mcmc->n_moves; mcmc->n_moves += 1;
   mcmc->num_move_kappa                    = mcmc->n_moves; mcmc->n_moves += 1;
   mcmc->num_move_tree_rates               = mcmc->n_moves; mcmc->n_moves += 1;
   mcmc->num_move_subtree_rates            = mcmc->n_moves; mcmc->n_moves += 1;
   mcmc->num_move_updown_nu_cr             = mcmc->n_moves; mcmc->n_moves += 1;
-  mcmc->num_move_ras                      = mcmc->n_moves; mcmc->n_moves += (tree->mod ? 2*tree->mod->ras->n_catg : 1);
+  mcmc->num_move_ras                      = mcmc->n_moves; mcmc->n_moves += 1;
   mcmc->num_move_updown_t_cr              = mcmc->n_moves; mcmc->n_moves += 1;
-  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_rates                = mcmc->n_moves; mcmc->n_moves += 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_death_rate               = mcmc->n_moves; mcmc->n_moves += 1;
+  mcmc->num_move_birth_death_updown       = mcmc->n_moves; mcmc->n_moves += 1;
+  mcmc->num_move_spr                      = mcmc->n_moves; mcmc->n_moves += 1;
+  mcmc->num_move_spr_weighted             = mcmc->n_moves; mcmc->n_moves += 1;
+  mcmc->num_move_spr_local                = mcmc->n_moves; mcmc->n_moves += 1;
+  mcmc->num_move_spr_root                 = 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;
@@ -4343,28 +6095,36 @@ void MCMC_Complete_MCMC(t_mcmc *mcmc, t_tree *tree)
   mcmc->sampled_val    = (phydbl *)mCalloc((int)mcmc->n_moves*(mcmc->chain_len/mcmc->sample_interval + 1),sizeof(phydbl));
   mcmc->mode           = (phydbl *)mCalloc((int)mcmc->n_moves,sizeof(phydbl));
   mcmc->move_name      = (char **)mCalloc(mcmc->n_moves,sizeof(char *));
-  For(i,mcmc->n_moves) mcmc->move_name[i] = (char *)mCalloc(T_MAX_MCMC_MOVE_NAME,sizeof(char));
+  for(i=0;i<mcmc->n_moves;i++) mcmc->move_name[i] = (char *)mCalloc(T_MAX_MCMC_MOVE_NAME,sizeof(char));
 
-  For(i,mcmc->n_moves) mcmc->adjust_tuning[i] = YES;
+  for(i=0;i<mcmc->n_moves;i++) mcmc->adjust_tuning[i] = YES;
 
-  for(i=mcmc->num_move_br_r;i<mcmc->num_move_br_r+2*tree->n_otu-2;i++) strcpy(mcmc->move_name[i],"br_rate");
-  for(i=mcmc->num_move_nd_r;i<mcmc->num_move_nd_r+2*tree->n_otu-1;i++) strcpy(mcmc->move_name[i],"nd_rate");
-  for(i=mcmc->num_move_nd_t;i<mcmc->num_move_nd_t+tree->n_otu-1;i++)   strcpy(mcmc->move_name[i],"time");
+  strcpy(mcmc->move_name[mcmc->num_move_br_r],"br_rate");
+  strcpy(mcmc->move_name[mcmc->num_move_nd_r],"nd_rate");
+  strcpy(mcmc->move_name[mcmc->num_move_times],"times");
+  strcpy(mcmc->move_name[mcmc->num_move_times_and_rates],"times_and_rates");
+  strcpy(mcmc->move_name[mcmc->num_move_times_and_rates_root],"times_and_rates_root");
+  strcpy(mcmc->move_name[mcmc->num_move_root_time],"root_time");
   strcpy(mcmc->move_name[mcmc->num_move_nu],"nu");
   strcpy(mcmc->move_name[mcmc->num_move_clock_r],"clock");
   strcpy(mcmc->move_name[mcmc->num_move_tree_height],"tree_height");
+  strcpy(mcmc->move_name[mcmc->num_move_time_slice],"time_slice");
   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_spr_weighted],"spr_weighted");
+  strcpy(mcmc->move_name[mcmc->num_move_spr_local],"spr_local");
+  strcpy(mcmc->move_name[mcmc->num_move_spr_root],"spr_root");
   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");
-  for(i=mcmc->num_move_ras;i<mcmc->num_move_ras+(tree->mod ? 2*tree->mod->ras->n_catg : 1);i++) 
-    strcpy(mcmc->move_name[i],"ras");  
+  strcpy(mcmc->move_name[mcmc->num_move_ras],"ras");  
   strcpy(mcmc->move_name[mcmc->num_move_updown_t_cr],"updown_t_cr");
-  for(i=mcmc->num_move_cov_rates;i<mcmc->num_move_cov_rates+(tree->mod->m4mod ? 2*tree->mod->m4mod->n_h : 1);i++) 
-    strcpy(mcmc->move_name[i],"cov_rates");  
+  strcpy(mcmc->move_name[mcmc->num_move_cov_rates],"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_birth_death_updown],"birth_death_updown");
   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");
@@ -4397,29 +6157,27 @@ void MCMC_Complete_MCMC(t_mcmc *mcmc, t_tree *tree)
   strcpy(mcmc->move_name[mcmc->num_move_phyrex_ldsk_given_disk],"phyrex_ldsk_given_disk");
 
 
-  For(i,mcmc->n_moves) mcmc->move_type[i] = -1;
-  
-  if(tree->rates && tree->rates->model_log_rates == YES)
-    for(i=mcmc->num_move_br_r;i<mcmc->num_move_br_r+2*tree->n_otu-2;i++) mcmc->move_type[i] = MCMC_MOVE_RANDWALK_NORMAL;
-  else
-    for(i=mcmc->num_move_br_r;i<mcmc->num_move_br_r+2*tree->n_otu-2;i++) mcmc->move_type[i] = MCMC_MOVE_SCALE_THORNE;
-
-  for(i=mcmc->num_move_nd_r;i<mcmc->num_move_nd_r+2*tree->n_otu-1;i++) mcmc->move_type[i] = MCMC_MOVE_SCALE_THORNE;
-  /* for(i=mcmc->num_move_nd_t;i<mcmc->num_move_nd_t+tree->n_otu-1;i++)   mcmc->move_type[i] = MCMC_MOVE_RANDWALK_UNIFORM; */
-  for(i=mcmc->num_move_nd_t;i<mcmc->num_move_nd_t+tree->n_otu-1;i++)   mcmc->move_type[i] = MCMC_MOVE_SCALE_THORNE;
+  for(i=0;i<mcmc->n_moves;i++) mcmc->move_type[i] = -1;
+  mcmc->move_type[mcmc->num_move_nd_r] = MCMC_MOVE_SCALE_THORNE;
+  mcmc->move_type[mcmc->num_move_br_r] = MCMC_MOVE_SCALE_THORNE;
+  mcmc->move_type[mcmc->num_move_times] = MCMC_MOVE_SCALE_THORNE;
+  mcmc->move_type[mcmc->num_move_root_time] = MCMC_MOVE_SCALE_THORNE;
   mcmc->move_type[mcmc->num_move_nu] = MCMC_MOVE_SCALE_THORNE;
   mcmc->move_type[mcmc->num_move_clock_r] = MCMC_MOVE_SCALE_THORNE;
   mcmc->move_type[mcmc->num_move_tree_height] = MCMC_MOVE_SCALE_THORNE;
+  mcmc->move_type[mcmc->num_move_time_slice] = MCMC_MOVE_SCALE_THORNE;
   mcmc->move_type[mcmc->num_move_subtree_height] = MCMC_MOVE_SCALE_THORNE;
   mcmc->move_type[mcmc->num_move_kappa] = MCMC_MOVE_SCALE_THORNE;
   mcmc->move_type[mcmc->num_move_tree_rates] = MCMC_MOVE_SCALE_THORNE;
   mcmc->move_type[mcmc->num_move_subtree_rates] = MCMC_MOVE_SCALE_THORNE;
   mcmc->move_type[mcmc->num_move_updown_nu_cr] = MCMC_MOVE_RANDWALK_NORMAL;
-  for(i=mcmc->num_move_ras;i<mcmc->num_move_ras+(tree->mod ? 2*tree->mod->ras->n_catg : 1);i++) mcmc->move_type[i] = MCMC_MOVE_RANDWALK_NORMAL;  
+  mcmc->move_type[mcmc->num_move_ras] = MCMC_MOVE_RANDWALK_NORMAL;  
   mcmc->move_type[mcmc->num_move_updown_t_cr] = MCMC_MOVE_SCALE_THORNE;
-  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_rates] = 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_birth_death_updown] = 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;
@@ -4436,7 +6194,7 @@ void MCMC_Complete_MCMC(t_mcmc *mcmc, t_tree *tree)
 
   /* We start with small tuning parameter values in order to have inflated ESS
      for clock_r */
-  For(i,mcmc->n_moves)
+  for(i=0;i<mcmc->n_moves;i++)
     {
       switch(mcmc->move_type[i])
 	{
@@ -4471,24 +6229,33 @@ void MCMC_Complete_MCMC(t_mcmc *mcmc, t_tree *tree)
 	}
     }
   
-  for(i=mcmc->num_move_br_r;i<mcmc->num_move_br_r+2*tree->n_otu-2;i++) mcmc->move_weight[i] = (phydbl)(1./(2.*tree->n_otu-2)); /* Rates */
-  for(i=mcmc->num_move_nd_r;i<mcmc->num_move_nd_r+2*tree->n_otu-1;i++) mcmc->move_weight[i] = 0.0; /* Node rates */
-  for(i=mcmc->num_move_nd_t;i<mcmc->num_move_nd_t+tree->n_otu-1;i++)   mcmc->move_weight[i] = (phydbl)(1./(tree->n_otu-1));  /* Times */
-  mcmc->move_weight[mcmc->num_move_clock_r]          = 1.0;
-  mcmc->move_weight[mcmc->num_move_tree_height]      = 2.0;
-  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_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;
-  for(i=mcmc->num_move_ras;i<mcmc->num_move_ras+(tree->mod ? 2*tree->mod->ras->n_catg : 1);i++) mcmc->move_weight[i] = 0.5*(1./(tree->mod ? (phydbl)tree->mod->ras->n_catg : 1));
-  mcmc->move_weight[mcmc->num_move_updown_t_cr]      = 0.0; /* Does not seem to work well (does not give uniform prior on root height
-  							      when sampling from prior) */
-  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_updown_t_br]           = 1.0;
+  mcmc->move_weight[mcmc->num_move_br_r]                  = 1.0; 
+  mcmc->move_weight[mcmc->num_move_nd_r]                  = 0.0;
+  mcmc->move_weight[mcmc->num_move_times]                 = 1.0;
+  mcmc->move_weight[mcmc->num_move_times_and_rates]       = 5.0;
+  mcmc->move_weight[mcmc->num_move_root_time]             = 0.0;
+  mcmc->move_weight[mcmc->num_move_clock_r]               = 1.0;
+  mcmc->move_weight[mcmc->num_move_tree_height]           = 1.0;
+  mcmc->move_weight[mcmc->num_move_time_slice]            = 0.0;
+  mcmc->move_weight[mcmc->num_move_subtree_height]        = 0.0;
+  mcmc->move_weight[mcmc->num_move_nu]                    = 1.0;
+  mcmc->move_weight[mcmc->num_move_kappa]                 = 0.5;
+  mcmc->move_weight[mcmc->num_move_spr]                   = 3.0;
+  mcmc->move_weight[mcmc->num_move_spr_weighted]          = 5.0;
+  mcmc->move_weight[mcmc->num_move_spr_local]             = 3.0;
+  mcmc->move_weight[mcmc->num_move_spr_root]              = 0.0;
+  mcmc->move_weight[mcmc->num_move_tree_rates]            = 1.0;
+  mcmc->move_weight[mcmc->num_move_subtree_rates]         = 0.0;
+  mcmc->move_weight[mcmc->num_move_updown_nu_cr]          = 0.0;
+  mcmc->move_weight[mcmc->num_move_ras]                   = 1.0;
+  mcmc->move_weight[mcmc->num_move_updown_t_cr]           = 1.0; /* Does not seem to work well (does not give uniform prior on root height
+                                                                    when sampling from prior) */
+  mcmc->move_weight[mcmc->num_move_cov_rates]             = 0.0;    
+  mcmc->move_weight[mcmc->num_move_cov_switch]            = 0.0;
+  mcmc->move_weight[mcmc->num_move_birth_rate]            = 1.0;
+  mcmc->move_weight[mcmc->num_move_death_rate]            = 1.0;
+  mcmc->move_weight[mcmc->num_move_birth_death_updown]    = 1.0;
+  mcmc->move_weight[mcmc->num_move_updown_t_br]           = 0.0;
 #if defined (INVITEE)
   mcmc->move_weight[mcmc->num_move_jump_calibration]      = 0.1;
 #else
@@ -4502,6 +6269,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;
@@ -4553,48 +6321,15 @@ void MCMC_Complete_MCMC(t_mcmc *mcmc, t_tree *tree)
   mcmc->move_weight[mcmc->num_move_phyrex_disk_multi]            = 0.0;
 #endif
 
-  /* for(i=mcmc->num_move_br_r;i<mcmc->num_move_br_r+2*tree->n_otu-2;i++) mcmc->move_weight[i] = 0.0; /\* Rates *\/ */
-  /* for(i=mcmc->num_move_nd_r;i<mcmc->num_move_nd_r+2*tree->n_otu-1;i++) mcmc->move_weight[i] = 0.0; /\* Node rates *\/ */
-  /* for(i=mcmc->num_move_nd_t;i<mcmc->num_move_nd_t+tree->n_otu-1;i++)   mcmc->move_weight[i] = 0.0;  /\* Times *\/ */
-/*   mcmc->move_weight[mcmc->num_move_clock_r]          = 0.0; */
-/*   mcmc->move_weight[mcmc->num_move_tree_height]      = 0.0; */
-/*   mcmc->move_weight[mcmc->num_move_subtree_height]   = 0.0; */
-/*   mcmc->move_weight[mcmc->num_move_tree_height]      = 0.0; */
-/*   mcmc->move_weight[mcmc->num_move_subtree_height]   = 0.0; */
-/*   mcmc->move_weight[mcmc->num_move_nu]               = 0.0; */
-/*   mcmc->move_weight[mcmc->num_move_kappa]            = 0.0; */
-/*   mcmc->move_weight[mcmc->num_move_tree_rates]       = 0.0; */
-/*   mcmc->move_weight[mcmc->num_move_subtree_rates]    = 0.0; */
-/*   mcmc->move_weight[mcmc->num_move_updown_nu_cr]     = 0.0; */
-/*   for(i=mcmc->num_move_ras;i<mcmc->num_move_ras+(tree->mod ? 2*tree->mod->ras->n_catg : 1);i++) mcmc->move_weight[i] = 0.0; */
-/*   mcmc->move_weight[mcmc->num_move_updown_t_cr]      = 0.0; /\* Does not seem to work well (does not give uniform prior on root height */
-/*   							      when sampling from prior) *\/ */
-/*   for(i=mcmc->num_move_cov_rates;i<mcmc->num_move_cov_rates+(tree->mod ? 2*tree->mod->m4mod->n_h : 1);i++) mcmc->move_weight[i] = 0.5*(1./(tree->mod ? (phydbl)tree->mod->m4mod->n_h : 1)); */
-/*   mcmc->move_weight[mcmc->num_move_cov_switch]       = 0.0; */
-/*   mcmc->move_weight[mcmc->num_move_birth_rate]       = 0.0; */
-/*   mcmc->move_weight[mcmc->num_move_updown_t_br]      = 0.0; */
-/* #if defined (INVITEE) */
-/*   mcmc->move_weight[mcmc->num_move_jump_calibration] = 1.0; */
-/* #else */
-/*   mcmc->move_weight[mcmc->num_move_jump_calibration] = 0.0; */
-/* #endif */
-/*   mcmc->move_weight[mcmc->num_move_geo_lambda]       = 0.0; */
-/*   mcmc->move_weight[mcmc->num_move_geo_sigma]        = 0.0; */
-/*   mcmc->move_weight[mcmc->num_move_geo_tau]          = 0.0; */
-/*   mcmc->move_weight[mcmc->num_move_geo_updown_tau_lbda]   = 0.0; */
-/*   mcmc->move_weight[mcmc->num_move_geo_updown_lbda_sigma] = 0.0; */
-
-
   sum = 0.0;
-  For(i,mcmc->n_moves) sum += mcmc->move_weight[i];
-  For(i,mcmc->n_moves) mcmc->move_weight[i] /= sum;
+  for(i=0;i<mcmc->n_moves;i++) sum += mcmc->move_weight[i];
+  for(i=0;i<mcmc->n_moves;i++) mcmc->move_weight[i] /= sum;
   for(i=1;i<mcmc->n_moves;i++) mcmc->move_weight[i] += mcmc->move_weight[i-1];
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void MCMC_Initialize_Param_Val(t_mcmc *mcmc, t_tree *tree)
 {
   /* int i; */
@@ -4607,19 +6342,18 @@ void MCMC_Initialize_Param_Val(t_mcmc *mcmc, t_tree *tree)
   /* For(i,2*tree->n_otu-2) */
   /*   mcmc->lag_param_val[mcmc->num_move_br_r+i] = tree->rates->br_r[i]; */
   
-  /* For(i,tree->n_otu-1) */
+  /* for(i=0;i<tree->n_otu-1;i++) */
   /*   mcmc->lag_param_val[mcmc->num_move_nd_t+i] = tree->rates->nd_t[tree->n_otu+i]; */
 
   /* For(i,2*tree->n_otu-1) */
   /*   mcmc->lag_param_val[mcmc->num_move_nd_r+i] = tree->rates->nd_r[i]; */
 
-  /* For(i,mcmc->n_moves) tree->mcmc->new_param_val[i] = tree->mcmc->lag_param_val[i]; */
+  /* for(i=0;i<mcmc->n_moves;i++) tree->mcmc->new_param_val[i] = tree->mcmc->lag_param_val[i]; */
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 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,12 +6361,11 @@ 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]; */
   
-  /* For(i,tree->n_otu-1) */
-  /*   mcmc->sampled_val[(mcmc->num_move_nd_t+i)*mcmc->sample_size+mcmc->sample_num] = tree->rates->nd_t[tree->n_otu+i]; */
 
   /* For(i,2*tree->n_otu-1) */
   /*   mcmc->sampled_val[(mcmc->num_move_nd_r+i)*mcmc->sample_size+mcmc->sample_num] = tree->rates->nd_r[i]; */
@@ -4666,7 +6399,7 @@ void MCMC_Slice_One_Rate(t_node *a, t_node *d, int traversal, t_tree *tree)
 
   b = NULL;
   if(a == tree->n_root) b = tree->e_root;
-  else For(i,3) if(d->v[i] == a) { b = d->b[i]; break; }
+  else for(i=0;i<3;i++) if(d->v[i] == a) { b = d->b[i]; break; }
   
   w = 0.05;
   /* w = 10.; */
@@ -4730,16 +6463,14 @@ void MCMC_Slice_One_Rate(t_node *a, t_node *d, int traversal, t_tree *tree)
       if(d->tax == YES) return;
       else
 	{
-	  For(i,3)
+	  for(i=0;i<3;i++)
 	    if(d->v[i] != a && d->b[i] != tree->e_root)
 	      {
-		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); } */
+		if(tree->io->lk_approx == EXACT) Update_Partial_Lk(tree,d->b[i],d);
 		MCMC_Slice_One_Rate(d,d->v[i],YES,tree);
 	      }
 	}
-      if(tree->io->lk_approx == EXACT && tree->mcmc->use_data) Update_P_Lk(tree,b,d);
-      /* if(tree->io->lk_approx == EXACT && tree->mcmc->use_data) { tree->both_sides = YES; Lk(tree); } */
+      if(tree->io->lk_approx == EXACT) Update_Partial_Lk(tree,b,d);
     }
 }
 
@@ -4777,8 +6508,8 @@ void MCMC_Make_Move(phydbl *cur, phydbl *new, phydbl inf, phydbl sup, phydbl *lo
     case MCMC_MOVE_SCALE_THORNE:
       {
 	u = Uni();
-	*new   = (*cur) * EXP(tune*(u-.5));
-	*loghr = LOG((*new)/(*cur));
+	*new   = (*cur) * exp(tune*(u-.5));
+	*loghr = log((*new)/(*cur));
 	break;
       }
 
@@ -4787,7 +6518,7 @@ void MCMC_Make_Move(phydbl *cur, phydbl *new, phydbl inf, phydbl sup, phydbl *lo
 	phydbl r;
 	*new = (*cur) * Rgamma(1./tune,tune);
 	r = (*new)/(*cur);
-	*loghr = -LOG(r) + LOG(Dgamma(1./r,1./tune,tune)/Dgamma(r,1./tune,tune));
+	*loghr = -log(r) + log(Dgamma(1./r,1./tune,tune)/Dgamma(r,1./tune,tune));
 	break;
       }
 
@@ -4859,7 +6590,7 @@ void MCMC_Read_Param_Vals(t_tree *tree)
   tree->mod->kappa->v = val;
   /* PhyML_Printf("\n. TsTv = %f",val); */
 
-  For(i,tree->n_otu-1)
+  for(i=0;i<tree->n_otu-1;i++)
     {
       v=fscanf(in_fp,"%lf\t",&val); // Node heights
       tree->rates->nd_t[i+tree->n_otu] = val;
@@ -4868,7 +6599,7 @@ void MCMC_Read_Param_Vals(t_tree *tree)
   For(i,2*tree->n_otu-2)
     {
       v=fscanf(in_fp,"%lf\t",&val); // Edge average rates
-      tree->rates->br_r[i] = LOG(val);
+      tree->rates->br_r[i] = log(val);
     }
   
   v++;
@@ -4917,8 +6648,8 @@ void MCMC_PHYREX_Mu(t_tree *tree)
   /* K              = tree->mcmc->tune_move[tree->mcmc->num_move_phyrex_mu]; */
 
   /* u = Uni(); */
-  /* new_beta = ori_beta * EXP(K*(u-.5)); */
-  /* hr += LOG(new_beta/ori_beta); */
+  /* new_beta = ori_beta * exp(K*(u-.5)); */
+  /* hr += log(new_beta/ori_beta); */
 
   /* tree->mmod->mu = 1./(new_beta+1.); */
 
@@ -4927,7 +6658,7 @@ void MCMC_PHYREX_Mu(t_tree *tree)
   /* ratio += (new_glnL - cur_glnL); */
   /* ratio += hr; */
   
-  /* ratio = EXP(ratio); */
+  /* ratio = exp(ratio); */
   /* alpha = MIN(1.,ratio); */
   
   /* /\* Always accept move *\/ */
@@ -5011,7 +6742,7 @@ void MCMC_PHYREX_Radius(t_tree *tree)
   /* ratio += (new_glnL - cur_glnL); */
   /* ratio += hr; */
   
-  /* ratio = EXP(ratio); */
+  /* ratio = exp(ratio); */
   /* alpha = MIN(1.,ratio); */
   
   /* /\* Always accept move *\/ */
@@ -5077,14 +6808,14 @@ void MCMC_PHYREX_Indel_Disk(t_tree *tree)
   new_rad = tree->mmod->rad;
   cur_rad = tree->mmod->rad;
 
-  /* new_lbda = cur_lbda * EXP(0.5*(Uni()-.5)); */
-  /* hr += LOG(new_lbda/cur_lbda); */
+  /* new_lbda = cur_lbda * exp(0.5*(Uni()-.5)); */
+  /* hr += log(new_lbda/cur_lbda); */
 
-  /* new_mu = cur_mu * EXP(0.5*(Uni()-.5)); */
-  /* hr += LOG(new_mu/cur_mu); */
+  /* new_mu = cur_mu * exp(0.5*(Uni()-.5)); */
+  /* hr += log(new_mu/cur_mu); */
 
-  /* new_rad = cur_rad * EXP(0.5*(Uni()-.5)); */
-  /* hr += LOG(new_rad/cur_rad); */
+  /* new_rad = cur_rad * exp(0.5*(Uni()-.5)); */
+  /* hr += log(new_rad/cur_rad); */
 
   if(new_rad > tree->mmod->max_rad || new_rad < tree->mmod->min_rad)     return; 
   if(new_mu > tree->mmod->max_mu || new_mu < tree->mmod->min_mu)         return; 
@@ -5193,27 +6924,27 @@ void MCMC_PHYREX_Delete_Disk(phydbl hr, int n_delete_disks, phydbl cur_lbda, phy
 
   permut = Permutate(n_valid_disks);
 
-  For(j,n_delete_disks)
+  for(j=0;j<n_delete_disks;j++)
     {
       /* Uniform selection of a disk where no coalescent nor 'hit' occurred */
       target_disk[j] = valid_disks[permut[j]];
   
       PHYREX_Remove_Disk(target_disk[j]);
   
-      For(i,tree->mmod->n_dim) hr += LOG(1./tree->mmod->lim->lonlat[i]);
+      for(i=0;i<tree->mmod->n_dim;i++) hr += log(1./tree->mmod->lim->lonlat[i]);
     }
 
   T = PHYREX_Tree_Height(tree);
 
   hr += LnChoose(n_valid_disks,n_delete_disks);
-  hr -= n_delete_disks * LOG(-T);
+  hr -= n_delete_disks * log(-T);
   hr += LnFact(n_delete_disks);
 
   new_glnL = PHYREX_Lk(tree);
   ratio += (new_glnL - cur_glnL);
   ratio += hr;
   
-  ratio = EXP(ratio);
+  ratio = exp(ratio);
   alpha = MIN(1.,ratio);
 
   /* Always accept move */
@@ -5229,7 +6960,7 @@ void MCMC_PHYREX_Delete_Disk(phydbl hr, int n_delete_disks, phydbl cur_lbda, phy
       tree->mmod->rad = cur_rad;
       tree->mmod->mu = cur_mu;
 
-      For(j,n_delete_disks) PHYREX_Insert_Disk(target_disk[j],tree);
+      for(j=0;j<n_delete_disks;j++) PHYREX_Insert_Disk(target_disk[j],tree);
 
       if(tree->mmod->safe_phyrex == YES)
         {
@@ -5248,7 +6979,7 @@ void MCMC_PHYREX_Delete_Disk(phydbl hr, int n_delete_disks, phydbl cur_lbda, phy
     }
   else
     {
-      For(j,n_delete_disks) Free_Disk(target_disk[j]);
+      for(j=0;j<n_delete_disks;j++) Free_Disk(target_disk[j]);
       tree->mcmc->acc_move[tree->mcmc->num_move_phyrex_indel_disk]++;
     }
 
@@ -5300,7 +7031,7 @@ void MCMC_PHYREX_Insert_Disk(phydbl hr, int n_insert_disks, phydbl cur_lbda, phy
   target_disk = (t_dsk **)mCalloc(n_insert_disks,sizeof(t_dsk *));
   new_disk    = (t_dsk **)mCalloc(n_insert_disks,sizeof(t_dsk *));
 
-  For(j,n_insert_disks)
+  for(j=0;j<n_insert_disks;j++)
     {
       t = Uni()*T;
       disk = tree->disk->prev;
@@ -5314,20 +7045,20 @@ void MCMC_PHYREX_Insert_Disk(phydbl hr, int n_insert_disks, phydbl cur_lbda, phy
         
       PHYREX_Insert_Disk(new_disk[j],tree);
       
-      For(i,tree->mmod->n_dim) new_disk[j]->centr->lonlat[i] = Uni()*tree->mmod->lim->lonlat[i];
+      for(i=0;i<tree->mmod->n_dim;i++) new_disk[j]->centr->lonlat[i] = Uni()*tree->mmod->lim->lonlat[i];
 
-      For(i,tree->mmod->n_dim) hr -= LOG(1./tree->mmod->lim->lonlat[i]);
+      for(i=0;i<tree->mmod->n_dim;i++) hr -= log(1./tree->mmod->lim->lonlat[i]);
     }
 
   hr -= LnChoose(n_valid_disks+n_insert_disks,n_insert_disks);
-  hr += n_insert_disks * LOG(-T);
+  hr += n_insert_disks * log(-T);
   hr -= LnFact(n_insert_disks);
 
   new_glnL = PHYREX_Lk(tree);
   ratio = (new_glnL - cur_glnL);
   ratio += hr;
   
-  ratio = EXP(ratio);
+  ratio = exp(ratio);
   alpha = MIN(1.,ratio);
   
   /* Always accept move */
@@ -5345,7 +7076,7 @@ void MCMC_PHYREX_Insert_Disk(phydbl hr, int n_insert_disks, phydbl cur_lbda, phy
       
       /* printf("\nI Reject"); */
 
-      For(j,n_insert_disks)
+      for(j=0;j<n_insert_disks;j++)
         {
           PHYREX_Remove_Disk(new_disk[j]);
           Free_Disk(new_disk[j]);
@@ -5433,7 +7164,7 @@ void MCMC_PHYREX_Move_Disk_Updown(t_tree *tree)
 
   permut = Permutate(n_all_disks);
 
-  For(i,n_move_disks)
+  for(i=0;i<n_move_disks;i++)
     {
       target_disk[i] = all_disks[permut[i]];
       
@@ -5456,8 +7187,8 @@ void MCMC_PHYREX_Move_Disk_Updown(t_tree *tree)
 
           new_time = max - new_plusmin;
 
-          hr += LOG(Dexp(cur_plusmin,1./new_plusmin));
-          hr -= LOG(Dexp(new_plusmin,1./cur_plusmin));
+          hr += log(Dexp(cur_plusmin,1./new_plusmin));
+          hr -= log(Dexp(new_plusmin,1./cur_plusmin));
 
           new_glnL -= (log_lbda - FABS(ori_time[i]-max)*tree->mmod->lbda);
           new_glnL += (log_lbda - FABS(new_time   -max)*tree->mmod->lbda);
@@ -5469,13 +7200,13 @@ void MCMC_PHYREX_Move_Disk_Updown(t_tree *tree)
 
   tree->mmod->c_lnL = new_glnL;
 
-  if(tree->mcmc->use_data == YES) new_alnL = Lk(NULL,tree);
+  new_alnL = Lk(NULL,tree);
 
   ratio += (new_alnL - cur_alnL);
   ratio += (new_glnL - cur_glnL);
   ratio += hr;
   
-  ratio = EXP(ratio);
+  ratio = exp(ratio);
   alpha = MIN(1.,ratio);
   
   /* Always accept move */
@@ -5489,20 +7220,18 @@ void MCMC_PHYREX_Move_Disk_Updown(t_tree *tree)
     {
       /* printf("- Reject"); */
       
-      For(i,n_move_disks) target_disk[i]->time = ori_time[i]; 
+      for(i=0;i<n_move_disks;i++) target_disk[i]->time = ori_time[i]; 
 
       if(tree->mmod->safe_phyrex == YES)
         {
-          if(tree->mcmc->use_data == YES)
-            {
-              new_alnL = Lk(NULL,tree);
+          new_alnL = Lk(NULL,tree);
               
-              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__);
-                }
+          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__);
             }
+            
           
           new_glnL = PHYREX_Lk(tree);
           
@@ -5560,7 +7289,7 @@ void MCMC_PHYREX_Scale_Times(t_tree *tree)
   new_lbda        = tree->mmod->lbda;
 
   u = Uni();
-  scale_fact_times = EXP(K*(u-.5));
+  scale_fact_times = exp(K*(u-.5));
   
   if(tree->disk->next) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
 
@@ -5578,21 +7307,21 @@ void MCMC_PHYREX_Scale_Times(t_tree *tree)
   /* The Hastings ratio involves (n_disk-2) when considering a uniform distrib
      for the multiplier, which is not the case here.
   */
-  hr += (n_disks)*LOG(scale_fact_times);
+  hr += (n_disks)*log(scale_fact_times);
 
   /* Adjust the value of lambda */
   new_lbda = cur_lbda * (1./scale_fact_times);
-  hr += LOG(1./scale_fact_times);
+  hr += log(1./scale_fact_times);
   tree->mmod->lbda = new_lbda;
 
   new_glnL = PHYREX_Lk(tree);
-  if(tree->mcmc->use_data == YES) new_alnL = Lk(NULL,tree);
+  new_alnL = Lk(NULL,tree);
 
   ratio += (new_alnL - cur_alnL);
   ratio += (new_glnL - cur_glnL);
   ratio += hr;
   
-  ratio = EXP(ratio);
+  ratio = exp(ratio);
   alpha = MIN(1.,ratio);
   
   /* Always accept move */
@@ -5621,16 +7350,14 @@ void MCMC_PHYREX_Scale_Times(t_tree *tree)
 
       if(tree->mmod->safe_phyrex == YES)
         {
-          if(tree->mcmc->use_data == YES)
+          new_alnL = Lk(NULL,tree); /* Not necessary. Remove once tested */
+          
+          if(Are_Equal(new_alnL,cur_alnL,1.E-3) == NO)
             {
-              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 lbda: %f",new_alnL,cur_alnL,tree->mmod->lbda);
-                  Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
-                }
+              PhyML_Printf("\n== new_alnL: %f cur_alnL: %f lbda: %f",new_alnL,cur_alnL,tree->mmod->lbda);
+              Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
             }
+            
           
           new_glnL = PHYREX_Lk(tree); /* Same here */
           
@@ -5715,7 +7442,7 @@ void MCMC_PHYREX_Swap_Disk(t_tree *tree)
       
       t_min = target_disk->ldsk->prev->disk->time;
       t_max = +INFINITY;
-      For(i,target_disk->ldsk->n_next)
+      for(i=0;i<target_disk->ldsk->n_next;i++)
         if(target_disk->ldsk->next[i]->disk->time < t_max) 
           t_max = target_disk->ldsk->next[i]->disk->time;
       
@@ -5732,13 +7459,13 @@ void MCMC_PHYREX_Swap_Disk(t_tree *tree)
       PHYREX_Insert_Disk(target_disk,tree);
       
       new_glnL = PHYREX_Lk(tree);
-      if(tree->mcmc->use_data == YES) new_alnL = Lk(NULL,tree);
+      new_alnL = Lk(NULL,tree);
       
       ratio += (new_alnL - cur_alnL);
       ratio += (new_glnL - cur_glnL);
       ratio += hr;
             
-      ratio = EXP(ratio);
+      ratio = exp(ratio);
       alpha = MIN(1.,ratio);
       
       /* Always accept move */
@@ -5762,16 +7489,14 @@ void MCMC_PHYREX_Swap_Disk(t_tree *tree)
           
           if(tree->mmod->safe_phyrex == YES)
             {
-              if(tree->mcmc->use_data == YES)
+              new_alnL = Lk(NULL,tree); /* Remove once checked */
+              
+              if(Are_Equal(new_alnL,cur_alnL,1.E-3) == NO)
                 {
-                  new_alnL = Lk(NULL,tree); /* Remove once checked */
-                  
-                  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__);
-                    }
+                  PhyML_Printf("\n== new_alnL: %f cur_alnL: %f",new_alnL,cur_alnL);
+                  Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
                 }
+                
               
               new_glnL = PHYREX_Lk(tree); /* Same */
               
@@ -5813,11 +7538,11 @@ void MCMC_PHYREX_Indel_Hit(t_tree *tree)
   new_mu  = tree->mmod->mu;
   cur_mu  = tree->mmod->mu;
 
-  /* new_rad = cur_rad * EXP(0.5*(Uni()-.5)); */
-  /* hr += LOG(new_rad/cur_rad); */
+  /* new_rad = cur_rad * exp(0.5*(Uni()-.5)); */
+  /* hr += log(new_rad/cur_rad); */
 
-  /* new_mu = cur_mu * EXP(0.5*(Uni()-.5)); */
-  /* hr += LOG(new_mu/cur_mu); */
+  /* new_mu = cur_mu * exp(0.5*(Uni()-.5)); */
+  /* hr += log(new_mu/cur_mu); */
 
   if(new_rad > tree->mmod->max_rad || new_rad < tree->mmod->min_rad) return; 
   if(new_mu > tree->mmod->max_mu || new_mu < tree->mmod->min_mu)     return; 
@@ -5842,8 +7567,8 @@ void MCMC_PHYREX_Indel_Hit(t_tree *tree)
   /* K = 0.2; */
   /* n_disks_new = (int)Rgamma((phydbl)n_disks_cur/K,K); */
 
-  /* hr += LOG(Pgamma(n_disks_cur+1,(phydbl)n_disks_new/K,K) - Pgamma(n_disks_cur,(phydbl)n_disks_new/K,K)); */
-  /* hr -= LOG(Pgamma(n_disks_new+1,(phydbl)n_disks_cur/K,K) - Pgamma(n_disks_new,(phydbl)n_disks_cur/K,K)); */
+  /* hr += log(Pgamma(n_disks_cur+1,(phydbl)n_disks_new/K,K) - Pgamma(n_disks_cur,(phydbl)n_disks_new/K,K)); */
+  /* hr -= log(Pgamma(n_disks_new+1,(phydbl)n_disks_cur/K,K) - Pgamma(n_disks_new,(phydbl)n_disks_cur/K,K)); */
 
   if(n_disks_new < n_disks_cur) MCMC_PHYREX_Delete_Hit(hr, n_disks_cur - n_disks_new, cur_rad, cur_mu, tree);
   else                          MCMC_PHYREX_Insert_Hit(hr, n_disks_new - n_disks_cur, cur_rad, cur_mu, tree);  
@@ -5894,7 +7619,7 @@ void MCMC_PHYREX_Insert_Hit(phydbl hr, int n_insert_disks, phydbl cur_rad, phydb
 
   T = PHYREX_Tree_Height(tree);
 
-  For(j,n_insert_disks)
+  for(j=0;j<n_insert_disks;j++)
     {  
       /* Time of insertion of new disk */
       t = Uni()*T;
@@ -5917,7 +7642,7 @@ void MCMC_PHYREX_Insert_Hit(phydbl hr, int n_insert_disks, phydbl cur_rad, phydb
       assert(young_disk->n_ldsk_a);
 
       /* Which lineage is going to be hit ? */
-      hr += LOG(young_disk->n_ldsk_a);
+      hr += log(young_disk->n_ldsk_a);
       
       young_ldsk[j] = young_disk->ldsk_a[Rand_Int(0,young_disk->n_ldsk_a-1)];
       old_ldsk[j]   = young_ldsk[j]->prev;
@@ -5953,7 +7678,7 @@ void MCMC_PHYREX_Insert_Hit(phydbl hr, int n_insert_disks, phydbl cur_rad, phydb
       PHYREX_Update_Lindisk_List(tree);
       
       /* Sample position of the displaced ldsk */
-      For(i,tree->mmod->n_dim)
+      for(i=0;i<tree->mmod->n_dim;i++)
         {
           new_ldsk[j]->coord->lonlat[i] = Rnorm_Trunc(0.5*(young_ldsk[j]->coord->lonlat[i]+old_ldsk[j]->coord->lonlat[i]),
                                                       1.0*tree->mmod->rad,
@@ -5965,7 +7690,7 @@ void MCMC_PHYREX_Insert_Hit(phydbl hr, int n_insert_disks, phydbl cur_rad, phydb
         }
 
       /* Sample position of the center of new_disk */
-      For(i,tree->mmod->n_dim)
+      for(i=0;i<tree->mmod->n_dim;i++)
         {
           new_disk[j]->centr->lonlat[i] = Rnorm_Trunc(new_ldsk[j]->coord->lonlat[i],
                                                       1.0*tree->mmod->rad,
@@ -5982,7 +7707,7 @@ void MCMC_PHYREX_Insert_Hit(phydbl hr, int n_insert_disks, phydbl cur_rad, phydb
   T = PHYREX_Tree_Height(tree);
 
   hr -= LnChoose(n_valid_disks+n_insert_disks,n_insert_disks);
-  hr += n_insert_disks * LOG(-T);  
+  hr += n_insert_disks * log(-T);  
   hr -= LnFact(n_insert_disks);
 
   new_glnL = PHYREX_Lk(tree);
@@ -5990,7 +7715,7 @@ void MCMC_PHYREX_Insert_Hit(phydbl hr, int n_insert_disks, phydbl cur_rad, phydb
   ratio = (new_glnL - cur_glnL);
   ratio += hr;  
 
-  ratio = EXP(ratio);
+  ratio = exp(ratio);
   alpha = MIN(1.,ratio);
 
   if(tree->mcmc->always_yes == YES && new_glnL > UNLIKELY) alpha = 1.0;
@@ -6118,7 +7843,7 @@ void MCMC_PHYREX_Delete_Hit(phydbl hr, int n_delete_disks, phydbl cur_rad, phydb
 
   permut = Permutate(n_valid_disks);
 
-  For(j,n_delete_disks)
+  for(j=0;j<n_delete_disks;j++)
     {
       target_disk[j] = valid_disks[permut[j]];  
       target_ldsk[j] = target_disk[j]->ldsk;
@@ -6134,10 +7859,10 @@ void MCMC_PHYREX_Delete_Hit(phydbl hr, int n_delete_disks, phydbl cur_rad, phydb
       
       /* Part of the Hastings ratio corresponding to the probability of selecting */
       /* one of target_disk->n_ldsk_a to be hit */ 
-      hr -= LOG(target_disk[j]->next->n_ldsk_a);
+      hr -= log(target_disk[j]->next->n_ldsk_a);
             
       /* Density for position of the displaced ldsk */
-      For(i,tree->mmod->n_dim)
+      for(i=0;i<tree->mmod->n_dim;i++)
         {
           hr += Log_Dnorm_Trunc(target_ldsk[j]->coord->lonlat[i],
                                 0.5*(young_ldsk[j]->coord->lonlat[i]+old_ldsk[j]->coord->lonlat[i]),
@@ -6147,7 +7872,7 @@ void MCMC_PHYREX_Delete_Hit(phydbl hr, int n_delete_disks, phydbl cur_rad, phydb
         }
 
       /* Density for position of the center of target_disk */
-      For(i,tree->mmod->n_dim)
+      for(i=0;i<tree->mmod->n_dim;i++)
         {
           hr += Log_Dnorm_Trunc(target_disk[j]->centr->lonlat[i],
                                 target_ldsk[j]->coord->lonlat[i],
@@ -6166,7 +7891,7 @@ void MCMC_PHYREX_Delete_Hit(phydbl hr, int n_delete_disks, phydbl cur_rad, phydb
   T = PHYREX_Tree_Height(tree);
   
   hr += LnChoose(n_valid_disks,n_delete_disks);
-  hr -= n_delete_disks * LOG(-T);
+  hr -= n_delete_disks * log(-T);
   hr += LnFact(n_delete_disks);
 
   Free(valid_disks);
@@ -6176,7 +7901,7 @@ void MCMC_PHYREX_Delete_Hit(phydbl hr, int n_delete_disks, phydbl cur_rad, phydb
   ratio += (new_glnL - cur_glnL);
   ratio += hr;
 
-  ratio = EXP(ratio);
+  ratio = exp(ratio);
   alpha = MIN(1.,ratio);
   
   /* Always accept move */
@@ -6218,8 +7943,8 @@ void MCMC_PHYREX_Delete_Hit(phydbl hr, int n_delete_disks, phydbl cur_rad, phydb
     {
       /* printf(" ***"); */
 
-      For(j,n_delete_disks) Free_Disk(target_disk[j]);
-      For(j,n_delete_disks) Free_Ldisk(target_ldsk[j]);
+      for(j=0;j<n_delete_disks;j++) Free_Disk(target_disk[j]);
+      for(j=0;j<n_delete_disks;j++) Free_Ldisk(target_ldsk[j]);
       tree->mcmc->acc_move[tree->mcmc->num_move_phyrex_indel_hit]++;
     }
   
@@ -6303,7 +8028,7 @@ void MCMC_PHYREX_Prune_Regraft(t_tree *tree)
       prune_disk = valid_disks[i];
       Free(valid_disks);
       
-      hr -= LOG(1./n_prune_disks);
+      hr -= log(1./n_prune_disks);
 
       prune_ldsk = prune_disk->ldsk;
       /* Which daughter lineage are we pruning? */
@@ -6315,7 +8040,7 @@ void MCMC_PHYREX_Prune_Regraft(t_tree *tree)
       /* prune_daughter_ldsk has to be the next coalescent node under prune_ldsk for this move to work */
       
       /* Proba of pruning this particular one */
-      hr -= LOG(1./prune_ldsk->n_next);
+      hr -= log(1./prune_ldsk->n_next);
             
       /* Get a ldsk to reattach the pruned lineage to */
       disk = tree->disk->prev;
@@ -6362,27 +8087,27 @@ void MCMC_PHYREX_Prune_Regraft(t_tree *tree)
       if(n_valid_disks > 1)
         {
           max_dist = -INFINITY;
-          For(i,n_valid_disks) if(prob_disks[i] > max_dist) max_dist = prob_disks[i];
+          for(i=0;i<n_valid_disks;i++) if(prob_disks[i] > max_dist) max_dist = prob_disks[i];
           
           sum = 0.0;
-          For(i,n_valid_disks) prob_disks[i] /= max_dist;
+          for(i=0;i<n_valid_disks;i++) prob_disks[i] /= max_dist;
 
           param_exp = 1.0;
-          For(i,n_valid_disks) prob_disks[i] = Dexp(prob_disks[i],param_exp);
+          for(i=0;i<n_valid_disks;i++) prob_disks[i] = Dexp(prob_disks[i],param_exp);
 
           sum = 0.0;
-          For(i,n_valid_disks) sum += prob_disks[i];
-          For(i,n_valid_disks) prob_disks[i] /= sum;
+          for(i=0;i<n_valid_disks;i++) sum += prob_disks[i];
+          for(i=0;i<n_valid_disks;i++) prob_disks[i] /= sum;
           
           i = Sample_i_With_Proba_pi(prob_disks,n_valid_disks);
           
           /* Prob of selecting this node as regraft site */
-          hr -= LOG(prob_disks[i]);
+          hr -= log(prob_disks[i]);
 
           assert(num_prune_disk > -1);
 
           /* Prob of selecting this node as regraft site (opposite move) */
-          hr += LOG(prob_disks[num_prune_disk]);
+          hr += log(prob_disks[num_prune_disk]);
         }
       else
         {
@@ -6406,7 +8131,7 @@ void MCMC_PHYREX_Prune_Regraft(t_tree *tree)
 
       /* Proba of pruning that particular lineage in the opposite move 
        */
-      hr += LOG(1./(phydbl)(regraft_ldsk->n_next+1));
+      hr += log(1./(phydbl)(regraft_ldsk->n_next+1));
       
       /* Prob of selecting that prune ldsk in the opposite move. Number
          of prune sites increases by one in case actual regraft ldsk
@@ -6414,7 +8139,7 @@ void MCMC_PHYREX_Prune_Regraft(t_tree *tree)
       */
       if(regraft_ldsk->n_next == 1) n_prune_disks += 1;
       if(prune_ldsk->n_next == 2) n_prune_disks   -= 1;
-      hr += LOG(1./n_prune_disks);
+      hr += log(1./n_prune_disks);
 
 
       /* Prune and regraft */
@@ -6448,13 +8173,13 @@ void MCMC_PHYREX_Prune_Regraft(t_tree *tree)
       new_glnL += PHYREX_Lk_Range(prune_daughter_ldsk->disk->prev,dum_dum_disk,tree);
       tree->mmod->c_lnL = new_glnL;
 
-      if(tree->mcmc->use_data == YES) new_alnL = Lk(NULL,tree);
+      new_alnL = Lk(NULL,tree);
       
       ratio += (new_alnL - cur_alnL);
       ratio += (new_glnL - cur_glnL);
       ratio += hr;
             
-      ratio = EXP(ratio);
+      ratio = exp(ratio);
       alpha = MIN(1.,ratio);
       
       /* Always accept move */
@@ -6492,15 +8217,13 @@ void MCMC_PHYREX_Prune_Regraft(t_tree *tree)
 
           if(tree->mmod->safe_phyrex == YES)
             {
-              if(tree->mcmc->use_data == YES)
+              new_alnL = Lk(NULL,tree);
+              if(Are_Equal(new_alnL,cur_alnL,1.E-3) == NO)
                 {
-                  new_alnL = Lk(NULL,tree);
-                  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__);
-                    }
+                  PhyML_Printf("\n== new_alnL: %f cur_alnL: %f",new_alnL,cur_alnL);
+                  Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
                 }
+                
               
               new_glnL = PHYREX_Lk(tree);
               if(Are_Equal(new_glnL,cur_glnL,1.E-3) == NO)
@@ -6570,23 +8293,23 @@ void MCMC_PHYREX_Simulate_Backward(t_tree *tree)
   while(disk && disk->time > t) disk = disk->prev;
   target_disk = disk->next;
 
-  hr -= LOG(FABS((target_disk->prev->time - target_disk->time)/T));
+  hr -= log(FABS((target_disk->prev->time - target_disk->time)/T));
 
   bkp_disk = target_disk->prev;
 
   bkp_ldsk = (t_ldsk **)mCalloc(target_disk->n_ldsk_a,sizeof(t_ldsk *));
-  For(i,target_disk->n_ldsk_a) bkp_ldsk[i] = target_disk->ldsk_a[i]->prev;
+  for(i=0;i<target_disk->n_ldsk_a;i++) bkp_ldsk[i] = target_disk->ldsk_a[i]->prev;
 
   PHYREX_Simulate_Backward_Core(NO,target_disk,tree);
   
   T =  PHYREX_Tree_Height(tree);
-  hr += LOG(FABS((target_disk->prev->time - target_disk->time)/T));
+  hr += log(FABS((target_disk->prev->time - target_disk->time)/T));
 
-  if(tree->mcmc->use_data == YES) new_alnL = Lk(NULL,tree);
+  new_alnL = Lk(NULL,tree);
   ratio += (new_alnL - cur_alnL);
   ratio += hr;
   
-  ratio = EXP(ratio);
+  ratio = exp(ratio);
   alpha = MIN(1.,ratio);
     
  /* Always accept move */
@@ -6609,19 +8332,17 @@ void MCMC_PHYREX_Simulate_Backward(t_tree *tree)
       Free_Disk(disk);
 
       target_disk->prev = bkp_disk;
-      For(i,target_disk->n_ldsk_a) target_disk->ldsk_a[i]->prev = bkp_ldsk[i];
+      for(i=0;i<target_disk->n_ldsk_a;i++) target_disk->ldsk_a[i]->prev = bkp_ldsk[i];
       
       if(tree->mmod->safe_phyrex == YES)
         {
-          if(tree->mcmc->use_data == YES)
+          new_alnL = Lk(NULL,tree);
+          if(Are_Equal(new_alnL,cur_alnL,1.E-3) == NO)
             {
-              new_alnL = Lk(NULL,tree);
-              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__);
-                }
+              PhyML_Printf("\n== new_alnL: %f cur_alnL: %f",new_alnL,cur_alnL);
+              Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
             }
+        
           
           new_glnL = PHYREX_Lk(tree);
           
@@ -6706,14 +8427,14 @@ void MCMC_PHYREX_Simulate_Backward_Plus(t_tree *tree)
   new_mu        = cur_mu;
 
   
-  new_lbda = cur_lbda * EXP(0.2*(Uni()-.5));
-  hr += LOG(new_lbda/cur_lbda);
+  new_lbda = cur_lbda * exp(0.2*(Uni()-.5));
+  hr += log(new_lbda/cur_lbda);
 
-  new_mu = cur_mu * EXP(0.2*(Uni()-.5));
-  hr += LOG(new_mu/cur_mu);
+  new_mu = cur_mu * exp(0.2*(Uni()-.5));
+  hr += log(new_mu/cur_mu);
 
-  new_rad = cur_rad * EXP(0.2*(Uni()-.5));
-  hr += LOG(new_rad/cur_rad);
+  new_rad = cur_rad * exp(0.2*(Uni()-.5));
+  hr += log(new_rad/cur_rad);
 
   if(new_lbda < tree->mmod->min_lbda) return;
   if(new_lbda > tree->mmod->max_lbda) return;
@@ -6735,12 +8456,12 @@ void MCMC_PHYREX_Simulate_Backward_Plus(t_tree *tree)
   while(disk && disk->time > t) disk = disk->prev;
   target_disk = disk->next;
 
-  hr -= LOG(FABS((target_disk->prev->time - target_disk->time)/T));
+  hr -= log(FABS((target_disk->prev->time - target_disk->time)/T));
 
   bkp_disk = target_disk->prev;
 
   bkp_ldsk = (t_ldsk **)mCalloc(target_disk->n_ldsk_a,sizeof(t_ldsk *));
-  For(i,target_disk->n_ldsk_a) bkp_ldsk[i] = target_disk->ldsk_a[i]->prev;
+  for(i=0;i<target_disk->n_ldsk_a;i++) bkp_ldsk[i] = target_disk->ldsk_a[i]->prev;
 
   cur_glnL_do = PHYREX_Lk_Range(tree->disk->prev,target_disk,tree);
 
@@ -6757,14 +8478,14 @@ void MCMC_PHYREX_Simulate_Backward_Plus(t_tree *tree)
   PHYREX_Simulate_Backward_Core(NO,target_disk,tree);
   
   T =  PHYREX_Tree_Height(tree);
-  hr += LOG(FABS((target_disk->prev->time - target_disk->time)/T));
+  hr += log(FABS((target_disk->prev->time - target_disk->time)/T));
 
-  if(tree->mcmc->use_data == YES) new_alnL = Lk(NULL,tree);
+  new_alnL = Lk(NULL,tree);
   ratio += (new_alnL - cur_alnL);
   ratio += (new_glnL_do - cur_glnL_do);
   ratio += hr;
   
-  ratio = EXP(ratio);
+  ratio = exp(ratio);
   alpha = MIN(1.,ratio);
     
  /* Always accept move */
@@ -6792,19 +8513,17 @@ void MCMC_PHYREX_Simulate_Backward_Plus(t_tree *tree)
       Free_Disk(disk);
 
       target_disk->prev = bkp_disk;
-      For(i,target_disk->n_ldsk_a) target_disk->ldsk_a[i]->prev = bkp_ldsk[i];
+      for(i=0;i<target_disk->n_ldsk_a;i++) target_disk->ldsk_a[i]->prev = bkp_ldsk[i];
       
       if(tree->mmod->safe_phyrex == YES)
         {
-          if(tree->mcmc->use_data == YES)
+          new_alnL = Lk(NULL,tree);
+          if(Are_Equal(new_alnL,cur_alnL,1.E-3) == NO)
             {
-              new_alnL = Lk(NULL,tree);
-              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__);
-                }
+              PhyML_Printf("\n== new_alnL: %f cur_alnL: %f",new_alnL,cur_alnL);
+              Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
             }
+        
           
           new_glnL = PHYREX_Lk(tree);
           
@@ -6894,7 +8613,7 @@ void MCMC_PHYREX_Lineage_Traj(t_tree *tree)
   permut = Permutate(n_valid_disks);
   n_iter = Rand_Int(1,1+(int)(n_valid_disks/5));
   
-  For(j,n_iter)
+  for(j=0;j<n_iter;j++)
     {
       tree->mcmc->run_move[tree->mcmc->num_move_phyrex_traj]++;
 
@@ -6936,7 +8655,7 @@ void MCMC_PHYREX_Lineage_Traj(t_tree *tree)
       ratio += (new_glnL - cur_glnL);
       ratio += hr;
             
-      ratio = EXP(ratio);
+      ratio = exp(ratio);
       alpha = MIN(1.,ratio);
       
       if(tree->mcmc->always_yes == YES && new_glnL > UNLIKELY) alpha = 1.0;
@@ -7028,12 +8747,12 @@ void MCMC_PHYREX_Lbda_Times(t_tree *tree)
 
   disk = tree->disk;
   while(disk->prev != NULL) disk = disk->prev;
-  hr += (n_inter)*LOG(tree->mmod->lbda) + tree->mmod->lbda*disk->time;
+  hr += (n_inter)*log(tree->mmod->lbda) + tree->mmod->lbda*disk->time;
 
   new_glnL  = cur_glnL;
-  new_glnL -= (n_inter)*LOG(tree->mmod->lbda) + tree->mmod->lbda*disk->time;
-  new_lbda = cur_lbda * EXP(0.3*(Uni()-.5));
-  hr += LOG(new_lbda/cur_lbda);
+  new_glnL -= (n_inter)*log(tree->mmod->lbda) + tree->mmod->lbda*disk->time;
+  new_lbda = cur_lbda * exp(0.3*(Uni()-.5));
+  hr += log(new_lbda/cur_lbda);
 
   tree->mmod->lbda = new_lbda;
 
@@ -7050,18 +8769,18 @@ void MCMC_PHYREX_Lbda_Times(t_tree *tree)
 
   disk = tree->disk;
   while(disk->prev != NULL) disk = disk->prev;
-  hr -= n_inter*LOG(tree->mmod->lbda) + tree->mmod->lbda*disk->time;
+  hr -= n_inter*log(tree->mmod->lbda) + tree->mmod->lbda*disk->time;
   
-  new_glnL += n_inter*LOG(tree->mmod->lbda) + tree->mmod->lbda*disk->time;;
+  new_glnL += n_inter*log(tree->mmod->lbda) + tree->mmod->lbda*disk->time;;
   tree->mmod->c_lnL = new_glnL;
 
-  if(tree->mcmc->use_data == YES) new_alnL = Lk(NULL,tree);
+  new_alnL = Lk(NULL,tree);
     
   ratio += (new_glnL - cur_glnL);
   ratio += (new_alnL - cur_alnL);
   ratio += hr;
             
-  ratio = EXP(ratio);
+  ratio = exp(ratio);
   alpha = MIN(1.,ratio);
 
   u = Uni();
@@ -7081,16 +8800,14 @@ void MCMC_PHYREX_Lbda_Times(t_tree *tree)
       
       if(tree->mmod->safe_phyrex == YES)
         {
-          if(tree->mcmc->use_data == YES)
+          new_alnL = Lk(NULL,tree);
+          
+          if(Are_Equal(new_alnL,cur_alnL,1.E-3) == NO)
             {
-              new_alnL = Lk(NULL,tree);
-              
-              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__);
-                }
+              PhyML_Printf("\n== new_alnL: %f cur_alnL: %f",new_alnL,cur_alnL);
+              Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
             }
+            
           
           new_glnL = PHYREX_Lk(tree);
           
@@ -7159,7 +8876,7 @@ void MCMC_PHYREX_Disk_Multi(t_tree *tree)
 
   permut = Permutate(n_all_disks);
 
-  For(i,n_move_disks)
+  for(i=0;i<n_move_disks;i++)
     {
       target_disk[i] = all_disks[permut[i]];
   
@@ -7169,7 +8886,7 @@ void MCMC_PHYREX_Disk_Multi(t_tree *tree)
       
       if(target_disk[i]->ldsk != NULL)
         {
-          For(j,tree->mmod->n_dim)
+          for(j=0;j<tree->mmod->n_dim;j++)
             {
               target_disk[i]->centr->lonlat[j] = 
                 Rnorm_Trunc(target_disk[i]->centr->lonlat[j],
@@ -7192,7 +8909,7 @@ void MCMC_PHYREX_Disk_Multi(t_tree *tree)
         }
       else
         {
-          For(j,tree->mmod->n_dim)
+          for(j=0;j<tree->mmod->n_dim;j++)
             {
               target_disk[i]->centr->lonlat[j] = 
                 Rnorm_Trunc(target_disk[i]->centr->lonlat[j],
@@ -7223,7 +8940,7 @@ void MCMC_PHYREX_Disk_Multi(t_tree *tree)
   ratio += (new_glnL - cur_glnL);
   ratio += hr;
   
-  ratio = EXP(ratio);
+  ratio = exp(ratio);
   alpha = MIN(1.,ratio);
   
   /* Always accept move */
@@ -7237,7 +8954,7 @@ void MCMC_PHYREX_Disk_Multi(t_tree *tree)
     {
       /* printf("- Reject"); */
       
-      For(i,n_move_disks) PHYREX_Restore_Geo_Coord(target_disk[i]->centr);
+      for(i=0;i<n_move_disks;i++) PHYREX_Restore_Geo_Coord(target_disk[i]->centr);
       
       if(tree->mmod->safe_phyrex == YES)
         {
@@ -7314,13 +9031,13 @@ void MCMC_PHYREX_Ldsk_Multi(t_tree *tree)
 
   permut = Permutate(n_all_disks);
 
-  For(i,n_move_ldsk)
+  for(i=0;i<n_move_ldsk;i++)
     {
       target_disk[i] = all_disks[permut[i]];
       
       PHYREX_Store_Geo_Coord(target_disk[i]->ldsk->coord);
 
-      For(j,tree->mmod->n_dim)
+      for(j=0;j<tree->mmod->n_dim;j++)
         {
           /* c: center; o: pos of direct ldsk ancestor */
           c = target_disk[i]->centr->lonlat[j];
@@ -7334,13 +9051,13 @@ void MCMC_PHYREX_Ldsk_Multi(t_tree *tree)
                         tree->mmod->lim->lonlat[j],&err);
           
           
-          For(j,tree->mmod->n_dim) hr -= Log_Dnorm_Trunc(target_disk[i]->ldsk->coord->lonlat[j],
+          for(j=0;j<tree->mmod->n_dim;j++) hr -= Log_Dnorm_Trunc(target_disk[i]->ldsk->coord->lonlat[j],
                                                          (o+2.*c)/3.,
                                                          1.*SQRT(f*tree->mmod->rad*tree->mmod->rad),
                                                          0.0,
                                                          tree->mmod->lim->lonlat[j],&err);
           
-          For(j,tree->mmod->n_dim) hr += Log_Dnorm_Trunc(target_disk[i]->ldsk->coord->cpy->lonlat[j],
+          for(j=0;j<tree->mmod->n_dim;j++) hr += Log_Dnorm_Trunc(target_disk[i]->ldsk->coord->cpy->lonlat[j],
                                                          (o+2.*c)/3.,
                                                          1.*SQRT(f*tree->mmod->rad*tree->mmod->rad),
                                                          0.0,
@@ -7355,7 +9072,7 @@ void MCMC_PHYREX_Ldsk_Multi(t_tree *tree)
   ratio += (new_glnL - cur_glnL);
   ratio += hr;
   
-  ratio = EXP(ratio);
+  ratio = exp(ratio);
   alpha = MIN(1.,ratio);
   
   /* Always accept move */
@@ -7369,7 +9086,7 @@ void MCMC_PHYREX_Ldsk_Multi(t_tree *tree)
     {
       /* printf("- Reject"); */
       
-      For(i,n_move_ldsk) PHYREX_Restore_Geo_Coord(target_disk[i]->ldsk->coord);
+      for(i=0;i<n_move_ldsk;i++) PHYREX_Restore_Geo_Coord(target_disk[i]->ldsk->coord);
 
       if(tree->mmod->safe_phyrex == YES)
         {
@@ -7421,8 +9138,8 @@ void MCMC_PHYREX_Ldsk_And_Disk(t_tree *tree)
 
   tree->mcmc->run_move[tree->mcmc->num_move_phyrex_ldsk_and_disk]++;
 
-  new_rad = cur_rad * EXP(0.2*(Uni()-.5));
-  hr += LOG(new_rad/cur_rad);
+  new_rad = cur_rad * exp(0.2*(Uni()-.5));
+  hr += log(new_rad/cur_rad);
 
   if(new_rad > tree->mmod->max_rad) return;
   if(new_rad < tree->mmod->min_rad) return;
@@ -7454,13 +9171,13 @@ void MCMC_PHYREX_Ldsk_And_Disk(t_tree *tree)
 
   permut = Permutate(n_all_disks);
 
-  For(i,n_move_ldsk)
+  for(i=0;i<n_move_ldsk;i++)
     {
       target_disk[i] = all_disks[permut[i]];
       
       PHYREX_Store_Geo_Coord(target_disk[i]->ldsk->coord);
             
-      For(j,tree->mmod->n_dim)
+      for(j=0;j<tree->mmod->n_dim;j++)
         target_disk[i]->ldsk->coord->lonlat[j] =
         Rnorm_Trunc(target_disk[i]->centr->lonlat[j],
                     1.*new_rad,
@@ -7468,13 +9185,13 @@ void MCMC_PHYREX_Ldsk_And_Disk(t_tree *tree)
                     tree->mmod->lim->lonlat[j],&err);
       
 
-      For(j,tree->mmod->n_dim) hr -= Log_Dnorm_Trunc(target_disk[i]->ldsk->coord->lonlat[j],
+      for(j=0;j<tree->mmod->n_dim;j++) hr -= Log_Dnorm_Trunc(target_disk[i]->ldsk->coord->lonlat[j],
                                                      target_disk[i]->centr->lonlat[j],
                                                      1.*new_rad,
                                                      0.0,
                                                      tree->mmod->lim->lonlat[j],&err);
       
-      For(j,tree->mmod->n_dim) hr += Log_Dnorm_Trunc(target_disk[i]->ldsk->coord->cpy->lonlat[j],
+      for(j=0;j<tree->mmod->n_dim;j++) hr += Log_Dnorm_Trunc(target_disk[i]->ldsk->coord->cpy->lonlat[j],
                                                      target_disk[i]->centr->lonlat[j],
                                                      1.*cur_rad,
                                                      0.0,
@@ -7489,7 +9206,7 @@ void MCMC_PHYREX_Ldsk_And_Disk(t_tree *tree)
   ratio += (new_glnL - cur_glnL);
   ratio += hr;
   
-  ratio = EXP(ratio);
+  ratio = exp(ratio);
   alpha = MIN(1.,ratio);
   
   /* Always accept move */
@@ -7505,8 +9222,8 @@ void MCMC_PHYREX_Ldsk_And_Disk(t_tree *tree)
       
       tree->mmod->rad = cur_rad;
 
-      For(i,n_move_ldsk) PHYREX_Restore_Geo_Coord(target_disk[i]->ldsk->coord);
-      /* For(i,n_move_ldsk) PHYREX_Restore_Geo_Coord(target_disk[i]->centr); */
+      for(i=0;i<n_move_ldsk;i++) PHYREX_Restore_Geo_Coord(target_disk[i]->ldsk->coord);
+      /* for(i=0;i<n_move_ldsk;i++) PHYREX_Restore_Geo_Coord(target_disk[i]->centr); */
 
       if(tree->mmod->safe_phyrex == YES)
         {
@@ -7571,7 +9288,7 @@ void MCMC_PHYREX_Ldsk_Given_Disk(t_tree *tree)
   
   permut = Permutate(n_all_disks);
 
-  For(i,n_move_ldsk)
+  for(i=0;i<n_move_ldsk;i++)
     {
       tree->mcmc->run_move[tree->mcmc->num_move_phyrex_ldsk_given_disk]++;
       
@@ -7586,7 +9303,7 @@ void MCMC_PHYREX_Ldsk_Given_Disk(t_tree *tree)
       
       PHYREX_Store_Geo_Coord(disk->ldsk->coord);
                   
-      For(j,tree->mmod->n_dim)
+      for(j=0;j<tree->mmod->n_dim;j++)
         {
           /* c: center; o: pos of direct ldsk ancestor */
           c = disk->centr->lonlat[j];
@@ -7619,7 +9336,7 @@ void MCMC_PHYREX_Ldsk_Given_Disk(t_tree *tree)
       ratio += (new_glnL - cur_glnL);
       ratio += hr;
       
-      ratio = EXP(ratio);
+      ratio = exp(ratio);
       alpha = MIN(1.,ratio);
       
       u = Uni();
@@ -7691,7 +9408,7 @@ void MCMC_PHYREX_Disk_Given_Ldsk(t_tree *tree)
   
   permut = Permutate(n_all_disks);
 
-  For(i,n_move_ldsk)
+  for(i=0;i<n_move_ldsk;i++)
     {
       tree->mcmc->run_move[tree->mcmc->num_move_phyrex_disk_given_ldsk]++;
       
@@ -7710,7 +9427,7 @@ void MCMC_PHYREX_Disk_Given_Ldsk(t_tree *tree)
 
       PHYREX_Store_Geo_Coord(disk->centr);
 
-      For(j,tree->mmod->n_dim) disk->centr->lonlat[j] = Uni()*tree->mmod->lim->lonlat[j];
+      for(j=0;j<tree->mmod->n_dim;j++) disk->centr->lonlat[j] = Uni()*tree->mmod->lim->lonlat[j];
 
       if(disk->ldsk != NULL)
         new_glnL += PHYREX_Lk_Range(disk,disk->ldsk->prev ? disk->ldsk->prev->disk : NULL,tree);
@@ -7722,7 +9439,7 @@ void MCMC_PHYREX_Disk_Given_Ldsk(t_tree *tree)
       ratio += (new_glnL - cur_glnL);
       ratio += hr;
       
-      ratio = EXP(ratio);
+      ratio = exp(ratio);
       alpha = MIN(1.,ratio);
       
       u = Uni();
@@ -7779,12 +9496,12 @@ void MCMC_PHYREX_Indel_Hit_Serial(t_tree *tree)
   type         = -1.0;
   n_trials     = (int)(PHYREX_Total_Number_Of_Hit_Disks(tree)/10);
   T            = PHYREX_Tree_Height(tree);
-  log_one_on_T = -LOG(FABS(T));
+  log_one_on_T = -log(FABS(T));
   pindel       = 0.5;
 
   disk = tree->disk->prev;
 
-  For(i,n_trials)
+  for(i=0;i<n_trials;i++)
     {
       tree->mcmc->run_move[tree->mcmc->num_move_phyrex_indel_hit_serial]++;
 
@@ -7803,14 +9520,14 @@ void MCMC_PHYREX_Indel_Hit_Serial(t_tree *tree)
       
       if(type < pindel) /* Insert */
         {
-          hr += LOG(FABS((t - disk->next->time)/T));
+          hr += log(FABS((t - disk->next->time)/T));
           hr -= log_one_on_T;
           
           young_disk = disk->next;
           assert(young_disk->n_ldsk_a);
           
           /* Which lineage is going to be hit ? */
-          hr -= LOG(1./young_disk->n_ldsk_a);
+          hr -= log(1./young_disk->n_ldsk_a);
 
           new_disk = PHYREX_Make_Disk_Event(tree->mmod->n_dim,tree->n_otu);
           PHYREX_Init_Disk_Event(new_disk,tree->mmod->n_dim,tree->mmod);
@@ -7848,7 +9565,7 @@ void MCMC_PHYREX_Indel_Hit_Serial(t_tree *tree)
           /* Insert disk */
           PHYREX_Insert_Disk(new_disk,tree);
 
-          For(j,tree->mmod->n_dim)
+          for(j=0;j<tree->mmod->n_dim;j++)
             {
               new_ldsk->coord->lonlat[j] = Rnorm_Trunc(0.5*(young_ldsk->coord->lonlat[j]+old_ldsk->coord->lonlat[j]),
                                                        1.*tree->mmod->rad,
@@ -7861,7 +9578,7 @@ void MCMC_PHYREX_Indel_Hit_Serial(t_tree *tree)
             }
           
           /* Sample position of the center of new_disk */
-          For(j,tree->mmod->n_dim)
+          for(j=0;j<tree->mmod->n_dim;j++)
             {
               new_disk->centr->lonlat[j] = Rnorm_Trunc(new_ldsk->coord->lonlat[j],
                                                        1.*tree->mmod->rad,
@@ -7880,7 +9597,7 @@ void MCMC_PHYREX_Indel_Hit_Serial(t_tree *tree)
           ratio  = (new_glnL - cur_glnL);
           ratio += hr;
           
-          ratio = EXP(ratio);
+          ratio = exp(ratio);
           alpha = MIN(1.,ratio);
           
           /* Always accept move */
@@ -7918,10 +9635,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;
 
@@ -7935,10 +9650,10 @@ void MCMC_PHYREX_Indel_Hit_Serial(t_tree *tree)
 
           /* Part of the Hastings ratio corresponding to the probability of selecting */
           /* one of disk->n_ldsk_a to be hit */ 
-          hr += LOG(1./target_disk->next->n_ldsk_a);
+          hr += log(1./target_disk->next->n_ldsk_a);
           
           /* Density for position of the displaced ldsk */
-          For(j,tree->mmod->n_dim)
+          for(j=0;j<tree->mmod->n_dim;j++)
             {
               hr += Log_Dnorm_Trunc(target_disk->ldsk->coord->lonlat[j],
                                     0.5*(young_ldsk->coord->lonlat[j]+old_ldsk->coord->lonlat[j]),
@@ -7948,7 +9663,7 @@ void MCMC_PHYREX_Indel_Hit_Serial(t_tree *tree)
             }
           
           /* Density for position of the center of target_disk */
-          For(j,tree->mmod->n_dim)
+          for(j=0;j<tree->mmod->n_dim;j++)
             {
               hr += Log_Dnorm_Trunc(target_disk->centr->lonlat[j],
                                     target_disk->ldsk->coord->lonlat[j],
@@ -7963,7 +9678,7 @@ void MCMC_PHYREX_Indel_Hit_Serial(t_tree *tree)
           old_ldsk->next[dir_old_young] = young_ldsk;
           young_ldsk->prev              = old_ldsk;
 
-          hr -= LOG(FABS((target_disk->time - target_disk->next->time)/T));
+          hr -= log(FABS((target_disk->time - target_disk->next->time)/T));
           hr += log_one_on_T;
           
           PHYREX_Remove_Disk(target_disk);
@@ -7973,7 +9688,7 @@ void MCMC_PHYREX_Indel_Hit_Serial(t_tree *tree)
           ratio  = (new_glnL - cur_glnL);
           ratio += hr;
           
-          ratio = EXP(ratio);
+          ratio = exp(ratio);
           alpha = MIN(1.,ratio);
           
           /* Always accept move */
@@ -8004,8 +9719,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]++;
             }
         }
@@ -8034,15 +9749,15 @@ void MCMC_PHYREX_Indel_Disk_Serial(t_tree *tree)
   type         = -1.0;
   n_trials     = (int)(PHYREX_Total_Number_Of_Intervals(tree)/2);
   T            = PHYREX_Tree_Height(tree);
-  log_one_on_T = -LOG(FABS(T));
+  log_one_on_T = -log(FABS(T));
   pindel       = 0.5;
 
   log_lk_centr = 0.0;
-  For(j,tree->mmod->n_dim) log_lk_centr += LOG(1./tree->mmod->lim->lonlat[j]);
+  for(j=0;j<tree->mmod->n_dim;j++) log_lk_centr += log(1./tree->mmod->lim->lonlat[j]);
 
   disk = tree->disk->prev;
 
-  For(i,n_trials)
+  for(i=0;i<n_trials;i++)
   /* do */
     {
       t = Uni()*T;
@@ -8062,7 +9777,7 @@ void MCMC_PHYREX_Indel_Disk_Serial(t_tree *tree)
       
       if(type < pindel) /* Insert */
         {
-          hr += LOG(FABS((t - disk->next->time)/T));
+          hr += log(FABS((t - disk->next->time)/T));
           hr -= log_one_on_T;
           hr -= log_lk_centr;
           
@@ -8072,7 +9787,7 @@ void MCMC_PHYREX_Indel_Disk_Serial(t_tree *tree)
           new_disk->time = t;
           PHYREX_Insert_Disk(new_disk,tree);
 
-          For(j,tree->mmod->n_dim) new_disk->centr->lonlat[j] = Uni()*tree->mmod->lim->lonlat[j];
+          for(j=0;j<tree->mmod->n_dim;j++) new_disk->centr->lonlat[j] = Uni()*tree->mmod->lim->lonlat[j];
 
           new_glnL += PHYREX_Lk_Range(new_disk,disk,tree);
           tree->mmod->c_lnL = new_glnL;
@@ -8082,7 +9797,7 @@ void MCMC_PHYREX_Indel_Disk_Serial(t_tree *tree)
           ratio  = (new_glnL - cur_glnL);
           ratio += hr;
           
-          ratio = EXP(ratio);
+          ratio = exp(ratio);
           alpha = MIN(1.,ratio);
           
           /* Always accept move */
@@ -8114,7 +9829,7 @@ void MCMC_PHYREX_Indel_Disk_Serial(t_tree *tree)
         {
           if(disk->ldsk != NULL) continue; /* Reject */
 
-          hr -= LOG(FABS((disk->time - disk->next->time)/T));
+          hr -= log(FABS((disk->time - disk->next->time)/T));
           hr += log_one_on_T;
           hr += log_lk_centr;
 
@@ -8127,7 +9842,7 @@ void MCMC_PHYREX_Indel_Disk_Serial(t_tree *tree)
           ratio  = (new_glnL - cur_glnL);
           ratio += hr;
           
-          ratio = EXP(ratio);
+          ratio = exp(ratio);
           alpha = MIN(1.,ratio);
           
           /* Always accept move */
@@ -8186,4 +9901,3 @@ void MCMC_PHYREX_Indel_Disk_Serial(t_tree *tree)
 ////////////////////////////////////////////////////////////*/
 /*////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////*/
-
diff --git a/src/mcmc.h b/src/mcmc.h
index e8baf3e..0d7f7a7 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,17 @@ 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_Times_All(t_tree *tree);
+void MCMC_Prune_Regraft(t_tree *tree);
+void MCMC_Randomize_Death(t_tree *tree);
+void MCMC_Time_Slice(t_tree *tree);
+void MCMC_Prune_Regraft_Local(t_tree *tree);
+void MCMC_Prune_Regraft_Weighted(t_tree *tree);
+void MCMC_Prune_Regraft_Root(t_tree *tree);
+void MCMC_Birth_Death_Updown(t_tree *tree);
+void MCMC_Rates_All(t_tree *tree);
+void MCMC_Times_And_Rates_Recur(t_node *a, t_node *d, int traversal, t_tree *tree);
+void MCMC_Times_And_Rates_All(t_tree *tree);
+void MCMC_Times_And_Rates_Root(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..ff5472c 100644
--- a/src/mixt.c
+++ b/src/mixt.c
@@ -21,7 +21,7 @@ void MIXT_Chain_All(t_tree *mixt_tree)
 {
   t_tree *curr, *next;
   int i;
-
+  
   curr = mixt_tree;
   next = mixt_tree->next;
 
@@ -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);
@@ -50,89 +51,127 @@ void MIXT_Chain_All(t_tree *mixt_tree)
     }
   while(next);
 
-  curr = mixt_tree;
-  do
-    {
-      MIXT_Chain_Edges(curr);
-      MIXT_Chain_Nodes(curr);
-      MIXT_Chain_Sprs(curr);
-      MIXT_Chain_Triplets(curr);
-
-      curr = curr->next;
-    }
-  while(curr);
-
+  MIXT_Chain_Edges(mixt_tree);
+  MIXT_Chain_Nodes(mixt_tree);
+  MIXT_Chain_Sprs(mixt_tree);
+  MIXT_Chain_Triplets(mixt_tree);
   Make_Rmat_Weight(mixt_tree);
   Make_Efrq_Weight(mixt_tree);
-
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-void MIXT_Chain_Edges(t_tree *tree)
+void MIXT_Chain_Edges(t_tree *mixt_tree)
 {
   int i;
   t_edge *b;
+  t_tree *tree;
 
-  For(i,2*tree->n_otu-1)
+  tree = mixt_tree;
+  do
     {
-      b = tree->a_edges[i];
-
-      if(tree->next)      b->next       = tree->next->a_edges[i];
-      if(tree->prev)      b->prev       = tree->prev->a_edges[i];
-      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];
+      For(i,2*tree->n_otu-1)
+        {
+          b = tree->a_edges[i];
+          
+          if(tree->next)      b->next       = tree->next->a_edges[i];
+          if(tree->prev)      b->prev       = tree->prev->a_edges[i];
+          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;
+        }
+      tree = tree->next;
     }
+  while(tree);
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-void MIXT_Chain_Nodes(t_tree *tree)
+void MIXT_Chain_Nodes(t_tree *mixt_tree)
 {
   int i;
   t_node *n;
+  t_tree *tree;
 
-  For(i,2*tree->n_otu-2)
+  tree = mixt_tree;
+  do
     {
-      n = tree->a_nodes[i];
-
-      if(tree->next)      n->next       = tree->next->a_nodes[i];
-      if(tree->prev)      n->prev       = tree->prev->a_nodes[i];
-      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];
+      For(i,2*tree->n_otu-2)
+        {
+          n = tree->a_nodes[i];
+          
+          if(tree->next)      n->next       = tree->next->a_nodes[i];
+          if(tree->prev)      n->prev       = tree->prev->a_nodes[i];
+          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;
+        }
+      tree = tree->next;
     }
+  while(tree);
 }
-
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-void MIXT_Chain_Sprs(t_tree *tree)
+void MIXT_Chain_Sprs(t_tree *mixt_tree)
 {
   int i;
+  t_tree *tree;
 
-  if(tree->next)      tree->best_spr->next      = tree->next->best_spr;
-  if(tree->prev)      tree->best_spr->prev      = tree->prev->best_spr;
-  if(tree->next_mixt) tree->best_spr->next_mixt = tree->next_mixt->best_spr;
-  if(tree->prev_mixt) tree->best_spr->prev_mixt = tree->prev_mixt->best_spr;
-
-  For(i,2*tree->n_otu-2)
+  tree = mixt_tree;
+  do
     {
-      if(tree->next)      tree->spr_list[i]->next      = tree->next->spr_list[i];
-      if(tree->prev)      tree->spr_list[i]->prev      = tree->prev->spr_list[i];
-      if(tree->next_mixt) tree->spr_list[i]->next_mixt = tree->next_mixt->spr_list[i];
-      if(tree->prev_mixt) tree->spr_list[i]->prev_mixt = tree->prev_mixt->spr_list[i];
+      if(tree->next)      tree->best_spr->next      = tree->next->best_spr;
+      if(tree->prev)      tree->best_spr->prev      = tree->prev->best_spr;
+      if(tree->next_mixt) tree->best_spr->next_mixt = tree->next_mixt->best_spr;
+      if(tree->prev_mixt) tree->best_spr->prev_mixt = tree->prev_mixt->best_spr;
+      
+      For(i,2*tree->n_otu-2)
+        {
+          if(tree->next)      tree->spr_list[i]->next      = tree->next->spr_list[i];
+          if(tree->prev)      tree->spr_list[i]->prev      = tree->prev->spr_list[i];
+          if(tree->next_mixt) tree->spr_list[i]->next_mixt = tree->next_mixt->spr_list[i];
+          if(tree->prev_mixt) tree->spr_list[i]->prev_mixt = tree->prev_mixt->spr_list[i];
+        }
+      tree = tree->next;
     }
+  while(tree);
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-void MIXT_Chain_Triplets(t_tree *tree)
+void MIXT_Chain_Triplets(t_tree *mixt_tree)
 {
-  if(tree->next)      tree->triplet_struct->next      = tree->next->triplet_struct;
-  if(tree->prev)      tree->triplet_struct->prev      = tree->prev->triplet_struct;
+  t_tree *tree;
+
+  tree = mixt_tree;
+  do
+    {
+      if(tree->next) tree->triplet_struct->next = tree->next->triplet_struct;
+      if(tree->prev) tree->triplet_struct->prev = tree->prev->triplet_struct;
+      tree = tree->next;
+    }
+  while(tree);
 }
 
 //////////////////////////////////////////////////////////////
@@ -447,88 +486,104 @@ void MIXT_Chain_RAS(t_ras *curr, t_ras *next)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-void MIXT_Turn_Branches_OnOff(int onoff, t_tree *mixt_tree)
+void MIXT_Chain_Rates(t_rate *curr, t_rate *next)
 {
-  int i;
-  t_tree *tree;
-
-  if(mixt_tree->is_mixt_tree == NO)
+  if(!next) return;
+  else
     {
-      PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__);
-      Exit("\n");
+      t_rate *buff,*last;
+
+      last = NULL;
+
+      buff = curr;
+      while(buff)
+        {
+          if(buff == next) break;
+          buff = buff->prev;
+        }
+
+      /*! Search forward */
+      if(!buff)
+        {
+          buff = curr;
+          while(buff)
+            {
+              if(buff == next) break;
+              buff = buff->next;
+            }
+        }
+
+      if(!buff)
+        {
+          last = curr;
+          while(last->next) { last = last->next; }
+
+          last->next = next;
+          next->prev = last;
+        }
     }
+}
 
-  tree = mixt_tree;
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
 
-  do
+void MIXT_Chain_Cal(t_tree *mixt_tree)
+{
+  int i;
+  for(i=0;i<mixt_tree->rates->n_cal-1;i++) 
     {
-      For(i,2*tree->n_otu-1) tree->a_edges[i]->l->onoff = onoff;
-      tree = tree->next;
+      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];
     }
-  while(tree && tree->is_mixt_tree == NO);
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-phydbl *MIXT_Get_Lengths_Of_This_Edge(t_edge *mixt_b, t_tree *mixt_tree)
+void MIXT_Turn_Branches_OnOff_In_All_Elem(int onoff, t_tree *mixt_tree)
 {
-  phydbl *lens;
-  t_edge *b;
   t_tree *tree;
-  int n_lens;
 
-  lens = NULL;
-  n_lens = 0;
-
-  b = mixt_b;
+  /*! Turn all branches to ON state */
   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;
-      tree = tree->next;
+      MIXT_Turn_Branches_OnOff_In_One_Elem(ON,tree);
+      tree = tree->next_mixt;
     }
-  while(b);
-
-  return(lens);
+  while(tree);
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-void MIXT_Set_Lengths_Of_This_Edge(phydbl *lens, t_edge *mixt_b, t_tree *mixt_tree)
+void MIXT_Turn_Branches_OnOff_In_One_Elem(int onoff, t_tree *mixt_tree)
 {
-  t_edge *b;
-  int n_lens;
+  int i;
   t_tree *tree;
 
-  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");
+    }
 
   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;
+      For(i,2*tree->n_otu-1) tree->a_edges[i]->l->onoff = onoff;
       tree = tree->next;
     }
-  while(b);
+  while(tree && tree->is_mixt_tree == NO);
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
 void MIXT_Post_Order_Lk(t_node *mixt_a, t_node *mixt_d, t_tree *mixt_tree)
 {
   t_tree *tree;
@@ -538,6 +593,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 +606,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 +632,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 +645,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;
@@ -596,101 +668,213 @@ phydbl MIXT_Lk(t_edge *mixt_b, t_tree *mixt_tree)
   t_tree *tree,*cpy_mixt_tree;
   t_edge *b,*cpy_mixt_b;
   phydbl sum_lnL;
-  int site, class, br;
+  unsigned int site, class, br, ns;
   phydbl *sum_scale_left_cat,*sum_scale_rght_cat;
-  phydbl sum,tmp;
-  int exponent;
+  phydbl sum;
   phydbl site_lk_cat,site_lk,log_site_lk,inv_site_lk;
-  int num_prec_issue,fact_sum_scale;
-  phydbl max_sum_scale,min_sum_scale;
+  int num_prec_issue;
   int ambiguity_check,state;
-  int k,l;
-  int dim1,dim2;
+  int l;
   phydbl r_mat_weight_sum, e_frq_weight_sum, sum_probas;
+  phydbl len;
+  phydbl *expl,*dot_prod;
+  
+  tree          = NULL;
+  b             = NULL;
+  expl          = NULL;
+  cpy_mixt_tree = mixt_tree;
+  cpy_mixt_b    = mixt_b;
+  len           = -1.;
+  ns            = 0;
+  
+  MIXT_Update_Br_Len_Multipliers(mixt_tree->mod);
 
-  tree            = NULL;
-  b               = NULL;
-  cpy_mixt_tree   = mixt_tree;
-  cpy_mixt_b      = mixt_b;
+#if (defined PHYTIME || defined INVITEE || defined PHYREX || defined DATE)
+  if((mixt_tree->rates) && (mixt_tree->rates->bl_from_rt)) MIXT_RATES_Update_Cur_Bl(mixt_tree);
+#endif
 
-  MIXT_Update_Br_Len_Multipliers(mixt_tree->mod);
+  /* Update RAS structure (mixt_tree level) */
+  tree = mixt_tree;
+  do
+    {
+      if(!cpy_mixt_b) Update_RAS(tree->mod);
+      tree = tree->next_mixt;
+    }
+  while(tree);
+
+  /* Update other model structure (tree level) */
+  tree = mixt_tree->next;
+  do
+    {
+      if(tree->is_mixt_tree == YES) tree = tree->next;
+      
+      if(!cpy_mixt_b)
+        {
+          Update_Boundaries(tree->mod);
+          Update_Efrq(tree->mod);
+          Update_Eigen(tree->mod);
+        }
+      
+      tree = tree->next;
+    }
+  while(tree);
 
+
+  
   do /*! Consider each element of the data partition */
     {
-      if(!cpy_mixt_b) Set_Model_Parameters(mixt_tree->mod);      
+      tree = mixt_tree->next;
+      do
+        {
+          tree->c_lnL = 0.0;
+          tree = tree->next;
+        }
+      while(tree && tree->is_mixt_tree == NO);
       
-      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)
+          for(br=0;br<2*mixt_tree->n_otu-3;++br) Update_PMat_At_Given_Edge(mixt_tree->a_edges[br],mixt_tree);
+
+          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
         {
           Update_PMat_At_Given_Edge(mixt_b,mixt_tree);
         }
-      
+            
       if(!cpy_mixt_b)
         {
-          if(mixt_tree->n_root)
+          if(mixt_tree->n_root != NULL)
             {
-              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);
+              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_Partial_Lk(mixt_tree,mixt_tree->n_root->b[1],mixt_tree->n_root);
+                  MIXT_Update_Partial_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_Post_Order_Lk(mixt_tree->e_root->rght,
+                                     mixt_tree->e_root->left,
+                                     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);
+                  MIXT_Post_Order_Lk(mixt_tree->e_root->left,
+                                     mixt_tree->e_root->rght,
+                                     mixt_tree);
 
-              if(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);
+                  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));
       sum_scale_rght_cat = (phydbl *)mCalloc(MAX(mixt_tree->mod->ras->n_catg,mixt_tree->mod->n_mixt_classes),sizeof(phydbl));
 
       r_mat_weight_sum = MIXT_Get_Sum_Chained_Scalar_Dbl(mixt_tree->next->mod->r_mat_weight);
       e_frq_weight_sum = MIXT_Get_Sum_Chained_Scalar_Dbl(mixt_tree->next->mod->e_frq_weight);
-      sum_probas       = MIXT_Get_Sum_Of_Probas_Across_Mixtures(r_mat_weight_sum, e_frq_weight_sum, mixt_tree);
+      sum_probas       = MIXT_Get_Sum_Of_Probas_Across_Mixtures(r_mat_weight_sum,e_frq_weight_sum,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;
+      do
         {
-          b    = mixt_b->next;
-          tree = mixt_tree->next;
+          while(tree->mod->ras->invar == YES)
+            {
+              tree = tree->next;
+              b    = b->next;
+
+              if(tree == NULL || tree->is_mixt_tree == YES)
+                {
+                  PhyML_Printf("\n== %p",(void *)tree);
+                  PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__);
+                  Exit("\n");
+                }
+            }
+
+          if(tree->update_eigen_lr == YES) Update_Eigen_Lr(b,tree);
+          
+          if(tree->use_eigen_lr == YES)
+            {
+              len = b->l->v;
+              len *= tree->mod->br_len_mult->v;
+              len *= tree->mixt_tree->mod->ras->gamma_rr->v[tree->mod->ras->parent_class_number];
+              if(len < tree->mod->l_min)      len = tree->mod->l_min;
+              else if(len > tree->mod->l_max) len = tree->mod->l_max;
+              expl = tree->expl;
+              for(l=0;l<tree->mod->ns;l++) expl[l] = (phydbl)POW(tree->mod->eigen->e_val[l],len);
+            }
+
+          tree = tree->next;
+          b    = b->next;
+
+        }
+      while(tree && tree->is_mixt_tree == NO);
+
 
 
+      mixt_tree->c_lnL = .0;
+      
+      for(site=0;site<mixt_tree->n_pattern;++site)
+        {
+          b    = mixt_b->next;
+          tree = mixt_tree->next;
+          
           /*! Skip calculations if model has zero rate */
           while(tree->mod->ras->invar == YES)
             {
               tree = tree->next;
               b    = b->next;
-              if(!tree || tree->is_mixt_tree == YES)
+
+              if(tree == NULL || tree->is_mixt_tree == YES)
                 {
                   PhyML_Printf("\n== %p",(void *)tree);
                   PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__);
@@ -709,175 +893,85 @@ phydbl MIXT_Lk(t_edge *mixt_b, t_tree *mixt_tree)
               if(!ambiguity_check) state = b->rght->c_seq->d_state[site];
             }
           
-          
           /*! For all classes in the mixture */
           do
             {
-              if(tree->is_mixt_tree)
+              if(tree->is_mixt_tree == YES)
                 {
                   tree = tree->next;
                   b    = b->next;
                 }
 
+              ns                     = tree->mod->ns;
               tree->curr_site        = site;
               tree->apply_lk_scaling = NO;
-
+              site_lk_cat            = 0.0;
+              expl                   = tree->expl;
+              dot_prod               = tree->dot_prod;
+              
               if(!(tree->mod->ras->invar == YES && mixt_tree->is_mixt_tree == YES) &&
                  (tree->data->wght[tree->curr_site] > SMALL))
                 {
-                  site_lk_cat = .0;
-
-                  if((b->rght->tax) && (!tree->mod->s_opt->greedy))
+                  if((b->rght->tax) && (tree->mod->s_opt->greedy == NO))
                     {
-                      if(!ambiguity_check)
-                        {
-                          sum = .0;
-                          For(l,tree->mod->ns)
-                            {
-                              sum +=
-                                b->Pij_rr[state*dim2+l] *
-                                b->p_lk_left[site*dim1+l];
-                            }
-
-                          site_lk_cat += sum * tree->mod->e_frq->pi->v[state];
-                        }
-                      else
-                        {
-                          For(k,tree->mod->ns)
-                            {
-                              sum = .0;
-                              if(b->p_lk_tip_r[site*dim2+k] > .0)
-                                {
-                                  For(l,tree->mod->ns)
-                                    {
-                                      sum +=
-                                        b->Pij_rr[k*dim2+l] *
-                                        b->p_lk_left[site*dim1+l];
-                                    }
-
-                                  site_lk_cat +=
-                                    sum *
-                                    tree->mod->e_frq->pi->v[k] *
-                                    b->p_lk_tip_r[site*dim2+k];
-                                }
-                            }
-                        }
+                      ambiguity_check = b->rght->c_seq->is_ambigu[tree->curr_site];
+                      if(ambiguity_check == NO) state = b->rght->c_seq->d_state[tree->curr_site];                        
+                    }
+                  
+                  if(tree->use_eigen_lr == YES)
+                    {
+                      site_lk_cat = Lk_Core_Eigen_Lr(expl,dot_prod + site*ns,NO,b,tree);
                     }
                   else
                     {
-                      For(k,tree->mod->ns)
-                        {
-                          sum = .0;
-                          if(b->p_lk_rght[site*dim1+k] > .0)
-                            {
-                              For(l,tree->mod->ns)
-                                {
-                                  sum +=
-                                    b->Pij_rr[k*dim2+l] *
-                                    b->p_lk_left[site*dim1+l];
-                                }
-
-                              site_lk_cat +=
-                                sum *
-                                tree->mod->e_frq->pi->v[k] *
-                                b->p_lk_rght[site*dim1+k];
-                            }
-                        }
+                      if(b->rght->tax == YES)
+                        site_lk_cat = Lk_Core(state,ambiguity_check,NO,
+                                              b->p_lk_left + site*ns,
+                                              b->p_lk_tip_r + site*ns,
+                                              b->Pij_rr,b,tree);
+                      else
+                        site_lk_cat = Lk_Core(state,ambiguity_check,NO,
+                                              b->p_lk_left + site*ns,
+                                              b->p_lk_rght  + site*ns,
+                                              b->Pij_rr,b,tree);
                     }
-                  tree->site_lk_cat[0] = site_lk_cat;
                 }
-              tree = tree->next;
-              b    = b->next;
-            }
-          while(tree && tree->is_mixt_tree == NO);
-
-
-          max_sum_scale =  (phydbl)BIG;
-          min_sum_scale = -(phydbl)BIG;
-
-          tree  = mixt_tree->next;
-          b     = mixt_b->next;
-          class = 0;
-          do
-            {
-              if(tree->mod->ras->invar == YES)
-                {
-                  tree = tree->next;
-                  b    = b->next;
-                  if(!(tree && tree->is_mixt_tree == NO)) break;
-                }
-
-              sum_scale_left_cat[class] =
+                            
+              sum_scale_left_cat[tree->mod->ras->parent_class_number] =
                 (b->sum_scale_left)?
                 (b->sum_scale_left[site]):
                 (0.0);
 
-              sum_scale_rght_cat[class] =
+              sum_scale_rght_cat[tree->mod->ras->parent_class_number] =
                 (b->sum_scale_rght)?
                 (b->sum_scale_rght[site]):
                 (0.0);
 
-              sum = sum_scale_left_cat[class] + sum_scale_rght_cat[class];
-
-              if(sum < .0)
-                {
-                  PhyML_Printf("\n== sum = %G",sum);
-                  PhyML_Printf("\n== Err in file %s at line %d\n\n",__FILE__,__LINE__);
-                  Warn_And_Exit("\n");
-                }
-
-              tmp = sum + ((phydbl)LOGBIG - LOG(tree->site_lk_cat[0]))/(phydbl)LOG2;
-              if(tmp < max_sum_scale) max_sum_scale = tmp; /* min of the maxs */
+              sum =
+                sum_scale_left_cat[tree->mod->ras->parent_class_number] +
+                sum_scale_rght_cat[tree->mod->ras->parent_class_number];
 
-              tmp = sum + ((phydbl)LOGSMALL - LOG(tree->site_lk_cat[0]))/(phydbl)LOG2;
-              if(tmp > min_sum_scale) min_sum_scale = tmp; /* max of the mins */
+              site_lk_cat /= pow(2,sum);
 
-              class++;
+              /* printf("\n\u2022 site: %4d lk: %12G class: %3d sum: %12G", */
+              /*        site, */
+              /*        site_lk_cat, */
+              /*        tree->mod->ras->parent_class_number,sum); */
 
+              tree->site_lk_cat[0] = site_lk_cat;
+                      
               tree = tree->next;
-              b    = b->next;
+              b    = b->next;          
             }
-          while(tree && tree->is_mixt_tree == NO);
+          while(tree && tree->is_mixt_tree == NO); 
+          // done with all trees in the mixture for this partition element.
+          // All likelihood values are in site_lk_cat[0]
+          
 
-          tree = NULL; /*! For debugging purpose */
-
-          if(min_sum_scale > max_sum_scale) min_sum_scale = max_sum_scale;
-
-          fact_sum_scale = (int)((max_sum_scale + min_sum_scale) / 2);
-
-
-          /*! Populate the mixt_tree->site_lk_cat[class] table after
-            scaling */
-
-          tree  = mixt_tree->next;
-          b     = mixt_b->next;
-          class = 0;
-
-          do
-            {
-              if(tree->mod->ras->invar == YES)
-                {
-                  tree = tree->next;
-                  b    = b->next;
-                  if(!(tree && tree->is_mixt_tree == NO)) break;
-                }
-
-              exponent = -(sum_scale_left_cat[class]+sum_scale_rght_cat[class])+fact_sum_scale;
-              site_lk_cat = tree->site_lk_cat[0];
-              Rate_Correction(exponent,&site_lk_cat,mixt_tree);
-              mixt_tree->site_lk_cat[class] = site_lk_cat;
-              tree->site_lk_cat[0] = site_lk_cat;
-              class++;
-
-              tree = tree->next;
-              b    = b->next;
-            }
-          while(tree && tree->is_mixt_tree == NO);
-
-          tree    = mixt_tree->next;
-          b       = mixt_b->next;
-          class   = 0;
-          site_lk = .0;
+          tree    = mixt_tree->next;
+          b       = mixt_b->next;
+          class   = 0;
+          site_lk = .0;
 
           do
             {
@@ -889,25 +983,24 @@ phydbl MIXT_Lk(t_edge *mixt_b, t_tree *mixt_tree)
                 }
 
               site_lk +=
-                mixt_tree->site_lk_cat[class] *
+                tree->site_lk_cat[0] *
                 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;
-
-                /* 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); */
-
+              
+              /* printf("\n. site_lk: %G site_lk: %G [%G %G %G]", */
+              /*        tree->site_lk_cat[0],site_lk, */
+              /*        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;
               b    = b->next;
-              class++;
             }
           while(tree && tree->is_mixt_tree == NO);
 
+
           /* Scaling for invariants */
           if(mixt_tree->mod->ras->invar == YES)
             {
@@ -917,7 +1010,7 @@ phydbl MIXT_Lk(t_edge *mixt_b, t_tree *mixt_tree)
               while(tree->mod->ras->invar == NO)
                 {
                   tree = tree->next;
-                  if(!tree || tree->is_mixt_tree == YES)
+                  if(tree == NULL || tree->is_mixt_tree == YES)
                     {
                       PhyML_Printf("\n== tree: %p",tree);
                       PhyML_Printf("\n== Err in file %s at line %d",__FILE__,__LINE__);
@@ -925,10 +1018,8 @@ phydbl MIXT_Lk(t_edge *mixt_b, t_tree *mixt_tree)
                     }
                 }
 
-              tree->apply_lk_scaling = YES;
-
               /*! 'tree' will give the correct state frequencies (as opposed to mixt_tree */
-              inv_site_lk = Invariant_Lk(fact_sum_scale,site,&num_prec_issue,tree);
+              inv_site_lk = Invariant_Lk(0,site,&num_prec_issue,tree);
 
               if(num_prec_issue == YES) // inv_site_lk >> site_lk
                 {
@@ -940,51 +1031,36 @@ 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_class = 0;
-              tree = mixt_tree->next;
-              do
-                {
-                  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;
-                      break;
-                    }
-                  mixt_class++;
-                  tree = tree->next;
-                }
-              while(tree && tree->is_mixt_tree == NO);
-            }
-
+          log_site_lk = log(site_lk);
+          
           if(isinf(log_site_lk) || isnan(log_site_lk))
             {
-              PhyML_Printf("\n== Site = %d",site);
-              PhyML_Printf("\n== Invar = %d",mixt_tree->data->invar[site]);
-              PhyML_Printf("\n== Mixt = %d",mixt_tree->is_mixt_tree);
-              PhyML_Printf("\n== Lk = %G LOG(Lk) = %f < %G",site_lk,log_site_lk,-BIG);
-              For(class,mixt_tree->mod->ras->n_catg) PhyML_Printf("\n== rr=%f p=%f",mixt_tree->mod->ras->gamma_rr->v[class],mixt_tree->mod->ras->gamma_r_proba->v[class]);
-              PhyML_Printf("\n== Pinv = %G",mixt_tree->mod->ras->pinvar->v);
-              PhyML_Printf("\n== Bl mult = %G",mixt_tree->mod->br_len_mult->v);
-              PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__);
+              PhyML_Printf("\n== site = %d",site);
+              PhyML_Printf("\n== invar = %d",mixt_tree->data->invar[site]);
+              PhyML_Printf("\n== mixt = %d",mixt_tree->is_mixt_tree);
+              PhyML_Printf("\n== lk = %G log(lk) = %f < %G",site_lk,log_site_lk,-BIG);
+              for(class=0;class<mixt_tree->mod->ras->n_catg;class++) PhyML_Printf("\n== rr=%f p=%f",mixt_tree->mod->ras->gamma_rr->v[class],mixt_tree->mod->ras->gamma_r_proba->v[class]);
+              PhyML_Printf("\n== pinv = %G",mixt_tree->mod->ras->pinvar->v);
+              PhyML_Printf("\n== bl mult = %G",mixt_tree->mod->br_len_mult->v);
+              PhyML_Printf("\n== Err. in file %s at line %d.\n",__FILE__,__LINE__);
               Exit("\n");
             }
-
-          mixt_tree->cur_site_lk[site] = log_site_lk;
-
+                    
+          // ... or using the log-likelihood
+          if(isinf(site_lk) || isnan(site_lk))
+            {
+              mixt_tree->cur_site_lk[site] = exp(log_site_lk);
+            }
+          else
+            {
+              mixt_tree->cur_site_lk[site] = 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;
 
+          
           mixt_tree->c_lnL += mixt_tree->data->wght[site]*log_site_lk;
-          /*   tree->sum_min_sum_scale += (int)tree->data->wght[site]*min_sum_scale; */
 
         }
 
@@ -1023,26 +1099,40 @@ phydbl MIXT_Lk(t_edge *mixt_b, t_tree *mixt_tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-void MIXT_Update_Eigen(t_mod *mixt_mod)
+void MIXT_Update_Partial_Lk(t_tree *mixt_tree, t_edge *mixt_b, t_node *mixt_d)
 {
-  t_mod *mod;
+  t_tree *tree;
+  t_edge *b;
+  t_node *d;
 
-  mod = mixt_mod;
+  tree = mixt_tree;
+  b    = mixt_b;
+  d    = mixt_d;
 
   do
     {
-      if(mod->is_mixt_mod) mod = mod->next;
-      Update_Eigen(mod);
-      mod = mod->next;
+      if(tree->is_mixt_tree)
+        {
+          tree = tree->next;
+          b    = b->next;
+          d    = d->next;
+        }
+
+      if(tree->mod->ras->invar == NO) Update_Partial_Lk(tree,b,d);
+
+      tree = tree->next;
+      b    = b->next;
+      d    = d->next;
+
     }
-  while(mod);
+  while(tree);
 
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-void MIXT_Update_P_Lk(t_tree *mixt_tree, t_edge *mixt_b, t_node *mixt_d)
+void MIXT_Update_Partial_Pars(t_tree *mixt_tree, t_edge *mixt_b, t_node *mixt_d)
 {
   t_tree *tree;
   t_edge *b;
@@ -1061,7 +1151,7 @@ void MIXT_Update_P_Lk(t_tree *mixt_tree, t_edge *mixt_b, t_node *mixt_d)
           d    = d->next;
         }
 
-      Update_P_Lk(tree,b,d);
+      Update_Partial_Pars(tree,b,d);
 
       tree = tree->next;
       b    = b->next;
@@ -1097,7 +1187,6 @@ void MIXT_Update_PMat_At_Given_Edge(t_edge *mixt_b, t_tree *mixt_tree)
       b    = b->next;
     }
   while(tree);
-
 }
 
 //////////////////////////////////////////////////////////////
@@ -1111,14 +1200,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;
@@ -1357,7 +1446,7 @@ void MIXT_Check_RAS_Struct_In_Each_Partition_Elem(t_tree *mixt_tree)
                       PhyML_Printf("\n== The invariant site class has to be the first element in");
                       PhyML_Printf("\n== each <mixtureelem> component. Please amend you XML");
                       PhyML_Printf("\n== file accordingly.\n");
-                      Exit("\n.");
+                      Exit("\n\u2022");
                     }
                 }
               tree  = tree->next;
@@ -1397,23 +1486,23 @@ 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;
-  d        = mixt_d;
-  target   = *mixt_target;
-  residual = *mixt_residual;
+  d        = mixt_d;  
+  target   = (mixt_target) ? (*mixt_target) : NULL;
+  residual = (mixt_residual) ? (*mixt_residual) : NULL;
 
   do
     {
-      if(tree->is_mixt_tree)
+      if(tree->is_mixt_tree == YES)
         {
           tree     = tree->next;
           a        = a->next;
           d        = d->next;
-          target   = target->next;
-          residual = residual->next;
+          target   = target ? target->next : NULL;
+          residual = residual ? residual->next : NULL;
         }
 
       Prune_Subtree(a,d,&target,&residual,tree);
@@ -1421,8 +1510,8 @@ void MIXT_Prune_Subtree(t_node *mixt_a, t_node *mixt_d, t_edge **mixt_target, t_
       tree     = tree->next;
       a        = a->next;
       d        = d->next;
-      target   = target->next;
-      residual = residual->next;
+      target   = target ? target->next : NULL;
+      residual = residual ? residual->next : NULL;
     }
   while(tree && tree->is_mixt_tree == NO);
 
@@ -1432,61 +1521,64 @@ 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);
 
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-void MIXT_Graft_Subtree(t_edge *mixt_target, t_node *mixt_link, t_edge *mixt_residual, t_tree *mixt_tree)
+void MIXT_Graft_Subtree(t_edge *mixt_target, t_node *mixt_link, t_node *mixt_link_daughter, t_edge *mixt_residual, t_node *mixt_target_nd, t_tree *mixt_tree)
 {
   t_edge *target,*residual;
-  t_node *link;
+  t_node *link,*link_daughter,*target_nd;
   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;
-  residual = mixt_residual;
-  link     = mixt_link;
+  tree          = mixt_tree;
+  target        = mixt_target;
+  residual      = mixt_residual;
+  link          = mixt_link;
+  link_daughter = mixt_link_daughter;
+  target_nd     = mixt_target_nd;
 
   do
     {
-      if(tree->is_mixt_tree)
+      if(tree->is_mixt_tree == YES)
         {
-          tree     = tree->next;
-          target   = target->next;
-          residual = residual->next;
-          link     = link->next;
+          tree          = tree->next;
+          target        = target->next;
+          residual      = residual->next;
+          link          = link->next;
+          link_daughter = link_daughter ? link_daughter->next : NULL;
+          target_nd     = target_nd ? target_nd->next : NULL;
         }
 
-      Graft_Subtree(target,link,residual,tree);
+      Graft_Subtree(target,link,link_daughter,residual,target_nd,tree);
 
-      tree     = tree->next;
-      target   = target->next;
-      residual = residual->next;
-      link     = link->next;
+      tree          = tree->next;
+      target        = target->next;
+      residual      = residual->next;
+      link          = link->next;
+      link_daughter = link_daughter ? link_daughter->next : NULL;
+      target_nd     = target_nd ? target_nd->next : NULL;
     }
   while(tree && tree->is_mixt_tree == NO);
 
-  if(tree) Graft_Subtree(target,link,residual,tree);
+  if(tree) Graft_Subtree(target,link,link_daughter,residual,target_nd,tree);
 
   /*! Turn branches of this mixt_tree to ON after recursive call
     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);
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-void MIXT_Br_Len_Brent(phydbl prop_min,
-                       phydbl prop_max,
-                       t_edge *mixt_b,
-                       t_tree *mixt_tree)
+void MIXT_Br_Len_Brent(t_edge *mixt_b, t_tree *mixt_tree)
 {
   t_tree *tree;
   t_edge *b;
@@ -1496,27 +1588,24 @@ void MIXT_Br_Len_Brent(phydbl prop_min,
 
   do
     {
-      if(tree->is_mixt_tree)
+      if(tree->is_mixt_tree == YES)
         {
           tree = tree->next;
           b    = b->next;
         }
 
-      Br_Len_Brent(prop_min,prop_max,b,tree);
+      Br_Len_Brent(b,tree);
+      
+      b->l->onoff = OFF; // Will not optimize that edge length later on in this loop
 
-      b->l->onoff = OFF;
       tree = tree->next;
       b    = b->next;
     }
   while(tree);
 
-  tree = mixt_tree;
-  do
-    {
-      MIXT_Turn_Branches_OnOff(ON,tree);
-      tree = tree->next_mixt;
-    }
-  while(tree);
+  // Updates likelihood of mixt_tree
+  MIXT_Lk(mixt_b,mixt_tree);
+  MIXT_Turn_Branches_OnOff_In_All_Elem(ON,mixt_tree);
 }
 
 /*////////////////////////////////////////////////////////////
@@ -1665,7 +1754,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 +1807,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);
 
@@ -1734,6 +1843,8 @@ void MIXT_Bootstrap(char *best_tree, xml_node *root)
   xml_node *n,*p_elem;
   char *bootstrap;
 
+  assert(root);
+  
   n = XML_Search_Node_Name("phyml",NO,root);
 
   bootstrap = XML_Get_Attribute_Value(n,"bootstrap");
@@ -1745,7 +1856,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;
@@ -1774,7 +1885,7 @@ void MIXT_Bootstrap(char *best_tree, xml_node *root)
       n_boot = atoi(bootstrap);
 
       io = NULL;
-      For(i,n_boot)
+      for(i=0;i<n_boot;i++)
         {
           boot_root = XML_Copy_XML_Graph(root);
 
@@ -1829,7 +1940,7 @@ void MIXT_Bootstrap(char *best_tree, xml_node *root)
               For(j,boot_data[0]->len)
                 {
                   position = Rand_Int(0,(int)(boot_data[0]->len-1.0));
-                  For(k,io->n_otu)
+                  for(k=0;k<io->n_otu;k++)
                     {
                       boot_data[k]->state[j] = orig_data[k]->state[position];
                     }
@@ -1867,7 +1978,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;
@@ -1916,6 +2028,8 @@ phydbl MIXT_Get_Mean_Edge_Len(t_edge *mixt_b, t_tree *mixt_tree)
   t_tree *tree;
   t_edge *b;
 
+  if(mixt_tree->is_mixt_tree == NO) return mixt_b->l->v;
+  
   b    = mixt_b;
   tree = mixt_tree;
   sum  = .0;
@@ -1928,7 +2042,7 @@ phydbl MIXT_Get_Mean_Edge_Len(t_edge *mixt_b, t_tree *mixt_tree)
           b    = b->next;
         }
 
-      sum += b->l->v * tree->mixt_tree->mod->br_len_mult->v;
+      sum += b->l->v * (tree->mixt_tree ? tree->mixt_tree->mod->br_len_mult->v : 1.0);
       n++;
       b    = b->next;
       tree = tree->next;
@@ -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,19 +2106,97 @@ 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;
+  
+  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
+    {
+      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);
+
+  tree = mixt_tree;
+  do
+    {
+      assert(tree->n_root != NULL);
+      
+      if(tree->next)      tree->n_root->next       = tree->next->n_root;
+      if(tree->prev)      tree->n_root->prev       = tree->prev->n_root;
+      if(tree->next_mixt) tree->n_root->next_mixt  = tree->next_mixt->n_root;
+      if(tree->prev_mixt) tree->n_root->prev_mixt  = tree->prev_mixt->n_root;
+
+      tree = tree->next;
+    }
+  while(tree);
+
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void MIXT_RATES_Update_Cur_Bl(t_tree *mixt_tree)
 {
   t_tree *tree;
 
   tree = mixt_tree->next;
-  
   do
     {
-      Set_Br_Len_Var(tree);
+      RATES_Update_Cur_Bl(tree);
       tree = tree->next;
     }
   while(tree);
-  
 }
 
 //////////////////////////////////////////////////////////////
@@ -2032,7 +2229,7 @@ void MIXT_Update_Br_Len_Multipliers(t_mod *mod)
         {
           loc->br_len_mult->v = loc->br_len_mult_unscaled->v / sum;
           loc->br_len_mult->v *= (phydbl)(n_mixt);
-          /* printf("\n. HERE %f %f\n",loc->br_len_mult_unscaled->v,loc->br_len_mult->v); */
+          /* printf("\n\u2022 HERE %f %f\n",loc->br_len_mult_unscaled->v,loc->br_len_mult->v); */
         }
       loc = loc->next_mixt;
     }
@@ -2042,13 +2239,1000 @@ 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 != NULL)
+        {
+          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;
+  
+  if(mixt_tree->io->mod->s_opt->random_input_tree == NO)
+    {
+      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);
+        }
+    }
+  else
+    {
+      tree = Make_Tree_From_Scratch(mixt_tree->n_otu,mixt_tree->data);
+      Random_Tree(tree);
+    }
+  
+  return tree;
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void MIXT_Connect_Cseqs_To_Nodes(t_tree *mixt_tree)
+{
+  t_tree *tree;
+  
+  Copy_Tree(mixt_tree,mixt_tree->next);
+  
+  tree = mixt_tree;
+  do
+    {
+      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\u2022 [%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_Ancestral_Sequences_One_Node(t_node *mixt_d, t_tree *mixt_tree, int print)
+{
+  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=0;site<curr_mixt_tree->n_pattern;site++) // For each site in the current partition element */
+          for(site=0;site<curr_mixt_tree->data->init_len;site++) // 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=0;i<tree->mod->ns;i++) 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=0;catg<tree->mod->ras->n_catg;catg++)
+                    {
+                      for(i=0;i<Ns;i++)
+                        {
+                          p0 = .0;
+                          if(v0->tax)
+                            for(j=0;j<tree->mod->ns;j++)
+                              {
+                                p0 += v0->b[0]->p_lk_tip_r[csite*Ns+j] * Pij0[catg*NsNs+i*Ns+j];
+
+                                /* printf("\n\u2022 p0 %d %f", */
+                                /*        v0->b[0]->p_lk_tip_r[site*Ns+j], */
+                                /*        Pij0[catg*NsNs+i*Ns+j]); */
+                              }
+                          else
+                            for(j=0;j<tree->mod->ns;j++)
+                              {
+                                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\u2022 p0 %f %f", */
+                                /*        p_lk0[site*NsNg+catg*Ns+j], */
+                                /*        Pij0[catg*NsNs+i*Ns+j]); */
+                              }
+                          p1 = .0;
+                          if(v1->tax)
+                            for(j=0;j<tree->mod->ns;j++)
+                              {
+                                p1 += v1->b[0]->p_lk_tip_r[csite*Ns+j] * Pij1[catg*NsNs+i*Ns+j];
+
+                                /* printf("\n\u2022 p1 %d %f", */
+                                /*        v1->b[0]->p_lk_tip_r[site*Ns+j], */
+                                /*        Pij1[catg*NsNs+i*Ns+j]); */
+                              }
+
+                          else
+                            for(j=0;j<tree->mod->ns;j++)
+                              {
+                                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\u2022 p1 %f %f", */
+                                /*        p_lk1[site*NsNg+catg*Ns+j], */
+                                /*        Pij1[catg*NsNs+i*Ns+j]); */
+                             }
+
+
+                          p2 = .0;
+                          if(v2->tax)
+                            for(j=0;j<tree->mod->ns;j++)
+                              {
+                                p2 += v2->b[0]->p_lk_tip_r[csite*Ns+j] * Pij2[catg*NsNs+i*Ns+j];
+                                /* printf("\n\u2022 p2 %d %f", */
+                                /*        v2->b[0]->p_lk_tip_r[site*Ns+j], */
+                                /*        Pij2[catg*NsNs+i*Ns+j]); */
+                              }
+                          else
+                            for(j=0;j<tree->mod->ns;j++)
+                              {
+                                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\u2022 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;
+
+                          if(print == YES)
+                            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]);
+                        }
+                    }
+                  
+                  if(print == YES)
+                    {
+                      PhyML_Fprintf(fp,"%4d\t%4d\t",site+1,d->num);
+                      for(i=0;i<Ns;i++)
+                        {
+                          PhyML_Fprintf(fp,"%.4f\t",p[i]);
+                        }
+                      PhyML_Fprintf(fp,"\n");
+                      fflush(NULL);
+                    }
+
+                  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);
+    }
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+// First and second derivative of the log-likelihood with respect
+// to the length of edge b
+phydbl MIXT_dLk(phydbl *l, t_edge *mixt_b, t_tree *mixt_tree)
+{
+  t_tree *tree,*cpy_mixt_tree;
+  t_edge *b,*cpy_mixt_b;
+  int site, class, n_tot_classes, ns, state;
+  phydbl *sum_scale_left_cat,*sum_scale_rght_cat;
+  phydbl sum,mult;
+  phydbl *lk,*dlk,*d2lk;
+  phydbl dlnlk,d2lnlk;
+  phydbl site_lk,site_dlk,site_d2lk;
+  phydbl log_site_lk,inv_site_lk;
+  int num_prec_issue;
+  phydbl r_mat_weight_sum, e_frq_weight_sum, sum_probas;
+  phydbl len;
+  phydbl *expl,*expld,*expld2,*dot_prod;
+  phydbl rr;
+  phydbl ev,expevlen;
+  phydbl one_m_pinv;
+  
+  tree          = NULL;
+  b             = NULL;
+  expl          = NULL;
+  expld         = NULL;
+  expld2        = NULL;
+  lk            = NULL;
+  dlk           = NULL;
+  d2lk          = NULL;
+  cpy_mixt_tree = mixt_tree;
+  cpy_mixt_b    = mixt_b;
+  len           = -1.;
+  
+  if(mixt_tree->update_eigen_lr == YES) MIXT_Update_Eigen_Lr(mixt_b,mixt_tree);
+    
+  do /*! Consider each element of the data partition */
+    {
+      tree = mixt_tree->next;
+      do
+        {
+          tree->c_lnL   = .0;
+          tree->c_dlnL  = .0;
+          tree->c_d2lnL = .0;
+
+          tree = tree->next;
+        }
+      while(tree && tree->is_mixt_tree == NO);
+
+      ns = mixt_tree->mod->ns;
+      n_tot_classes = MIXT_Mixt_Size(mixt_tree);
+      
+      lk   = (phydbl *)mCalloc(n_tot_classes,sizeof(phydbl));
+      dlk  = (phydbl *)mCalloc(n_tot_classes,sizeof(phydbl));
+      d2lk = (phydbl *)mCalloc(n_tot_classes,sizeof(phydbl));
+
+      sum_scale_left_cat = (phydbl *)mCalloc(n_tot_classes,sizeof(phydbl));
+      sum_scale_rght_cat = (phydbl *)mCalloc(n_tot_classes,sizeof(phydbl));
+
+      r_mat_weight_sum = MIXT_Get_Sum_Chained_Scalar_Dbl(mixt_tree->next->mod->r_mat_weight);
+      e_frq_weight_sum = MIXT_Get_Sum_Chained_Scalar_Dbl(mixt_tree->next->mod->e_frq_weight);
+      sum_probas       = MIXT_Get_Sum_Of_Probas_Across_Mixtures(r_mat_weight_sum,e_frq_weight_sum,mixt_tree);
+      
+
+      // Fill in expl, expld and expld2 vectors for each rate class
+      tree = mixt_tree->next;
+      class = 0;
+      do
+        {          
+          if(tree->mod->ras->invar == YES) rr = 0.0;
+          else                             
+            {
+              rr = 1.0;
+              rr *= tree->mod->br_len_mult->v;
+              rr *= mixt_tree->mod->ras->gamma_rr->v[tree->mod->ras->parent_class_number];
+            }
+
+          len = (*l) * rr;
+          
+          if(isinf(len) || isnan(len)) 
+            {
+              PhyML_Printf("\n== len=%f rr=%f l=%f",len,rr,*l);
+              Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
+            }
+          
+          if(tree->mod->ras->invar == NO) 
+            {
+              if(len < tree->mod->l_min)      len = tree->mod->l_min;
+              else if(len > tree->mod->l_max) len = tree->mod->l_max;
+            }
+          else
+            {
+              len = 0.0;
+            }
+          
+          dot_prod = tree->dot_prod;
+          expl = tree->expl;
+          
+          for(state=0;state<tree->mod->ns;++state) 
+            {
+              ev = log(tree->mod->eigen->e_val[state]);
+              expevlen = exp(ev*len);
+
+              expl[0*ns + state] = expevlen;
+              expl[1*ns + state] = expevlen*ev*rr;
+              expl[2*ns + state] = expevlen*ev*ev*rr*rr;
+            }
+                    
+          class++;
+
+          tree = tree->next;
+        }
+      while(tree && tree->is_mixt_tree == NO); 
+
+      assert(class == n_tot_classes);
+
+      mixt_tree->c_lnL   = .0;
+      mixt_tree->c_dlnL  = .0;
+      mixt_tree->c_d2lnL = .0;
+      dlnlk              = 0.0;
+      d2lnlk             = 0.0;
+      
+      for(site=0;site<mixt_tree->n_pattern;++site)
+        {
+          b     = mixt_b->next;
+          tree  = mixt_tree->next;
+          
+          for(class=0;class<n_tot_classes;++class)
+            {
+              dlk[class]  = 0.0;
+              d2lk[class] = 0.0;
+              lk[class]   = 0.0;
+            }
+          
+          class = 0;
+          /*! For all classes in the mixture */
+          do
+            {
+              if(tree->mod->ras->invar == NO && tree->data->wght[tree->curr_site] > SMALL)
+                {
+                  tree->curr_site        = site;
+                  tree->apply_lk_scaling = NO;
+                  dot_prod               = tree->dot_prod;
+                  expl                   = tree->expl;
+                  expld                  = expl + 1*ns;
+                  expld2                 = expl + 2*ns;
+                  
+                  dlk[class]  = Lk_Core_Eigen_Lr(expld ,dot_prod + site*ns,YES,b,tree);
+                  d2lk[class] = Lk_Core_Eigen_Lr(expld2,dot_prod + site*ns,YES,b,tree);
+                  lk[class]   = Lk_Core_Eigen_Lr(expl  ,dot_prod + site*ns,NO ,b,tree);
+                
+                  
+                  sum_scale_left_cat[tree->mod->ras->parent_class_number] =
+                    (b->sum_scale_left)?
+                    (b->sum_scale_left[site]):
+                    (0.0);
+                  
+                  sum_scale_rght_cat[tree->mod->ras->parent_class_number] =
+                    (b->sum_scale_rght)?
+                    (b->sum_scale_rght[site]):
+                    (0.0);
+                  
+                  sum =
+                    sum_scale_left_cat[tree->mod->ras->parent_class_number] +
+                    sum_scale_rght_cat[tree->mod->ras->parent_class_number];
+                  
+                  mult = pow(2,sum);
+                  
+                  dlk[class]  /= mult;
+                  d2lk[class] /= mult;
+                  lk[class]   /= mult;
+
+                  class++;
+                }
+              
+              tree = tree->next;
+              b    = b->next;
+            }
+          while(tree && tree->is_mixt_tree == NO); 
+          // done with all trees in the mixture for this partition element.
+          // All likelihood values are in site_lk_cat[0]
+
+          
+          tree      = mixt_tree->next;
+          class     = 0;
+          site_lk   = .0;
+          site_dlk  = .0;
+          site_d2lk = .0;
+
+          if(mixt_tree->mod->ras->invar == YES) one_m_pinv = 1. - mixt_tree->mod->ras->pinvar->v;
+          else one_m_pinv = 1.;
+            
+
+          do
+            {              
+              if(tree->mod->ras->invar == NO && tree->data->wght[tree->curr_site] > SMALL)
+                {
+                  site_lk +=
+                    lk[class] *
+                    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;
+
+
+                  site_dlk +=
+                    dlk[class] *
+                    one_m_pinv *
+                    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;
+                  
+                  site_d2lk +=
+                    d2lk[class] *
+                    one_m_pinv *
+                    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;
+
+                  class++;
+                }
+              
+              tree = tree->next;
+                  
+            }
+          while(tree && tree->is_mixt_tree == NO);
+
+          /* printf("\nc site: %4d l:%15G lk:%15G dlk:%15G d2lk:%15G",site,mixt_b->l->v,site_lk,site_dlk,site_d2lk); */
+
+                  
+          /* Scaling for invariants */
+          if(mixt_tree->mod->ras->invar == YES)
+            {
+              num_prec_issue = NO;
+
+              tree = mixt_tree->next;
+              while(tree->mod->ras->invar == NO)
+                {
+                  tree = tree->next;
+                  if(!tree || tree->is_mixt_tree == YES)
+                    {
+                      PhyML_Printf("\n== tree: %p",tree);
+                      PhyML_Printf("\n== Err in file %s at line %d",__FILE__,__LINE__);
+                      Exit("\n");
+                    }
+                }
+
+              tree->apply_lk_scaling = YES;
+
+              /*! 'tree' will give the correct state frequencies (as opposed to mixt_tree) */              
+              inv_site_lk = Invariant_Lk(0,site,&num_prec_issue,tree);
+
+
+              if(num_prec_issue == YES) // inv_site_lk >> site_lk
+                {
+                  site_lk = inv_site_lk * mixt_tree->mod->ras->pinvar->v;
+                }
+              else
+                {
+                  site_lk = site_lk * (1. - mixt_tree->mod->ras->pinvar->v) + inv_site_lk * mixt_tree->mod->ras->pinvar->v;
+                }
+            }
+
+
+          /* Note: no need to 'remove' in two terms below part of scaling factor that is 
+             common to all classes of the mixtures. Indeed, this factor cancels out in 
+             site_dlk/site_lk as well as in site_d2lk/site_lk */
+
+          dlnlk  += mixt_tree->data->wght[site] * ( site_dlk / site_lk );
+          d2lnlk += mixt_tree->data->wght[site] * ( site_d2lk / site_lk - (site_dlk / site_lk) * (site_dlk / site_lk) );
+          
+          /* printf("\n\u2022 dlnlk: %f d2lnlk: %f wght: %f site_dlk: %f site_d2lk: %f",dlnlk,d2lnlk,mixt_tree->data->wght[site],site_dlk,site_d2lk); */
+
+          log_site_lk = log(site_lk);
+
+          if(isinf(log_site_lk) || isnan(log_site_lk))
+            {
+              PhyML_Printf("\n== site = %d",site);
+              PhyML_Printf("\n== invar = %d",mixt_tree->data->invar[site]);
+              PhyML_Printf("\n== mixt = %d",mixt_tree->is_mixt_tree);
+              PhyML_Printf("\n== lk = %G log(lk) = %f < %G",site_lk,log_site_lk,-BIG);
+              for(class=0;class<mixt_tree->mod->ras->n_catg;++class) PhyML_Printf("\n== rr=%f p=%f",mixt_tree->mod->ras->gamma_rr->v[class],mixt_tree->mod->ras->gamma_r_proba->v[class]);
+              PhyML_Printf("\n== pinv = %G",mixt_tree->mod->ras->pinvar->v);
+              PhyML_Printf("\n== bl mult = %G",mixt_tree->mod->br_len_mult->v);
+              PhyML_Printf("\n== Err. in file %s at line %d.\n",__FILE__,__LINE__);
+              Exit("\n");
+            }
+          
+          mixt_tree->c_lnL += mixt_tree->data->wght[site]*log_site_lk;
+        }
+      
+      Free(sum_scale_left_cat);
+      Free(sum_scale_rght_cat);
+
+      Free(lk);
+      Free(dlk);
+      Free(d2lk);
+
+      mixt_tree->c_dlnL  = dlnlk;
+      mixt_tree->c_d2lnL = d2lnlk;
+      
+      mixt_tree = mixt_tree->next_mixt;
+      mixt_b    = mixt_b->next_mixt;
+    }
+  while(mixt_tree);
+
+
+  // mixt_tree across all partition elements have the same c_dlnL
+  mixt_tree = cpy_mixt_tree;
+  mixt_b    = cpy_mixt_b;
+
+  sum = .0;
+  do
+    {
+      sum += mixt_tree->c_dlnL;
+      mixt_tree = mixt_tree->next_mixt;
+    }
+  while(mixt_tree);
+
+  mixt_tree = cpy_mixt_tree;
+  do
+    {
+      mixt_tree->c_dlnL = sum;
+      mixt_tree = mixt_tree->next_mixt;
+    }
+  while(mixt_tree);
+
+
+  // mixt_tree across all partition elements have the same c_d2lnL
+  mixt_tree = cpy_mixt_tree;
+  mixt_b    = cpy_mixt_b;
+
+  sum = .0;
+  do
+    {
+      sum += mixt_tree->c_d2lnL;
+      mixt_tree = mixt_tree->next_mixt;
+    }
+  while(mixt_tree);
+
+  mixt_tree = cpy_mixt_tree;
+  do
+    {
+      mixt_tree->c_d2lnL = sum;
+      mixt_tree = mixt_tree->next_mixt;
+    }
+  while(mixt_tree);
+
+
+
+  // mixt_tree across all partition elements have the same c_lnL
+  mixt_tree = cpy_mixt_tree;
+  mixt_b    = cpy_mixt_b;
+
+  sum = .0;
+  do
+    {
+      sum += mixt_tree->c_lnL;
+      mixt_tree = mixt_tree->next_mixt;
+    }
+  while(mixt_tree);
+
+  mixt_tree = cpy_mixt_tree;
+  do
+    {
+      mixt_tree->c_lnL = sum;
+      mixt_tree = mixt_tree->next_mixt;
+    }
+  while(mixt_tree);
+
+
+  mixt_tree = cpy_mixt_tree;
+  mixt_b    = cpy_mixt_b;
+
+  return mixt_tree->c_lnL;
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+// Returns the number of trees (including mixt_trees) in the
+// whole model.
+int MIXT_Part_Mixt_Size(t_tree *mixt_tree)
+{
+  if(mixt_tree->is_mixt_tree == NO) return 1;
+  else
+    {
+      int num;
+      t_tree *tree;
+      
+      num = 0;
+      tree = mixt_tree;
+      do
+        {
+          num++;
+          tree = tree->next;
+        }
+      while(tree);
+      return num;
+    }
+  return -1;
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+// Returns the number of trees in the partition element corresponding to mixt_tree.
+int MIXT_Mixt_Size(t_tree *mixt_tree)
+{
+  if(mixt_tree->is_mixt_tree == NO) return 1;
+  else
+    {
+      int num;
+      t_tree *tree;
+      
+      num = 0;
+      tree = mixt_tree->next;
+      do
+        {
+          num++;
+          tree = tree->next;
+        }
+      while(tree && tree->is_mixt_tree == NO);
+ 
+     return num;
+    }
+  return -1;
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void MIXT_Set_Both_Sides(int yesno, t_tree *mixt_tree)
+{
+  t_tree *tree;
+  
+  assert(mixt_tree->is_mixt_tree == YES);
+
+  tree = mixt_tree;
+  
+  do
+    {
+      if(tree->is_mixt_tree == YES) tree = tree->next;        
+      Set_Both_Sides(yesno,tree);
+      tree = tree->next;
+    }
+  while(tree);
+
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void MIXT_Update_Eigen(t_mod *mixt_mod)
+{
+  t_mod *mod;
+
+  mod = mixt_mod;
+
+  do
+    {
+      if(mod->is_mixt_mod) mod = mod->next;
+      Update_Eigen(mod);
+      mod = mod->next;
+    }
+  while(mod);
+
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void MIXT_Update_Eigen_Lr(t_edge *mixt_b, t_tree *mixt_tree)
+{
+  t_edge *b;
+  t_tree *tree;
+
+  tree = mixt_tree->next;
+  b    = mixt_b->next;
+
+  do
+    {
+      if(tree->is_mixt_tree == YES)
+        {
+          tree = tree->next;
+          b    = b->next;
+        }
+
+      Update_Eigen_Lr(b,tree);
+
+      tree = tree->next;
+      b    = b->next;
+    }
+  while(tree);
+}
+
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void MIXT_Set_Update_Eigen_Lr(int yn, t_tree *mixt_tree)
+{
+  t_tree *tree;
+
+  tree = mixt_tree->next;
+  do
+    {
+      if(tree->is_mixt_tree == YES) tree = tree->next;        
+      Set_Update_Eigen_Lr(yn,tree);
+      tree = tree->next;
+    }
+  while(tree); 
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void MIXT_Set_Use_Eigen_Lr(int yn, t_tree *mixt_tree)
+{
+  t_tree *tree;
+
+  tree = mixt_tree->next;
+  do
+    {
+      if(tree->is_mixt_tree == YES) tree = tree->next;        
+      Set_Use_Eigen_Lr(yn,tree);
+      tree = tree->next;
+    }
+  while(tree); 
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
diff --git a/src/mixt.h b/src/mixt.h
index 4373d8a..2e17d0d 100644
--- a/src/mixt.h
+++ b/src/mixt.h
@@ -26,7 +26,7 @@ void MIXT_Set_Lengths_Of_This_Edge(phydbl *lens,t_edge *mixt_b, t_tree *tree);
 void MIXT_Post_Order_Lk(t_node *mixt_a,t_node *mixt_d,t_tree *mixt_tree);
 void MIXT_Pre_Order_Lk(t_node *mixt_a,t_node *mixt_d,t_tree *mixt_tree);
 phydbl MIXT_Lk(t_edge *mixt_b,t_tree *mixt_tree);
-void MIXT_Update_P_Lk(t_tree *mixt_tree,t_edge *mixt_b,t_node *mixt_d);
+void MIXT_Update_Partial_Lk(t_tree *mixt_tree,t_edge *mixt_b,t_node *mixt_d);
 void MIXT_Update_PMat_At_Given_Edge(t_edge *mixt_b,t_tree *mixt_tree);
 int *MIXT_Get_Number_Of_Classes_In_All_Mixtures(t_tree *mixt_tree);
 t_tree **MIXT_Record_All_Mixtures(t_tree *mixt_tree);
@@ -36,8 +36,8 @@ int *MIXT_Record_Has_Invariants(t_tree *mixt_tree);
 void MIXT_Reset_Has_Invariants(int *has_invariants,t_tree *mixt_tree);
 void MIXT_Check_Invar_Setup(t_tree *mixt_tree);
 void MIXT_Prune_Subtree(t_node *mixt_a,t_node *mixt_d,t_edge **mixt_target,t_edge **mixt_residual,t_tree *mixt_tree);
-void MIXT_Graft_Subtree(t_edge *mixt_target,t_node *mixt_link,t_edge *mixt_residual,t_tree *mixt_tree);
-void MIXT_Br_Len_Brent(phydbl prop_min, phydbl prop_max,t_edge *mixt_b, t_tree *mixt_tree);
+void MIXT_Graft_Subtree(t_edge *mixt_target, t_node *mixt_link, t_node *mixt_link_daughter, t_edge *mixt_residual, t_node *mixt_target_nd, t_tree *mixt_tree);
+void MIXT_Br_Len_Brent(t_edge *mixt_b, t_tree *mixt_tree);
 void MIXT_Check_Number_Of_Invar_Classes(t_tree *mixt_tree);
 void MIXT_Prepare_Tree_For_Lk(t_tree *tree);
 void MIXT_Check_Invar_Struct_In_Each_Partition_Elem(t_tree *mixt_tree);
@@ -47,7 +47,6 @@ void MIXT_Br_Len_Not_Involving_Invar(t_tree *mixt_tree);
 phydbl MIXT_Unscale_Br_Len_Multiplier_Tree(t_tree *mixt_tree);
 phydbl MIXT_Rescale_Br_Len_Multiplier_Tree(t_tree *mixt_tree);
 void MIXT_Set_Alias_Subpatt(int onoff, t_tree *mixt_tree);
-phydbl Lk_Core(int state, int ambiguity_check, t_edge *b, t_tree *tree);
 void MIXT_Check_Single_Edge_Lens(t_tree *mixt_tree);
 void MIXT_Update_Eigen(t_mod *mixt_mod);
 int MIXT_Pars(t_edge *mixt_b, t_tree *mixt_tree);
@@ -70,8 +69,38 @@ 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_Ancestral_Sequences_One_Node(t_node *mixt_d, t_tree *mixt_tree, int print);
+void MIXT_Update_Partial_Pars(t_tree *mixt_tree, t_edge *mixt_b, t_node *mixt_d);
+void MIXT_Chain_Cal(t_tree *mixt_tree);
+void MIXT_Chain_Rates(t_rate *curr, t_rate *next);
+void MIXT_RATES_Update_Cur_Bl(t_tree *mixt_tree);
+phydbl MIXT_dLk(phydbl *l, t_edge *mixt_b, t_tree *mixt_tree);
+void MIXT_Update_Eigen_Lr(t_edge *mixt_b, t_tree *mixt_tree);
+int MIXT_Part_Mixt_Size(t_tree *mixt_tree);
+int MIXT_Mixt_Size(t_tree *mixt_tree);
+void MIXT_Set_Use_Eigen_Lr(int yn, t_tree *mixt_tree);
+void MIXT_Set_Update_Eigen_Lr(int yn, t_tree *mixt_tree);
+void MIXT_Backup_Partial_Pars(t_node *mixt_d, t_edge *mixt_b, t_tree *mixt_tree);
+void MIXT_Restore_Partial_Pars(t_node *mixt_d, t_edge *mixt_b, t_tree *mixt_tree);
+void MIXT_Backup_Partial_Lk(t_node *mixt_d, t_edge *mixt_b, t_tree *mixt_tree);
+void MIXT_Restore_Partial_Lk(t_node *mixt_d, t_edge *mixt_b, t_tree *mixt_tree);
+void MIXT_Backup_Partial_Scale(t_node *mixt_d, t_edge *mixt_b, t_tree *mixt_tree);
+void MIXT_Restore_Partial_Scale(t_node *mixt_d, t_edge *mixt_b, t_tree *mixt_tree);
+void MIXT_Set_Both_Sides(int yesno, t_tree *mixt_tree);
 
 #endif
diff --git a/src/models.c b/src/models.c
index a2eebd0..21d6d12 100644
--- a/src/models.c
+++ b/src/models.c
@@ -1,7 +1,7 @@
 /*
 
-PhyML :  a program that  computes maximum likelihood  phyLOGenies from
-DNA or AA homoLOGous sequences
+PhyML :  a program that  computes maximum likelihood  phylogenies from
+DNA or AA homologous sequences
 
 Copyright (C) Stephane Guindon. Oct 2003 onward
 
@@ -28,11 +28,11 @@ void PMat_JC69(phydbl l, int pos, phydbl *Pij, t_mod *mod)
   ns = mod->ns;
 
 
-  For(i,ns) Pij[pos+ ns*i+i] = 1. - ((ns - 1.)/ns)*(1. - EXP(-ns*l/(ns - 1.)));
-  For(i,ns-1)
+  for(i=0;i<ns;i++) Pij[pos+ ns*i+i] = 1. - ((ns - 1.)/ns)*(1. - exp(-ns*l/(ns - 1.)));
+  for(i=0;i<ns-1;i++)
     for(j=i+1;j<ns;j++)
       {
-        Pij[pos+ ns*i+j] = (1./ns)*(1. - EXP(-ns*l/(ns - 1.)));
+        Pij[pos+ ns*i+j] = (1./ns)*(1. - exp(-ns*l/(ns - 1.)));
         if(Pij[pos+ns*i+j] < SMALL_PIJ) Pij[pos+ns*i+j] = SMALL_PIJ;
         Pij[pos+ ns*j+i] = Pij[pos+ ns*i+j];
       }
@@ -56,9 +56,9 @@ void PMat_K80(phydbl l, phydbl kappa, int pos, phydbl *Pij)
 
 
   aux = -2*l/(kappa+2);
-  e1 = (phydbl)EXP(aux *2);
+  e1 = (phydbl)exp(aux *2);
 
-  e2 = (phydbl)EXP(aux *(kappa+1));
+  e2 = (phydbl)exp(aux *(kappa+1));
   Tv = .25*(1-e1);
   Ts = .25*(1+e1-2*e2);
 
@@ -74,7 +74,7 @@ void PMat_K80(phydbl l, phydbl kappa, int pos, phydbl *Pij)
 
   Pij[pos+ 4*2+3] = Pij[pos+ 4*3+2] = Tv;
 
-  For(i,4) For(j,4)
+  for(i=0;i<4;i++) for(j=0;j<4;j++)
     if(Pij[pos + 4*i+j] < SMALL_PIJ) Pij[pos + 4*i+j] = SMALL_PIJ;
 
 }
@@ -111,9 +111,9 @@ void PMat_TN93(phydbl l, t_mod *mod, int pos, phydbl *Pij)
   a2t = kappa2;
   a1t*=bt; a2t*=bt;
 
-  e1 = (phydbl)EXP(-a1t*R-bt*Y);
-  e2 = (phydbl)EXP(-a2t*Y-bt*R);
-  e3 = (phydbl)EXP(-bt);
+  e1 = (phydbl)exp(-a1t*R-bt*Y);
+  e2 = (phydbl)exp(-a2t*Y-bt*R);
+  e3 = (phydbl)exp(-bt);
 
 
   /*A->A*/Pij[pos + 4*0+0] = A+Y*A/R*e3+G/R*e1;
@@ -136,7 +136,7 @@ void PMat_TN93(phydbl l, t_mod *mod, int pos, phydbl *Pij)
   /*T->G*/Pij[pos + 4*3+2] = G*(1-e3);
   /*T->T*/Pij[pos + 4*3+3] = T+R*T/Y*e3+C/Y*e2;
 
-  For(i,4) For(j,4)
+  for(i=0;i<4;i++) for(j=0;j<4;j++)
     if(Pij[pos + 4*i+j] < SMALL_PIJ) Pij[pos + 4*i+j] = SMALL_PIJ;
 
 /*   /\*A->A*\/(*Pij)[0][0] = A+Y*A/R*e3+G/R*e1;  */
@@ -159,7 +159,7 @@ void PMat_TN93(phydbl l, t_mod *mod, int pos, phydbl *Pij)
 /*   /\*T->G*\/(*Pij)[3][2] = G*(1-e3); */
 /*   /\*T->T*\/(*Pij)[3][3] = T+R*T/Y*e3+C/Y*e2; */
 
-/*   For(i,4) For(j,4) */
+/*   for(i=0;i<4;i++) for(j=0;j<4;j++) */
 /*     if((*Pij)[i][j] < SMALL) (*Pij)[i][j] = SMALL; */
 
 }
@@ -201,12 +201,9 @@ phydbl Get_Lambda_F84(phydbl *pi, phydbl *kappa)
   return lambda;
 }
 
-
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
-
 /********************************************************************/
 /* void PMat_Empirical(phydbl l, t_mod *mod, phydbl ***Pij)         */
 /*                                                                  */
@@ -219,7 +216,7 @@ phydbl Get_Lambda_F84(phydbl *pi, phydbl *kappa)
 /* ouput : Pij , substitution probability matrix                    */
 /*                                                                  */
 /* matrix P(l) is computed as follows :                             */
-/* P(l) = EXP(Q*t) , where :                                        */
+/* P(l) = exp(Q*t) , where :                                        */
 /*                                                                  */
 /*   Q = substitution rate matrix = Vr*D*inverse(Vr) , where :      */
 /*                                                                  */
@@ -235,12 +232,12 @@ phydbl Get_Lambda_F84(phydbl *pi, phydbl *kappa)
 /*       p(i->j) = subst. probability from i to a different state   */
 /*               = -Q[ii] , as sum(j)(Q[ij]) +Q[ii] =0              */
 /*                                                                  */
-/* the Taylor development of EXP(Q*t) gives :                       */
-/* P(l) = Vr*EXP(D*t)        *inverse(Vr)                           */
-/*      = Vr*POW(EXP(D/mr),l)*inverse(Vr)                           */
+/* the Taylor development of exp(Q*t) gives :                       */
+/* P(l) = Vr*exp(D*t)        *inverse(Vr)                           */
+/*      = Vr*POW(exp(D/mr),l)*inverse(Vr)                           */
 /*                                                                  */
 /* for performance we compute only once the following matrixes :    */
-/* Vr, inverse(Vr), EXP(D/mr)                                       */
+/* Vr, inverse(Vr), exp(D/mr)                                       */
 /* thus each time we compute P(l) we only have to :                 */
 /* make 20 times the operation POW()                                */
 /* make 2 20x20 matrix multiplications , that is :                  */
@@ -251,13 +248,14 @@ phydbl Get_Lambda_F84(phydbl *pi, phydbl *kappa)
 /*   8000 = 20x20x20 times the operation +                          */
 /********************************************************************/
 
-void PMat_Empirical(phydbl l, t_mod *mod, int pos, phydbl *Pij)
+void PMat_Empirical(phydbl l, t_mod *mod, int pos, phydbl *Pij, phydbl *tPij)
 {
-  int n = mod->ns;
-  int i, j, k;
+  const unsigned int ns = mod->ns;
+  unsigned int i, j, k;
   phydbl *U,*V,*R;
   phydbl *expt;
   phydbl *uexpt;
+  phydbl sum;
 
   expt  = mod->eigen->e_val_im;
   uexpt = mod->eigen->r_e_vect_im;
@@ -265,70 +263,45 @@ void PMat_Empirical(phydbl l, t_mod *mod, int pos, phydbl *Pij)
   V     = mod->eigen->l_e_vect;
   R     = mod->eigen->e_val; /* exponential of the eigen value matrix */
 
-  //Initialize a rate-specific N*N matrix
-  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);
-
-  /* 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];
+  /* Initialize a rate-specific N*N matrix */
+  for(i=0;i<ns;++i) for(k=0;k<ns;k++) Pij[pos+ns*i+k] = .0;
+  /* compute POW(exp(D/mr),l) into mat_eDmrl */
+  for(k=0;k<ns;++k)  expt[k] = (phydbl)POW(R[k],l);
+  /* multiply Vr*POW(exp(D/mr),l)*Vi into Pij */
+  for(i=0;i<ns;i++) for (k=0;k<ns;k++) uexpt[i*ns+k] = U[i*ns+k] * expt[k];
 
-  For (i,n)
+  for(i=0;i<ns;++i)
     {
-      For (j,n)
+      for(j=0;j<ns;++j)
         {
-          For(k,n)
+          for(k=0;k<ns;++k)
             {
-              Pij[pos+mod->ns*i+j] += (uexpt[i*n+k] * V[k*n+j]);
+              Pij[pos+ns*i+j] += (uexpt[i*ns+k] * V[k*ns+j]);
             }
-          /* 	  if(Pij[pos+mod->ns*i+j] < SMALL) Pij[pos+mod->ns*i+j] = SMALL; */
-          if(Pij[pos+mod->ns*i+j] < SMALL_PIJ) Pij[pos+mod->ns*i+j] = SMALL_PIJ;
+
+          if(Pij[pos+ns*i+j] < SMALL_PIJ) Pij[pos+ns*i+j] = SMALL_PIJ;
         }
-      
-#ifndef PHYML
-      phydbl sum;
-      sum = .0;
-      For (j,n) sum += Pij[pos+mod->ns*i+j];
-      if((sum > 1.+.0001) || (sum < 1.-.0001))
+
+      sum = 0.0;
+      for(j=0;j<ns;++j) sum += Pij[pos+ns*i+j];
+      for(j=0;j<ns;++j) Pij[pos+ns*i+j] /= sum;
+    }
+
+  if(tPij)
+    {
+      for(i=0;i<ns;++i)
         {
-          PhyML_Printf("\n");
-          PhyML_Printf("\n. Q\n");
-          For(i,n) { For(j,n) PhyML_Printf("%7.3f ",mod->eigen->q[i*n+j]); PhyML_Printf("\n"); }
-          PhyML_Printf("\n. U\n");
-          For(i,n) { For(j,n) PhyML_Printf("%7.3f ",U[i*n+j]); PhyML_Printf("\n"); }
-          PhyML_Printf("\n");
-          PhyML_Printf("\n. V\n");
-          For(i,n) { For(j,n) PhyML_Printf("%7.3f ",V[i*n+j]); PhyML_Printf("\n"); }
-          PhyML_Printf("\n");
-          PhyML_Printf("\n. Eigen\n");
-          For(i,n)  PhyML_Printf("%E ",expt[i]);
-          PhyML_Printf("\n");
-          PhyML_Printf("\n. Pij\n");
-          For(i,n) { For (j,n) PhyML_Printf("%f ",Pij[pos+mod->ns*i+j]); PhyML_Printf("\n"); }
-          PhyML_Printf("\n. sum = %f",sum);
-          if(mod->m4mod)
+          for(j=0;j<ns;++j)
             {
-              int i;
-              PhyML_Printf("\n. mod->m4mod->alpha = %f",mod->m4mod->alpha);
-              PhyML_Printf("\n. mod->m4mod->delta = %f",mod->m4mod->delta);
-              For(i,mod->m4mod->n_h)
-                {
-                  PhyML_Printf("\n. mod->m4mod->multipl[%d] = %f",i,mod->m4mod->multipl[i]);
-                }
+              tPij[pos+ns*i+j] = Pij[pos+ns*j+i];
             }
-          PhyML_Printf("\n. l=%f",l);
-          PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__);
-          Warn_And_Exit("");
         }
-#endif
     }
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void PMat_Gamma(phydbl l, t_mod *mod, int pos, phydbl *Pij)
 {
   int n;
@@ -350,7 +323,7 @@ void PMat_Gamma(phydbl l, t_mod *mod, int pos, phydbl *Pij)
   else                 shape = mod->ras->alpha->v;
 
 
-  For(i,n) For(k,n) Pij[pos+mod->ns*i+k] = .0;
+  for(i=0;i<n;i++) for(k=0;k<n;k++) Pij[pos+mod->ns*i+k] = .0;
 
   if(shape < 1.E-10)
     {
@@ -359,16 +332,16 @@ void PMat_Gamma(phydbl l, t_mod *mod, int pos, phydbl *Pij)
     }
 
   /* Formula 13.42, page 220 of Felsenstein's book ``Inferring Phylogenies'' */
-  For(k,n) expt[k] = POW(shape/(shape-LOG(R[k])*l),shape);
+  for(k=0;k<n;k++) expt[k] = POW(shape/(shape-log(R[k])*l),shape);
 
   /* multiply Vr*expt*Vi into Pij */
-  For(i,n) For(k,n) uexpt[i*n+k] = U[i*n+k] * expt[k];
+  for(i=0;i<n;i++) for(k=0;k<n;k++) uexpt[i*n+k] = U[i*n+k] * expt[k];
 
   For (i,n)
     {
       For (j,n)
     {
-      For(k,n)
+      for(k=0;k<n;k++)
         {
           Pij[pos+mod->ns*i+j] += (uexpt[i*n+k] * V[k*n+j]);
         }
@@ -383,25 +356,25 @@ void PMat_Gamma(phydbl l, t_mod *mod, int pos, phydbl *Pij)
     {
       PhyML_Printf("\n");
       PhyML_Printf("\n. Q\n");
-      For(i,n) { For(j,n) PhyML_Printf("%7.3f ",mod->eigen->q[i*n+j]); PhyML_Printf("\n"); }
+      for(i=0;i<n;i++) { for(j=0;j<n;j++) PhyML_Printf("%7.3f ",mod->eigen->q[i*n+j]); PhyML_Printf("\n"); }
       PhyML_Printf("\n. U\n");
-      For(i,n) { For(j,n) PhyML_Printf("%7.3f ",U[i*n+j]); PhyML_Printf("\n"); }
+      for(i=0;i<n;i++) { for(j=0;j<n;j++) PhyML_Printf("%7.3f ",U[i*n+j]); PhyML_Printf("\n"); }
       PhyML_Printf("\n");
       PhyML_Printf("\n. V\n");
-      For(i,n) { For(j,n) PhyML_Printf("%7.3f ",V[i*n+j]); PhyML_Printf("\n"); }
+      for(i=0;i<n;i++) { for(j=0;j<n;j++) PhyML_Printf("%7.3f ",V[i*n+j]); PhyML_Printf("\n"); }
       PhyML_Printf("\n");
       PhyML_Printf("\n. Eigen\n");
-      For(i,n)  PhyML_Printf("%E ",expt[i]);
+      for(i=0;i<n;i++)  PhyML_Printf("%E ",expt[i]);
       PhyML_Printf("\n");
       PhyML_Printf("\n. Pij\n");
-      For(i,n) { For (j,n) PhyML_Printf("%f ",Pij[pos+mod->ns*i+j]); PhyML_Printf("\n"); }
+      for(i=0;i<n;i++) { For (j,n) PhyML_Printf("%f ",Pij[pos+mod->ns*i+j]); PhyML_Printf("\n"); }
       PhyML_Printf("\n. sum = %f",sum);
       if(mod->m4mod)
         {
           int i;
           PhyML_Printf("\n. mod->m4mod->ras->alpha = %f",mod->m4mod->alpha);
           PhyML_Printf("\n. mod->m4mod->delta = %f",mod->m4mod->delta);
-          For(i,mod->m4mod->n_h)
+          for(i=0;i<mod->m4mod->n_h;i++)
         {
           PhyML_Printf("\n. mod->m4mod->multipl[%d] = %f",i,mod->m4mod->multipl[i]);
         }
@@ -440,7 +413,7 @@ void PMat_Zero_Br_Len(t_mod *mod, int pos, phydbl *Pij)
  *  pos: offset into a specific rate-category
  *
  */
-void PMat(phydbl l, t_mod *mod, int pos, phydbl *Pij)
+void PMat(phydbl l, t_mod *mod, int pos, phydbl *Pij, phydbl *tPij)
 {
   /* Warning: l is never the log of branch length here */
   if(l < 0.0)
@@ -452,69 +425,12 @@ void PMat(phydbl l, t_mod *mod, int pos, phydbl *Pij)
     }
   else
     {
-      switch(mod->io->datatype)
-        {
-        case NT :
-          {
-            if(mod->use_m4mod)
-              {
-                PMat_Empirical(l,mod,pos,Pij);
-              }
-            else
-              {
-                if((mod->whichmodel == JC69) ||
-                   (mod->whichmodel == K80))
-                  {
-                    /* 		    PMat_JC69(l,pos,Pij,mod); */
-                    PMat_K80(l,mod->kappa->v,pos,Pij);
-                  }
-                else
-                  {
-                    if(
-                       (mod->whichmodel == F81)   ||
-                       (mod->whichmodel == HKY85) ||
-                       (mod->whichmodel == F84)   ||
-                       (mod->whichmodel == TN93))
-                      {
-                        PMat_TN93(l,mod,pos,Pij);
-                      }
-                    else
-                      {
 #ifdef BEAGLE
-                        //when there is no active instance (i.e. when we are building the initial tree)
-                        if(UNINITIALIZED == mod->b_inst) {
-                            PMat_Empirical(l,mod,pos,Pij);
-                        }
-#else
-                        PMat_Empirical(l,mod,pos,Pij);
-#endif
-                      }
-                  }
-                break;
-              }
-          case AA :
-            {
-#ifdef BEAGLE
-                //when there is no active instance (i.e. when we are building the initial tree)
-                if(UNINITIALIZED == mod->b_inst) {
-                    PMat_Empirical(l,mod,pos,Pij);
-                }
+      //when there is no active instance (i.e. when we are building the initial tree)
+      if(UNINITIALIZED == mod->b_inst) PMat_Empirical(l,mod,pos,Pij,tPij);
 #else
-                PMat_Empirical(l,mod,pos,Pij);
+      PMat_Empirical(l,mod,pos,Pij,tPij);
 #endif
-              break;
-            }
-          default:
-            {
-              PMat_JC69(l,pos,Pij,mod);
-              break;
-    /* 	      PhyML_Printf("\n. Not implemented yet.\n"); */
-    /* 	      PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); */
-    /* 	      Warn_And_Exit(""); */
-    /* 	      break; */
-            }
-          }
-        }
     }
 }
 
@@ -550,7 +466,7 @@ int GetDaa (phydbl *daa, phydbl *pi, char *file_name)
      if (dmin>daa[i*naa+j]) dmin=daa[i*naa+j];
        }
 
-   For(i,naa)
+   for(i=0;i<naa;i++)
      {
 /*        if(fscanf(fdaa,"%lf",&pi[i])!=1) Exit("\n. err aaRatefile"); */
        if(fscanf(fdaa,"%lf",&val)!=1) Exit("\n. err aaRatefile");
@@ -585,7 +501,7 @@ void Update_Qmat_Generic(phydbl *rr, phydbl *pi, int ns, phydbl *qmat)
       PhyML_Printf("\n== Err in file %s at line %d\n\n",__FILE__,__LINE__);
       Warn_And_Exit("");
     }
-
+  
   /* PhyML_Printf("\n"); */
   /* For(i,(int)(ns*(ns-1)/2)) */
   /*   { */
@@ -596,39 +512,38 @@ void Update_Qmat_Generic(phydbl *rr, phydbl *pi, int ns, phydbl *qmat)
     {
       rr[i] /= rr[(int)(ns*(ns-1)/2)-1];
     }
-
+  
   /* Fill the non-diagonal parts */
-  For(i,ns)
+  for(i=0;i<ns;i++)
     {
       for(j=i+1;j<ns;j++)
-    {
-      qmat[i*ns+j] = rr[MIN(i,j) * ns + MAX(i,j) -
-                (MIN(i,j)+1+(int)POW(MIN(i,j)+1,2))/2];
-      qmat[j*ns+i] = qmat[i*ns+j];
-    }
+        {
+          qmat[i*ns+j] = rr[MIN(i,j) * ns + MAX(i,j) - (MIN(i,j)+1+(int)POW(MIN(i,j)+1,2))/2];
+          qmat[j*ns+i] = qmat[i*ns+j];
+        }
     }
 
 
   /* Multiply by pi */
-  For(i,ns)
-    {
-      For(j,ns)
+  for(i=0;i<ns;i++)
     {
-      qmat[i*ns+j] *= pi[j];
-    }
+      for(j=0;j<ns;j++)
+        {
+          qmat[i*ns+j] *= pi[j];
+        }
     }
 
   /* Compute diagonal elements */
   mr = .0;
-  For(i,ns)
+  for(i=0;i<ns;i++)
     {
       sum = .0;
-      For(j,ns) {sum += qmat[i*ns+j];}
+      for(j=0;j<ns;j++) sum += qmat[i*ns+j];
       qmat[i*ns+i] = -sum;
       mr += sum * pi[i];
     }
 
-  /* For(i,ns) For(j,ns) qmat[i*ns+j] /= mr; */
+  /* for(i=0;i<ns;i++) for(j=0;j<ns;j++) qmat[i*ns+j] /= mr; */
 }
 
 //////////////////////////////////////////////////////////////
@@ -639,20 +554,17 @@ void Update_Qmat_GTR(phydbl *rr, phydbl *rr_val, int *rr_num, phydbl *pi, phydbl
   int i;
   phydbl mr;
 
-  For(i,6) rr[i] = rr_val[rr_num[i]];
-  For(i,6)
+  for(i=0;i<6;i++) rr[i] = rr_val[rr_num[i]];
+  for(i=0;i<6;i++)
     if(rr[i] < 0.0)
       {
         PhyML_Printf("\n== rr%d: %f",i,rr[i]);
         PhyML_Printf("\n== Err. in file %s at line %d (function '%s').\n",__FILE__,__LINE__,__FUNCTION__);
         Exit("");
       }
-
-  For(i,6) rr[i] /= MAX(rr[5],RR_MIN);
-  For(i,6) if(rr[i] < RR_MIN) rr[i] = RR_MIN;
-  For(i,6) if(rr[i] > RR_MAX) rr[i] = RR_MAX;
-
-  For(i,6) if(isnan(rr[i])) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); 
+  for(i=0;i<6;i++) rr[i] /= MAX(rr[5],RR_MIN);
+  for(i=0;i<6;i++) if(rr[i] < RR_MIN) rr[i] = RR_MIN;
+  for(i=0;i<6;i++) if(rr[i] > RR_MAX) rr[i] = RR_MAX;
 
   qmat[0*4+1] = (rr[0]*pi[1]);
   qmat[0*4+2] = (rr[1]*pi[2]);
@@ -677,18 +589,18 @@ void Update_Qmat_GTR(phydbl *rr, phydbl *rr_val, int *rr_num, phydbl *pi, phydbl
 
   /* compute diagonal terms of Q and mean rate mr = l/t */
   mr = .0;
-  For(i,4) mr += pi[i] * (-qmat[i*4+i]);
-  For(i,16) qmat[i] /= mr;
+  for(i=0;i<4;i++) mr += pi[i] * (-qmat[i*4+i]);
+  for(i=0;i<16;i++) qmat[i] /= mr;
 
   /* int j; */
   /* printf("\n"); */
   /* printf("\n. rr -- "); */
-  /* For(i,5) printf(" %15f ",rr[i]); */
+  /* for(i=0;i<5;i++) printf(" %15f ",rr[i]); */
   /* printf("\n"); */
-  /* For(i,4) */
+  /* for(i=0;i<4;i++) */
   /*   { */
   /*     printf("\n. [%15f] \t ",pi[i]); */
-  /*     For(j,4) */
+  /*     for(j=0;j<4;j++) */
   /* 	{ */
   /* 	  printf(" %15f ",qmat[i*4+j]); */
   /* 	} */
@@ -728,7 +640,7 @@ void Update_Qmat_HKY(phydbl kappa, phydbl *pi, phydbl *qmat)
   /* compute diagonal terms of Q and mean rate mr = l/t */
   mr = .0;
   For (i,4) mr += pi[i] * (-qmat[i*4+i]);
-  For(i,16) qmat[i] /= mr;
+  for(i=0;i<16;i++) qmat[i] /= mr;
 }
 
 //////////////////////////////////////////////////////////////
@@ -739,13 +651,13 @@ void Translate_Custom_Mod_String(t_mod *mod)
 {
   int i,j;
 
-  For(i,6) mod->r_mat->n_rr_per_cat->v[i] = 0;
+  for(i=0;i<6;i++) mod->r_mat->n_rr_per_cat->v[i] = 0;
 
   mod->r_mat->n_diff_rr = 0;
 
-  For(i,6)
+  for(i=0;i<6;i++)
     {
-      For(j,i)
+      for(j=0;j<i;j++)
         {
           if(mod->custom_mod_string->s[i] == mod->custom_mod_string->s[j])
             {
@@ -767,8 +679,8 @@ void Translate_Custom_Mod_String(t_mod *mod)
     }
   
     /* PhyML_Printf("\n"); */
-    /* For(i,6) PhyML_Printf("%d ",mod->r_mat->rr_num->v[i]); */
-    /* For(i,mod->r_mat->n_diff_rr) PhyML_Printf("\n. Class %d size %d",i+1,mod->r_mat->n_rr_per_cat->v[i]); */
+    /* for(i=0;i<6;i++) PhyML_Printf("%d ",mod->r_mat->rr_num->v[i]); */
+    /* for(i=0;i<mod->r_mat->n_diff_rr;i++) PhyML_Printf("\n. Class %d size %d",i+1,mod->r_mat->n_rr_per_cat->v[i]); */
 }
 
 //////////////////////////////////////////////////////////////
@@ -782,64 +694,57 @@ void Update_RAS(t_mod *mod)
   int i;
 
   if(mod->ras->free_mixt_rates == NO) 
-    DiscreteGamma(mod->ras->gamma_r_proba->v,
-                  mod->ras->gamma_rr->v,
-                  mod->ras->alpha->v,
-                  mod->ras->alpha->v,
-                  mod->ras->n_catg,
-                  mod->ras->gamma_median);
+    {
+      DiscreteGamma(mod->ras->gamma_r_proba->v,
+                    mod->ras->gamma_rr->v,
+                    mod->ras->alpha->v,
+                    mod->ras->alpha->v,
+                    mod->ras->n_catg,
+                    mod->ras->gamma_median);
+    }
   else
     {
-      if(mod->ras->sort_rate_classes == YES)
+      // Update class frequencies
+      Qksort(mod->ras->gamma_r_proba_unscaled->v,NULL,0,mod->ras->n_catg-1); // Unscaled class frequencies sorted in increasing order
+ 
+      mod->ras->gamma_r_proba->v[0] = mod->ras->gamma_r_proba_unscaled->v[0] / mod->ras->gamma_r_proba_unscaled->v[mod->ras->n_catg-1];
+      for(i=1;i<mod->ras->n_catg;i++)
         {
-          Qksort(mod->ras->gamma_r_proba_unscaled->v,NULL,0,mod->ras->n_catg-1); // Unscaled class frequencies sorted in increasing order
-
-          // Update class frequencies
-          For(i,mod->ras->n_catg)
-            {
-              if(!i)
-                mod->ras->gamma_r_proba->v[i] =
-                  mod->ras->gamma_r_proba_unscaled->v[i] /  (mod->ras->gamma_r_proba_unscaled->v[mod->ras->n_catg-1]) ;
-              else
-                mod->ras->gamma_r_proba->v[i] =
-                  (mod->ras->gamma_r_proba_unscaled->v[i] - mod->ras->gamma_r_proba_unscaled->v[i-1]) /
-                  (mod->ras->gamma_r_proba_unscaled->v[mod->ras->n_catg-1]) ;
-            }
-        }
-      else
-        {
-          sum = 0.0;
-          For(i,mod->ras->n_catg) sum += mod->ras->gamma_r_proba_unscaled->v[i];
-          For(i,mod->ras->n_catg) mod->ras->gamma_r_proba->v[i] = mod->ras->gamma_r_proba_unscaled->v[i] / sum;
+          mod->ras->gamma_r_proba->v[i] =
+            (mod->ras->gamma_r_proba_unscaled->v[i] -
+             mod->ras->gamma_r_proba_unscaled->v[i-1]) /
+            mod->ras->gamma_r_proba_unscaled->v[mod->ras->n_catg-1];
         }
 
       do
         {
           sum = .0;
-          For(i,mod->ras->n_catg)
+          for(i=0;i<mod->ras->n_catg;i++)
             {
               if(mod->ras->gamma_r_proba->v[i] < 0.01) mod->ras->gamma_r_proba->v[i]=0.01;
               if(mod->ras->gamma_r_proba->v[i] > 0.99) mod->ras->gamma_r_proba->v[i]=0.99;
               sum += mod->ras->gamma_r_proba->v[i];
             }
-          For(i,mod->ras->n_catg) mod->ras->gamma_r_proba->v[i]/=sum;
+          for(i=0;i<mod->ras->n_catg;i++) mod->ras->gamma_r_proba->v[i]/=sum;
         }
       while((sum > 1.01) || (sum < 0.99));
 
 
       // Update class rates
-      sum = .0;
-      For(i,mod->ras->n_catg) sum += mod->ras->gamma_r_proba->v[i] * mod->ras->gamma_rr_unscaled->v[i];
 
       if(mod->ras->normalise_rr == YES)
-        For(i,mod->ras->n_catg)
-          mod->ras->gamma_rr->v[i] = mod->ras->gamma_rr_unscaled->v[i]/sum;
+        {
+          sum = .0;
+          for(i=0;i<mod->ras->n_catg;i++) sum += mod->ras->gamma_r_proba->v[i] * mod->ras->gamma_rr_unscaled->v[i];
+          for(i=0;i<mod->ras->n_catg;i++) mod->ras->gamma_rr->v[i] = mod->ras->gamma_rr_unscaled->v[i]/sum;
+        }
       else
-        For(i,mod->ras->n_catg)
-          mod->ras->gamma_rr->v[i] = mod->ras->gamma_rr_unscaled->v[i] * mod->ras->free_rate_mr->v;
-
+        {
+          for(i=0;i<mod->ras->n_catg;i++) mod->ras->gamma_rr->v[i] = mod->ras->gamma_rr_unscaled->v[i] * mod->ras->free_rate_mr->v;
+        }
+      
       /* printf("\n"); */
-      /* For(i,mod->ras->n_catg)  */
+      /* for(i=0;i<mod->ras->n_catg;i++)  */
       /*   printf("\nx %3d %12f %12f xx %12f %12f", */
       /*          mod->ras->normalise_rr, */
       /*          mod->ras->gamma_r_proba->v[i], */
@@ -859,36 +764,36 @@ void Update_RAS(t_mod *mod)
 
 void Update_Efrq(t_mod *mod)
 {
+
+  unsigned int i;
   phydbl sum;
-  int i;
 
-  if((mod->io->datatype == NT) && (mod->s_opt->opt_state_freq))
+  if((mod->io->datatype == NT) && (mod->s_opt->opt_state_freq == YES))
     {
-      sum = .0;
-      For(i,mod->ns) sum += FABS(mod->e_frq->pi_unscaled->v[i]);
-      For(i,mod->ns) mod->e_frq->pi->v[i] = FABS(mod->e_frq->pi_unscaled->v[i])/sum;
-
-      do
-        {
-          sum = .0;
-          For(i,mod->ns)
-            {
-              if(mod->e_frq->pi->v[i] < 0.01) mod->e_frq->pi->v[i]=0.01;
-              if(mod->e_frq->pi->v[i] > 0.99) mod->e_frq->pi->v[i]=0.99;
-              sum += mod->e_frq->pi->v[i];
-            }
-          For(i,mod->ns) 
-            {
-              mod->e_frq->pi->v[i]/=sum;
-            }
-        }
-      while((sum > 1.01) || (sum < 0.99));
-
+      sum = 0.0;
+      for(i=0;i<mod->ns;i++) sum += FABS(mod->e_frq->pi_unscaled->v[i]);
+      for(i=0;i<mod->ns;i++) mod->e_frq->pi->v[i] = FABS(mod->e_frq->pi_unscaled->v[i])/sum;
+            
 #ifdef BEAGLE
       if(UNINITIALIZED != mod->b_inst)
         update_beagle_efrqs(mod);
 #endif
     }
+  
+
+  // Adjust equilibrium state frequencies if some of them are too close to zero
+  // in order to avoid numerical precision issues.
+  int iter = 0;
+  do
+    {
+      for(i=0;i<mod->ns;i++) if(mod->e_frq->pi->v[i] < E_FRQ_MIN) mod->e_frq->pi->v[i] = E_FRQ_MIN;
+      sum = 0.0;
+      for(i=0;i<mod->ns;i++) sum += FABS(mod->e_frq->pi->v[i]);
+      for(i=0;i<mod->ns;i++) mod->e_frq->pi->v[i] /= sum;
+      iter++;
+    }
+  while(iter < 10);
+
 }
 
 //////////////////////////////////////////////////////////////
@@ -896,6 +801,7 @@ void Update_Efrq(t_mod *mod)
 
 void Set_Model_Parameters(t_mod *mod)
 {
+  Update_Boundaries(mod);
   Update_RAS(mod);
   Update_Efrq(mod);
   Update_Eigen(mod);
@@ -904,6 +810,60 @@ void Set_Model_Parameters(t_mod *mod)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
+void Update_Boundaries(t_mod *mod)
+{
+  int i;
+
+  if(mod->kappa->v > TSTV_MAX) mod->kappa->v = TSTV_MAX;
+  if(mod->kappa->v < TSTV_MIN) mod->kappa->v = TSTV_MIN;
+
+  if(mod->ras->alpha->v < ALPHA_MIN) mod->ras->alpha->v = ALPHA_MIN;
+  if(mod->ras->alpha->v > ALPHA_MAX) mod->ras->alpha->v = ALPHA_MAX;
+
+  if(mod->ras->free_mixt_rates == YES) 
+    {
+      for(i=0;i<mod->ras->n_catg;i++) 
+        {
+          if(mod->ras->gamma_rr_unscaled->v[i] < GAMMA_RR_UNSCALED_MIN)
+            mod->ras->gamma_rr_unscaled->v[i] = GAMMA_RR_UNSCALED_MIN;
+          
+          if(mod->ras->gamma_rr_unscaled->v[i] > GAMMA_RR_UNSCALED_MAX)
+            mod->ras->gamma_rr_unscaled->v[i] = GAMMA_RR_UNSCALED_MAX;
+          
+          if(mod->ras->gamma_r_proba_unscaled->v[i] < GAMMA_R_PROBA_UNSCALED_MIN)
+            mod->ras->gamma_r_proba_unscaled->v[i] = GAMMA_R_PROBA_UNSCALED_MIN;
+          
+          if(mod->ras->gamma_r_proba_unscaled->v[i] > GAMMA_R_PROBA_UNSCALED_MAX)
+            mod->ras->gamma_r_proba_unscaled->v[i] = GAMMA_R_PROBA_UNSCALED_MAX;
+        }
+    }
+
+  if(mod->whichmodel == CUSTOM || mod->whichmodel == GTR)
+    {
+      for(i=0;i<6;i++) if(mod->r_mat->rr_val->v[i] < RR_MIN) mod->r_mat->rr_val->v[i] = RR_MIN;
+      for(i=0;i<6;i++) if(mod->r_mat->rr_val->v[i] > RR_MAX) mod->r_mat->rr_val->v[i] = RR_MAX;
+    }
+
+  for(i=0;i<mod->ns;i++)
+    {
+      if(mod->e_frq->pi_unscaled->v[i] < UNSCALED_E_FRQ_MIN)
+        mod->e_frq->pi_unscaled->v[i] = UNSCALED_E_FRQ_MIN;
+
+      if(mod->e_frq->pi_unscaled->v[i] > UNSCALED_E_FRQ_MAX)
+        mod->e_frq->pi_unscaled->v[i] = UNSCALED_E_FRQ_MAX;
+    }
+  
+  if(mod->r_mat_weight->v < R_MAT_WEIGHT_MIN) mod->r_mat_weight->v = R_MAT_WEIGHT_MIN;
+  if(mod->r_mat_weight->v > R_MAT_WEIGHT_MAX) mod->r_mat_weight->v = R_MAT_WEIGHT_MAX;
+
+  if(mod->e_frq_weight->v < E_FRQ_WEIGHT_MIN) mod->e_frq_weight->v = E_FRQ_WEIGHT_MIN;
+  if(mod->e_frq_weight->v > E_FRQ_WEIGHT_MAX) mod->e_frq_weight->v = E_FRQ_WEIGHT_MAX;
+
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
 void Update_Eigen(t_mod *mod)
 {
   int result, n_iter;
@@ -911,13 +871,14 @@ void Update_Eigen(t_mod *mod)
   int i;
 
 
-  if(mod->is_mixt_mod)
+  if(mod->is_mixt_mod == YES)
     {
       MIXT_Update_Eigen(mod);
       return;
     }
 
-  if(mod->update_eigen)
+
+  if(mod->update_eigen == YES)
     {
       //Update the Q-matrix first before computing the Eigen(because the Eigen is computed based on the Q-matrix)
       if(mod->use_m4mod == NO)
@@ -925,13 +886,13 @@ void Update_Eigen(t_mod *mod)
           if(mod->io->datatype == NT)
             {
               if(mod->whichmodel == GTR)
-                 Update_Qmat_GTR(mod->r_mat->rr->v, mod->r_mat->rr_val->v, mod->r_mat->rr_num->v, mod->e_frq->pi->v, mod->r_mat->qmat->v);
+                Update_Qmat_GTR(mod->r_mat->rr->v, mod->r_mat->rr_val->v, mod->r_mat->rr_num->v, mod->e_frq->pi->v, mod->r_mat->qmat->v);
               else if(mod->whichmodel == CUSTOM)
-                 Update_Qmat_GTR(mod->r_mat->rr->v, mod->r_mat->rr_val->v, mod->r_mat->rr_num->v, mod->e_frq->pi->v, mod->r_mat->qmat->v);
+                Update_Qmat_GTR(mod->r_mat->rr->v, mod->r_mat->rr_val->v, mod->r_mat->rr_num->v, mod->e_frq->pi->v, mod->r_mat->qmat->v);
               else if(mod->whichmodel == HKY85)
-                 Update_Qmat_HKY(mod->kappa->v, mod->e_frq->pi->v, mod->r_mat->qmat->v);
+                Update_Qmat_HKY(mod->kappa->v, mod->e_frq->pi->v, mod->r_mat->qmat->v);
               else /* Any other nucleotide-based t_mod */
-                 Update_Qmat_HKY(mod->kappa->v, mod->e_frq->pi->v, mod->r_mat->qmat->v);
+                Update_Qmat_HKY(mod->kappa->v, mod->e_frq->pi->v, mod->r_mat->qmat->v);
             }
         }
       else
@@ -939,13 +900,16 @@ void Update_Eigen(t_mod *mod)
           M4_Update_Qmat(mod->m4mod,mod);
         }
 
-      //Now compute the Eigen
+      //Now compute the eigen vectors and values
       scalar   = 1.0;
       n_iter   = 0;
       result   = 0;
 
-      For(i,mod->ns*mod->ns) mod->r_mat->qmat_buff->v[i] = mod->r_mat->qmat->v[i];
-
+      For(i,mod->ns*mod->ns)
+        {
+          mod->r_mat->qmat_buff->v[i] = mod->r_mat->qmat->v[i];
+        }
+      
       /* compute eigenvectors/values */
       /*       if(!EigenRealGeneral(mod->eigen->size,mod->r_mat->qmat,mod->eigen->e_val, */
       /* 			  mod->eigen->e_val_im, mod->eigen->r_e_vect, */
@@ -984,12 +948,11 @@ 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]);
-
+            }
+          for(i=0;i<mod->eigen->size;i++) mod->eigen->e_val[i] /= scalar;
+          
+          /* compute the diagonal terms of exp(D) */
+          for(i=0;i<mod->ns;i++) mod->eigen->e_val[i] = (phydbl)exp(mod->eigen->e_val[i]);
 
       /* int j; */
       /* double *U,*V,*R; */
@@ -1006,15 +969,15 @@ void Update_Eigen(t_mod *mod)
 
       /* PhyML_Printf("\n"); */
       /* PhyML_Printf("\n. Q\n"); */
-      /* For(i,n) { For(j,n) PhyML_Printf("%7.3f ",mod->eigen->q[i*n+j]); PhyML_Printf("\n"); } */
+      /* for(i=0;i<n;i++) { for(j=0;j<n;j++) PhyML_Printf("%7.3f ",mod->eigen->q[i*n+j]); PhyML_Printf("\n"); } */
       /* PhyML_Printf("\n. U\n"); */
-      /* For(i,n) { For(j,n) PhyML_Printf("%7.3f ",U[i*n+j]); PhyML_Printf("\n"); } */
+      /* for(i=0;i<n;i++) { for(j=0;j<n;j++) PhyML_Printf("%7.3f ",U[i*n+j]); PhyML_Printf("\n"); } */
       /* PhyML_Printf("\n"); */
       /* PhyML_Printf("\n. V\n"); */
-      /* For(i,n) { For(j,n) PhyML_Printf("%7.3f ",V[i*n+j]); PhyML_Printf("\n"); } */
+      /* for(i=0;i<n;i++) { for(j=0;j<n;j++) PhyML_Printf("%7.3f ",V[i*n+j]); PhyML_Printf("\n"); } */
       /* PhyML_Printf("\n"); */
       /* PhyML_Printf("\n. Eigen\n"); */
-      /* For(i,n)  PhyML_Printf("%E ",mod->eigen->e_val[i]); */
+      /* for(i=0;i<n;i++)  PhyML_Printf("%E ",mod->eigen->e_val[i]); */
       /* PhyML_Printf("\n"); */
 
 /* 	  Exit("\n"); */
@@ -1037,14 +1000,13 @@ void Update_Eigen(t_mod *mod)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Switch_From_M4mod_To_Mod(t_mod *mod)
 {
   int i;
 
   mod->use_m4mod = 0;
   mod->ns = mod->m4mod->n_o;
-  For(i,mod->ns) mod->e_frq->pi->v[i] = mod->m4mod->o_fq[i];
+  for(i=0;i<mod->ns;i++) mod->e_frq->pi->v[i] = mod->m4mod->o_fq[i];
   mod->eigen->size = mod->ns;
   Switch_Eigen(YES,mod);
 }
@@ -1052,7 +1014,6 @@ void Switch_From_M4mod_To_Mod(t_mod *mod)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void PMat_MGF_Gamma(phydbl *Pij, phydbl shape, phydbl scale, phydbl scaling_fact, t_mod *mod)
 {
   int dim;
@@ -1064,24 +1025,24 @@ void PMat_MGF_Gamma(phydbl *Pij, phydbl shape, phydbl scale, phydbl scaling_fact
   imbd  = mod->eigen->e_val_im;
 
   /* Get the eigenvalues of Q (not the exponentials) */
-  For(i,dim) imbd[i]  = LOG(mod->eigen->e_val[i]);
+  for(i=0;i<dim;i++) imbd[i]  = log(mod->eigen->e_val[i]);
 
   /* Multiply them by the scaling factor */
-  For(i,dim) imbd[i]  *= scaling_fact;
+  for(i=0;i<dim;i++) imbd[i]  *= scaling_fact;
 
-  For(i,dim) imbd[i] *= -scale;
-  For(i,dim) imbd[i] += 1.0;
-  For(i,dim) imbd[i]  = POW(imbd[i],-shape);
+  for(i=0;i<dim;i++) imbd[i] *= -scale;
+  for(i=0;i<dim;i++) imbd[i] += 1.0;
+  for(i=0;i<dim;i++) imbd[i]  = POW(imbd[i],-shape);
 
-  For(i,dim) For(k,dim) uexpt[i*dim+k] = mod->eigen->r_e_vect[i*dim+k] * imbd[k];
+  for(i=0;i<dim;i++) for(k=0;k<dim;k++) uexpt[i*dim+k] = mod->eigen->r_e_vect[i*dim+k] * imbd[k];
 
-  For(i,dim) For(k,dim) Pij[dim*i+k] = .0;
+  for(i=0;i<dim;i++) for(k=0;k<dim;k++) Pij[dim*i+k] = .0;
 
-  For(i,dim)
+  for(i=0;i<dim;i++)
     {
-      For(j,dim)
+      for(j=0;j<dim;j++)
 	{
-	  For(k,dim)
+	  for(k=0;k<dim;k++)
 	    {
 	      Pij[dim*i+j] += (uexpt[i*dim+k] * mod->eigen->l_e_vect[k*dim+j]);
 	    }
@@ -1093,10 +1054,10 @@ void PMat_MGF_Gamma(phydbl *Pij, phydbl shape, phydbl scale, phydbl scaling_fact
   /* printf("\n. Pij: %f",Pij[1]); */
 
   /* printf("\n. Pmat"); */
-  /* For(i,dim) */
+  /* for(i=0;i<dim;i++) */
   /*   { */
   /*     printf("\n"); */
-  /*     For(j,dim) */
+  /*     for(j=0;j<dim;j++) */
   /* 	{ */
   /* 	  printf("%12f ",Pij[i*dim+j]); */
   /* 	} */
@@ -1112,7 +1073,7 @@ void Switch_From_Mod_To_M4mod(t_mod *mod)
   int i;
   mod->use_m4mod = 1;
   mod->ns = mod->m4mod->n_o * mod->m4mod->n_h;
-  For(i,mod->ns) mod->e_frq->pi->v[i] = mod->m4mod->o_fq[i%mod->m4mod->n_o] * mod->m4mod->h_fq[i/mod->m4mod->n_o];
+  for(i=0;i<mod->ns;i++) mod->e_frq->pi->v[i] = mod->m4mod->o_fq[i%mod->m4mod->n_o] * mod->m4mod->h_fq[i/mod->m4mod->n_o];
   mod->eigen->size = mod->ns;
   Switch_Eigen(YES,mod);
 }
@@ -1137,12 +1098,12 @@ phydbl General_Dist(phydbl *F, t_mod *mod, eigen *eigen_struct)
   pi       = (phydbl *)mCalloc(eigen_struct->size,sizeof(phydbl));
   mod_pi   = (phydbl *)mCalloc(eigen_struct->size,sizeof(phydbl));
 
-  For(i,mod->ns) mod_pi[i] = mod->e_frq->pi->v[i];
+  for(i=0;i<mod->ns;i++) mod_pi[i] = mod->e_frq->pi->v[i];
 
   sum = .0;
-  For(i,eigen_struct->size)
+  for(i=0;i<eigen_struct->size;i++)
     {
-      For(j,eigen_struct->size)
+      for(j=0;j<eigen_struct->size;j++)
         {
           pi[i] += (F[eigen_struct->size*i+j] + F[eigen_struct->size*j+i])/2.;
           sum += F[eigen_struct->size*i+j];
@@ -1153,13 +1114,13 @@ phydbl General_Dist(phydbl *F, t_mod *mod, eigen *eigen_struct)
   Divide_Mat_By_Vect(&F,mod->e_frq->pi->v,eigen_struct->size);
 
   /* Eigen decomposition of pi^{-1} x F */
-  For(i,eigen_struct->size) For(j,eigen_struct->size) F_phydbl[eigen_struct->size*i+j] = F[eigen_struct->size*i+j];
+  for(i=0;i<eigen_struct->size;i++) for(j=0;j<eigen_struct->size;j++) F_phydbl[eigen_struct->size*i+j] = F[eigen_struct->size*i+j];
 
   if(Eigen(1,F_phydbl,mod->eigen->size,mod->eigen->e_val,
        mod->eigen->e_val_im,mod->eigen->r_e_vect,
        mod->eigen->r_e_vect_im,mod->eigen->space))
     {
-      For(i,mod->ns) mod->e_frq->pi->v[i] = mod_pi[i];
+      for(i=0;i<mod->ns;i++) mod->e_frq->pi->v[i] = mod_pi[i];
       Update_Qmat_GTR(mod->r_mat->rr->v, mod->r_mat->rr_val->v, mod->r_mat->rr_num->v, mod->e_frq->pi->v, mod->r_mat->qmat->v);
       Free(pi);
       Free(mod_pi);
@@ -1168,44 +1129,44 @@ phydbl General_Dist(phydbl *F, t_mod *mod, eigen *eigen_struct)
 
   /* Get the left eigen vector of pi^{-1} x F */
   For(i,eigen_struct->size*eigen_struct->size) eigen_struct->l_e_vect[i] = eigen_struct->r_e_vect[i];
-  if(!Matinv(eigen_struct->l_e_vect,eigen_struct->size,eigen_struct->size,YES)<0)
+  if(!Matinv(eigen_struct->l_e_vect,eigen_struct->size,eigen_struct->size,YES))
     {
-      For(i,mod->ns) mod->e_frq->pi->v[i] = mod_pi[i];
+      for(i=0;i<mod->ns;i++) mod->e_frq->pi->v[i] = mod_pi[i];
       Update_Qmat_GTR(mod->r_mat->rr->v, mod->r_mat->rr_val->v, mod->r_mat->rr_num->v, mod->e_frq->pi->v, mod->r_mat->qmat->v);
       Free(pi);
       Free(mod_pi);
       return -1.;
     }
 
-  /* LOG of eigen values */
-  For(i,eigen_struct->size)
+  /* log of eigen values */
+  for(i=0;i<eigen_struct->size;i++)
     {
 /*       if(eigen_struct->e_val[i] < 0.0) eigen_struct->e_val[i] = 0.0001; */
-      eigen_struct->e_val[i] = (phydbl)LOG(eigen_struct->e_val[i]);
+      eigen_struct->e_val[i] = (phydbl)log(eigen_struct->e_val[i]);
      }
 
-  /* Matrix multiplications LOG(pi^{-1} x F) */
-  For(i,eigen_struct->size) For(j,eigen_struct->size)
+  /* Matrix multiplications log(pi^{-1} x F) */
+  for(i=0;i<eigen_struct->size;i++) for(j=0;j<eigen_struct->size;j++)
     eigen_struct->r_e_vect[eigen_struct->size*i+j] =
     eigen_struct->r_e_vect[eigen_struct->size*i+j] *
     eigen_struct->e_val[j];
-  For(i,eigen_struct->size) For(j,eigen_struct->size) F[eigen_struct->size*i+j] = .0;
-  For(i,eigen_struct->size) For(j,eigen_struct->size) For(k,eigen_struct->size)
+  for(i=0;i<eigen_struct->size;i++) for(j=0;j<eigen_struct->size;j++) F[eigen_struct->size*i+j] = .0;
+  for(i=0;i<eigen_struct->size;i++) for(j=0;j<eigen_struct->size;j++) for(k=0;k<eigen_struct->size;k++)
     F[eigen_struct->size*i+j] += eigen_struct->r_e_vect[eigen_struct->size*i+k] * eigen_struct->l_e_vect[eigen_struct->size*k+j];
 
 
   /* Trace */
   dist = .0;
-  For(i,eigen_struct->size) dist+=F[eigen_struct->size*i+i];
+  for(i=0;i<eigen_struct->size;i++) dist+=F[eigen_struct->size*i+i];
 
   sum_ev = .0;
-  For(i,mod->ns) sum_ev += mod->eigen->e_val[i];
+  for(i=0;i<mod->ns;i++) sum_ev += mod->eigen->e_val[i];
 
 /*   dist /= sum_ev; */
   dist /= -4.;
 
 
-/*   For(i,mod->ns) mod->e_frq->pi->v[i] = mod_pi[i]; */
+/*   for(i=0;i<mod->ns;i++) mod->e_frq->pi->v[i] = mod_pi[i]; */
 /*   Update_Qmat_GTR(mod); */
   Free(pi);
   Free(mod_pi);
@@ -1236,9 +1197,9 @@ phydbl GTR_Dist(phydbl *F, phydbl alpha, eigen *eigen_struct)
 /*   F[4*3+0] = 3./4898.;    F[4*3+1] = 117./4898.;  F[4*3+2] = 1./4898.;   F[4*3+3] = 1126./4898.; */
 
   sum = 0.0;
-  For(i,eigen_struct->size)
+  for(i=0;i<eigen_struct->size;i++)
     {
-      For(j,eigen_struct->size)
+      for(j=0;j<eigen_struct->size;j++)
         {
           pi[i] += (F[eigen_struct->size*i+j] + F[eigen_struct->size*j+i])/2.;
           sum += F[eigen_struct->size*i+j];
@@ -1247,11 +1208,11 @@ phydbl GTR_Dist(phydbl *F, phydbl alpha, eigen *eigen_struct)
 
 /* /\*   Jukes and Cantor correction *\/ */
 /*   sum = .0; */
-/*   For(i,eigen_struct->size) sum += F[eigen_struct->size*i+i]; */
+/*   for(i=0;i<eigen_struct->size;i++) sum += F[eigen_struct->size*i+i]; */
 /*   sum = 1.-sum; */
 /*   For(i,eigen_struct->size*eigen_struct->size) F[i] = sum/12.; */
-/*   For(i,eigen_struct->size) F[eigen_struct->size*i+i] = (1.-sum)/4.; */
-/*   For(i,eigen_struct->size) pi[i] = 1./(phydbl)eigen_struct->size; */
+/*   for(i=0;i<eigen_struct->size;i++) F[eigen_struct->size*i+i] = (1.-sum)/4.; */
+/*   for(i=0;i<eigen_struct->size;i++) pi[i] = 1./(phydbl)eigen_struct->size; */
 
 
   Make_Symmetric(&F,eigen_struct->size);
@@ -1259,7 +1220,7 @@ phydbl GTR_Dist(phydbl *F, phydbl alpha, eigen *eigen_struct)
 
 
   /* Eigen decomposition of pi^{-1} x F */
-  For(i,eigen_struct->size) For(j,eigen_struct->size) F_phydbl[eigen_struct->size*i+j] = F[eigen_struct->size*i+j];
+  for(i=0;i<eigen_struct->size;i++) for(j=0;j<eigen_struct->size;j++) F_phydbl[eigen_struct->size*i+j] = F[eigen_struct->size*i+j];
   if(Eigen(1,F_phydbl,eigen_struct->size,eigen_struct->e_val,
        eigen_struct->e_val_im,eigen_struct->r_e_vect,
        eigen_struct->r_e_vect_im,eigen_struct->space))
@@ -1270,33 +1231,33 @@ phydbl GTR_Dist(phydbl *F, phydbl alpha, eigen *eigen_struct)
 
   /* Get the left eigen vector of pi^{-1} x F */
   For(i,eigen_struct->size*eigen_struct->size) eigen_struct->l_e_vect[i] = eigen_struct->r_e_vect[i];
-  if(!Matinv(eigen_struct->l_e_vect,eigen_struct->size,eigen_struct->size,YES)<0) {Free(pi); return -1.;}
+  if(!Matinv(eigen_struct->l_e_vect,eigen_struct->size,eigen_struct->size,YES)) {Free(pi); return -1.;}
 
   /* Equation (3) + inverse of the moment generating function for the gamma distribution (see Waddell & Steel, 1997) */
-  For(i,eigen_struct->size)
+  for(i=0;i<eigen_struct->size;i++)
     {
       if(eigen_struct->e_val[i] < 0.0)
     {
       eigen_struct->e_val[i] = 0.0001;
     }
       if(alpha < .0)
-    eigen_struct->e_val[i] = (phydbl)LOG(eigen_struct->e_val[i]);
+    eigen_struct->e_val[i] = (phydbl)log(eigen_struct->e_val[i]);
       else
     eigen_struct->e_val[i] = alpha * (1. - (phydbl)POW(eigen_struct->e_val[i],-1./alpha));
      }
 
-  /* Matrix multiplications pi x LOG(pi^{-1} x F) */
-  For(i,eigen_struct->size) For(j,eigen_struct->size)
+  /* Matrix multiplications pi x log(pi^{-1} x F) */
+  for(i=0;i<eigen_struct->size;i++) for(j=0;j<eigen_struct->size;j++)
     eigen_struct->r_e_vect[eigen_struct->size*i+j] =
     eigen_struct->r_e_vect[eigen_struct->size*i+j] * eigen_struct->e_val[j];
-  For(i,eigen_struct->size) For(j,eigen_struct->size) F[eigen_struct->size*i+j] = .0;
-  For(i,eigen_struct->size) For(j,eigen_struct->size) For(k,eigen_struct->size)
+  for(i=0;i<eigen_struct->size;i++) for(j=0;j<eigen_struct->size;j++) F[eigen_struct->size*i+j] = .0;
+  for(i=0;i<eigen_struct->size;i++) for(j=0;j<eigen_struct->size;j++) for(k=0;k<eigen_struct->size;k++)
     F[eigen_struct->size*i+j] += eigen_struct->r_e_vect[eigen_struct->size*i+k] * eigen_struct->l_e_vect[eigen_struct->size*k+j];
-  For(i,eigen_struct->size) For(j,eigen_struct->size) F[eigen_struct->size*i+j] *= pi[i];
+  for(i=0;i<eigen_struct->size;i++) for(j=0;j<eigen_struct->size;j++) F[eigen_struct->size*i+j] *= pi[i];
 
   /* Trace */
   dist = .0;
-  For(i,eigen_struct->size) dist-=F[eigen_struct->size*i+i];
+  for(i=0;i<eigen_struct->size;i++) dist-=F[eigen_struct->size*i+i];
 
 /*   PhyML_Printf("\nDIST = %f\n",dist); Exit("\n"); */
 
diff --git a/src/models.h b/src/models.h
index 1f59467..5332151 100644
--- a/src/models.h
+++ b/src/models.h
@@ -21,10 +21,10 @@ the GNU public licence.  See http://www.opensource.org for details.
 #include "stats.h"
 #include "mixt.h"
 
-void PMat(phydbl l, t_mod *mod, int pos, phydbl *Pij);
+void PMat(phydbl l, t_mod *mod, int pos, phydbl *Pij, phydbl *tPij);
 void  PMat_K80(phydbl l,phydbl kappa, int pos, phydbl *Pij);
 void  PMat_TN93(phydbl l, t_mod *mod, int pos, phydbl *Pij);
-void  PMat_Empirical(phydbl l, t_mod *mod, int pos, phydbl *Pij);
+void  PMat_Empirical(phydbl l, t_mod *mod, int pos, phydbl *Pij, phydbl *tPij);
 void PMat_Zero_Br_Len(t_mod *mod, int pos, phydbl *Pij);
 void PMat_Gamma(phydbl l, t_mod *mod, int pos, phydbl *Pij);
 int GetDaa (phydbl *daa, phydbl *pi, char *file_name);
@@ -43,5 +43,6 @@ void Update_Eigen(t_mod *mod);
 void Update_RAS(t_mod *mod);
 void Update_Efrq(t_mod *mod);
 void PMat_MGF_Gamma(phydbl *Pij, phydbl shape, phydbl scale, phydbl scaling_fact, t_mod *mod);
+void Update_Boundaries(t_mod *mod);
 
 #endif
diff --git a/src/mpi_boot.c b/src/mpi_boot.c
index 86e7a0e..e05f0da 100644
--- a/src/mpi_boot.c
+++ b/src/mpi_boot.c
@@ -1,6 +1,6 @@
 /*
 
-PhyML:  a program that  computes maximum likelihood phyLOGenies from
+PhyML:  a program that  computes maximum likelihood phylogenies from
 DNA or AA homologous sequences.
 
 Copyright (C) Stephane Guindon. Oct 2003 onward.
@@ -33,6 +33,12 @@ void Bootstrap_MPI(t_tree *tree)
   int *score_par, *score_tot;
   char *bootStr, *t;
   
+  if(tree->is_mixt_tree == YES)
+    {
+      PhyML_Printf("\n== Bootstrap option not yet available for partition/mixture analysis.");
+      Generic_Exit(__FILE__,__LINE__,__FUNCTION__);    
+    }
+
   randomRecv = nbElem = bootRecv = 0;
 
   tree->print_boot_val       = 1;
@@ -46,7 +52,7 @@ void Bootstrap_MPI(t_tree *tree)
   Get_Bip(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree);
 
   n_site = 0;
-  For(j,tree->data->crunch_len) For(k,tree->data->wght[j])
+  for(j=0;j<tree->data->crunch_len;j++) For(k,tree->data->wght[j])
     {
       site_num[n_site] = j;
       n_site++;
@@ -64,7 +70,7 @@ void Bootstrap_MPI(t_tree *tree)
       tree->mod->bootstrap = nbRep * Global_numTask;
       if (Global_myRank == 0) {
         PhyML_Printf("\n. The number of replicates is not a multiple of %d CPUs.\n", Global_numTask);
-        PhyML_Printf("\n. Will run %d replicates analysis.\n", tree->mod->bootstrap);
+        PhyML_Printf("\n. Will run %d replicates.\n", tree->mod->bootstrap);
       }
     }
   else
@@ -89,63 +95,77 @@ void Bootstrap_MPI(t_tree *tree)
 
   For(replicate, nbRep)
     {
-      For(j,boot_data->crunch_len) boot_data->wght[j] = 0;
+      for(j=0;j<boot_data->crunch_len;j++) boot_data->wght[j] = 0;
 
       // Send random data to other process
-      if (Global_myRank == 0) {
-        // Compute number of data to send
-        if (tree->mod->bootstrap - randomRecv > Global_numTask)
-          nbElem = Global_numTask;
-        else
-          nbElem = tree->mod->bootstrap - randomRecv;
-
-        For(i,nbElem) {
-          For(j,boot_data->crunch_len) boot_data->wght[j] = 0;
-          init_len = 0;
-          // Create random data
-          For(j,boot_data->init_len)
+      if (Global_myRank == 0) 
+        {
+          // Compute number of data to send
+          if (tree->mod->bootstrap - randomRecv > Global_numTask)
+            nbElem = Global_numTask;
+          else
+            nbElem = tree->mod->bootstrap - randomRecv;
+          
+          for(i=0;i<nbElem;i++) 
             {
-              position = Rand_Int(0,(int)(tree->data->init_len-1.0));
-              boot_data->wght[site_num[position]] += 1;
-              init_len++;
-            }
-            
+              for(j=0;j<boot_data->crunch_len;j++) boot_data->wght[j] = 0;
+
+              init_len = 0;
+              // Create random data
+              for(j=0;j<boot_data->init_len;j++)
+                {
+                  position = Rand_Int(0,(int)(tree->data->init_len-1.0));
+                  boot_data->wght[site_num[position]] += 1;
+                  init_len++;
+                }
+              
 
-          if (init_len != tree->data->init_len) {
-            MPI_Finalize();
-            Warn_And_Exit("\n== Pb. when copying sequences...\n");
-          }
-          // Send random data to other process, not to current process
-          if (i < nbElem-1) {
-            MPI_Ssend (boot_data->wght, boot_data->crunch_len, MPI_INT, i+1, Global_myRank, MPI_COMM_WORLD);
+              if (init_len != tree->data->init_len) 
+                {
+                  PhyML_Printf("\n== thread: %d || init: %d %d here\n",Global_myRank,init_len,tree->data->init_len);
+                  fflush(NULL);
+                  Generic_Exit(__FILE__,__LINE__,__FUNCTION__);    
+                }
+              
+              // Send random data to other process, not to current process
+              if (i < nbElem-1)
+                {
+                  MPI_Ssend (boot_data->wght, boot_data->crunch_len, MPI_DOUBLE, i+1, Global_myRank, MPI_COMM_WORLD);
 #ifdef MPI_DEBUG
-fprintf (stderr, "\ntask %d, sending random to %d done\n", Global_myRank, i+1);
-fflush(stderr);
+                  fprintf (stderr, "\ntask %d, sending random to %d done\n", Global_myRank, i+1);
+                  fflush(stderr);
 #endif
-          }
-          randomRecv++;
+                }
+              randomRecv++;
+            }
         }
-      }
-      else {
-        MPI_Recv (boot_data->wght, boot_data->crunch_len, MPI_INT, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &Stat);
+      else 
+        {
+          MPI_Recv(boot_data->wght, boot_data->crunch_len, MPI_DOUBLE, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &Stat);
 #ifdef MPI_DEBUG
-fprintf (stderr, "\ntask %d, receiving random from task %d done\n", Global_myRank, Stat.MPI_SOURCE);
-fflush(stderr);
+          fprintf (stderr, "\ntask %d, receiving random from task %d done\n", Global_myRank, Stat.MPI_SOURCE);
+          fflush(stderr);
 #endif
-      }
+
+
+        }
 
       init_len = 0;
-      For(j,boot_data->crunch_len) init_len += boot_data->wght[j];
+      for(j=0;j<boot_data->crunch_len;j++) init_len += boot_data->wght[j];
 
-      if(init_len != tree->data->init_len) {
-        MPI_Finalize();
-        Warn_And_Exit("\n== Pb when copying sequences\n");
-      }
+
+      if(init_len != tree->data->init_len) 
+        {
+          printf("\n== thread: %d init: %d %d\n",Global_myRank,init_len,tree->data->init_len);
+          Generic_Exit(__FILE__,__LINE__,__FUNCTION__);    
+        }
+      
 
       (tree->mod->io->datatype == NT)?
         (Get_Base_Freqs(boot_data)):
         (Get_AA_Freqs(boot_data));
 
+
       if(tree->io->random_boot_seq_order) Randomize_Sequence_Order(boot_data);
 
       Set_D_States(boot_data,tree->io->datatype,tree->io->state_len);
@@ -171,9 +191,9 @@ fflush(stderr);
 	      }
 	    case NEXUS:
 	      {
-		PhyML_Printf("\n. Unfortunately, PhyML cannot read NEXUS files and perform a bootstrap analysis."); 
-		PhyML_Printf("\n. Please use the PHYLIP format.."); 
-		PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__);
+		PhyML_Printf("\n== Unfortunately, PhyML cannot read NEXUS files and perform a bootstrap analysis."); 
+		PhyML_Printf("\n== Please use the PHYLIP format."); 
+		PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__);
 		Warn_And_Exit("");
 		break;
 	      }
@@ -198,7 +218,7 @@ fflush(stderr);
       boot_tree->mod                = boot_mod;
       boot_tree->io                 = tree->io;
       boot_tree->data               = boot_data;
-      boot_tree->mod->s_opt->print  = 0;
+      boot_tree->verbose            = VL0;
       boot_tree->n_pattern          = boot_tree->data->crunch_len;
       boot_tree->io->print_site_lnl = 0;
       boot_tree->io->print_trace    = 0;
@@ -214,12 +234,16 @@ fflush(stderr);
       Fill_Dir_Table(boot_tree);
       Update_Dirs(boot_tree);
 
-      if(tree->mod->s_opt->greedy) Init_P_Lk_Tips_Double(boot_tree);
-      else                         Init_P_Lk_Tips_Int(boot_tree);
+      if(tree->mod->s_opt->greedy) Init_Partial_Lk_Tips_Double(boot_tree);
+      else                         Init_Partial_Lk_Tips_Int(boot_tree);
       Init_Ui_Tips(boot_tree);
-      Init_P_Pars_Tips(boot_tree);
+      Init_Partial_Pars_Tips(boot_tree);
       Br_Len_Not_Involving_Invar(boot_tree);
       
+      Switch_Eigen(YES,boot_tree->mod);                 
+      Lk(NULL,boot_tree);
+      Switch_Eigen(NO,boot_tree->mod);
+
       if(boot_tree->mod->s_opt->opt_topo)
         {
           if(boot_tree->mod->s_opt->topo_search == NNI_MOVE) 
@@ -235,7 +259,7 @@ fflush(stderr);
       else
         {
           if(boot_tree->mod->s_opt->opt_subst_param || boot_tree->mod->s_opt->opt_bl)
-            Round_Optimize(boot_tree,boot_tree->data,ROUND_MAX);
+            Round_Optimize(boot_tree,ROUND_MAX);
           else
             Lk(NULL,boot_tree);
         }
@@ -265,7 +289,7 @@ fflush(stderr);
             fprintf(tree->io->fp_out_boot_tree,"%s\n",s);
             fprintf(tree->io->fp_out_boot_stats,"%s\n",t);
             bootRecv++;
-            PhyML_Printf(".");
+            PhyML_Printf("\u2022");
 	    if(!((bootRecv)%tree->io->boot_prog_every)) 
 	      {
 		PhyML_Printf("] %4d/%4d\n  ",bootRecv,tree->mod->bootstrap);
@@ -302,7 +326,7 @@ fflush(stderr);
 		  fprintf(tree->io->fp_out_boot_stats,"%s\n", bootStr);
 		
 		bootRecv++;
-		PhyML_Printf(".");
+		PhyML_Printf("\u2022");
 		if(!((bootRecv)%tree->io->boot_prog_every)) {
 		  PhyML_Printf("] %4d/%4d\n  ",bootRecv,tree->mod->bootstrap);
 		  if(bootRecv != tree->mod->bootstrap) PhyML_Printf("[");
@@ -350,7 +374,7 @@ fflush(stdout);
     if(((bootRecv)%tree->io->boot_prog_every)) PhyML_Printf("] %4d/%4d\n ",bootRecv,tree->mod->bootstrap);
 
 PhyML_Printf("\n\n. Exiting bootstrap function normally."); fflush(NULL);
-  tree->lock_topo = 1; /* TopoLOGy should not be modified afterwards */
+tree->lock_topo = 1; /* Topology should not be modified afterwards */
 
   if(tree->io->print_boot_trees)
     {
@@ -358,7 +382,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);
 }
 
@@ -499,7 +523,7 @@ void Print_Fp_Out_Lines_MPI(t_tree *tree, option *io, int n_data_set, char *boot
     {
       int i,j;
 
-      For(i,4)
+      for(i=0;i<4;i++)
         {
           if (i!=0) {
             /*format*/
@@ -512,7 +536,7 @@ void Print_Fp_Out_Lines_MPI(t_tree *tree, option *io, int n_data_set, char *boot
             snprintf(tmp, T_MAX_LINE, "             \t                                      \t");
             strncat (s, tmp, T_MAX_LINE);
           }
-          For(j,4) {
+          for(j=0;j<4;j++) {
             snprintf(tmp, T_MAX_LINE, "%8.5f  ",tree->mod->r_mat->qmat->v[i*4+j]);
             strncat (s, tmp, T_MAX_LINE);
           }
diff --git a/src/nexus.c b/src/nexus.c
index e0decc0..8e6813b 100644
--- a/src/nexus.c
+++ b/src/nexus.c
@@ -16,14 +16,14 @@ void Find_Nexus_Com(char *token, nexcom **found_com, nexparm **default_parm, nex
 {
   int i,j,tokenlen,ndiff;
     
-  For(i,N_MAX_NEX_COM) 
+  for(i=0;i<N_MAX_NEX_COM;i++) 
     {
       tokenlen = strlen(token);
       ndiff = -1;
       if(tokenlen && (tokenlen == strlen(com_list[i]->name)))
 	{
 	  ndiff = 0;
-	  For(j,tokenlen)
+	  for(j=0;j<tokenlen;j++)
 	    {
 	      Lowercase(token+j);
 	      Lowercase(com_list[i]->name+j);
@@ -54,14 +54,14 @@ void Find_Nexus_Parm(char *token, nexparm **found_parm, nexcom *curr_com)
       Exit("");
     }
 
-  For(i,curr_com->nparm)
+  for(i=0;i<curr_com->nparm;i++)
     {
       tokenlen = strlen(token);
       ndiff = -1;
       if(tokenlen == strlen(curr_com->parm[i]->name))
 	{
 	  ndiff = 0;
-	  For(j,tokenlen)
+	  for(j=0;j<tokenlen;j++)
 	    {
 	      Lowercase(token+j);
 	      Lowercase(curr_com->parm[i]->name+j);
@@ -369,7 +369,7 @@ int Read_Nexus_Format(char *token, nexparm *curr_parm, option *io)
 
       int len;
       len = strlen(io->alphabet[0]);
-      For(i,io->mod->ns)
+      for(i=0;i<io->mod->ns;i++)
 	{
 	  if(strlen(io->alphabet[i]) != len)
 	    {
@@ -380,7 +380,7 @@ int Read_Nexus_Format(char *token, nexparm *curr_parm, option *io)
 	}
       io->state_len = len;      
 
-/*       For(i,io->mod->ns) PhyML_Printf("\n. '%s'",io->alphabet[i]); */
+/*       for(i=0;i<io->mod->ns;i++) PhyML_Printf("\n. '%s'",io->alphabet[i]); */
     }
   
   else if(!strcmp(curr_parm->name,"equate"))
diff --git a/src/optimiz.c b/src/optimiz.c
index 6ddc17b..79cfbc8 100644
--- a/src/optimiz.c
+++ b/src/optimiz.c
@@ -1,7 +1,7 @@
 /*
 
-PhyML :  a program that  computes maximum likelihood  phyLOGenies from
-DNA or AA homoLOGous sequences
+PhyML :  a program that  computes maximum likelihood  phylogenies from
+DNA or AA homologous sequences
 
 Copyright (C) Stephane Guindon. Oct 2003 onward
 
@@ -12,11 +12,11 @@ the GNU public licence.  See http://www.opensource.org for details.
 
 #include "optimiz.h"
 
+static phydbl Br_Len_Newton_Raphson(phydbl *l, t_edge *b, int n_iter_max, phydbl tol, t_tree *tree);
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Optimize_Single_Param_Generic(t_tree *tree, phydbl *param, phydbl lim_inf, phydbl lim_sup, phydbl tol, int n_max_iter, int quickdirty)
 {
   phydbl lk_init;
@@ -38,10 +38,7 @@ void Optimize_Single_Param_Generic(t_tree *tree, phydbl *param, phydbl lim_inf,
 
   if(tree->c_lnL < lk_init - tree->mod->s_opt->min_diff_lk_global)
     {
-      PhyML_Printf("\n== %.10f < %.10f --> diff=%.10f param value = %f\n",
-         tree->c_lnL,lk_init,
-         tree->c_lnL-lk_init,
-         *param);
+      PhyML_Printf("\n== %.10f < %.10f --> diff=%.10f param value = %f\n",tree->c_lnL,lk_init,tree->c_lnL-lk_init,*param);
       Exit("\n== Optimisation failed !\n");
     }
 }
@@ -50,10 +47,10 @@ void Optimize_Single_Param_Generic(t_tree *tree, phydbl *param, phydbl lim_inf,
 //////////////////////////////////////////////////////////////
 
 int Generic_Brak(phydbl *param,
-         phydbl *ax, phydbl *bx, phydbl *cx,
-         phydbl *fa, phydbl *fb, phydbl *fc,
-         phydbl lim_inf, phydbl lim_sup,
-         t_tree *tree)
+                 phydbl *ax, phydbl *bx, phydbl *cx,
+                 phydbl *fa, phydbl *fb, phydbl *fc,
+                 phydbl lim_inf, phydbl lim_sup,
+                 t_tree *tree)
 {
    phydbl ulim,u,r,q,fu,dum;
 
@@ -68,9 +65,9 @@ int Generic_Brak(phydbl *param,
    if(*param < lim_inf) *param = lim_inf;
    *fb=-Lk(NULL,tree);
    if (*fb > *fa) {
-      SHFT(dum,*ax,*bx,dum)
-      SHFT(dum,*fb,*fa,dum)
-   }
+     SHFT(dum,*ax,*bx,dum)
+       SHFT(dum,*fb,*fa,dum)
+       }
    *cx=(*bx)+MNBRAK_GOLD*(*bx-*ax);
    *param = FABS(*cx);
    if(*param > lim_sup) *param = lim_sup;
@@ -78,7 +75,7 @@ int Generic_Brak(phydbl *param,
    *fc=-Lk(NULL,tree);
    while (*fb > *fc)
      {
-
+       
        if(*ax > lim_sup) *ax = lim_sup;
        if(*ax < lim_inf) *ax = lim_inf;
        if(*bx > lim_sup) *bx = lim_sup;
@@ -87,79 +84,79 @@ int Generic_Brak(phydbl *param,
        if(*cx < lim_inf) *cx = lim_inf;
        if(u   > lim_sup) u   = lim_sup;
        if(u   < lim_inf) u   = lim_inf;
-
+       
        r=(*bx-*ax)*(*fb-*fc);
        q=(*bx-*cx)*(*fb-*fa);
        u=(*bx)-((*bx-*cx)*q-(*bx-*ax)*r)/
-               (2.0*SIGN(MAX(FABS(q-r),MNBRAK_TINY),q-r));
+         (2.0*SIGN(MAX(FABS(q-r),MNBRAK_TINY),q-r));
        ulim=(*bx)+MNBRAK_GLIMIT*(*cx-*bx);
-
+       
        if ((*bx-u)*(u-*cx) > lim_inf)
-     {
-       *param = FABS(u);
-       if(*param > lim_sup) {*param = u = lim_sup;}
-       if(*param < lim_inf) {*param = u = lim_inf;}
-       fu=-Lk(NULL,tree);
-       if (fu < *fc)
          {
-           *ax=(*bx);
-           *bx=u;
-           *fa=(*fb);
-           *fb=fu;
-           (*ax)=FABS(*ax);
-           (*bx)=FABS(*bx);
-           (*cx)=FABS(*cx);
-           return(0);
-         }
-       else if (fu > *fb)
-         {
-           *cx=u;
-           *fc=fu;
-           (*ax)=FABS(*ax);
-           (*bx)=FABS(*bx);
-           (*cx)=FABS(*cx);
-           return(0);
+           *param = FABS(u);
+           if(*param > lim_sup) {*param = u = lim_sup;}
+           if(*param < lim_inf) {*param = u = lim_inf;}
+           fu=-Lk(NULL,tree);
+           if (fu < *fc)
+             {
+               *ax=(*bx);
+               *bx=u;
+               *fa=(*fb);
+               *fb=fu;
+               (*ax)=FABS(*ax);
+               (*bx)=FABS(*bx);
+               (*cx)=FABS(*cx);
+               return(0);
+             }
+           else if (fu > *fb)
+             {
+               *cx=u;
+               *fc=fu;
+               (*ax)=FABS(*ax);
+               (*bx)=FABS(*bx);
+               (*cx)=FABS(*cx);
+               return(0);
+             }
+           u=(*cx)+MNBRAK_GOLD*(*cx-*bx);
+           *param = FABS(u);
+           if(*param > lim_sup) {*param = u = lim_sup;}
+           if(*param < lim_inf) {*param = u = lim_inf;}
+           fu=-Lk(NULL,tree);
          }
-       u=(*cx)+MNBRAK_GOLD*(*cx-*bx);
-       *param = FABS(u);
-       if(*param > lim_sup) {*param = u = lim_sup;}
-       if(*param < lim_inf) {*param = u = lim_inf;}
-       fu=-Lk(NULL,tree);
-     }
        else if ((*cx-u)*(u-ulim) > lim_inf)
-     {
-       *param = FABS(u);
-       if(*param > lim_sup) {*param = u = lim_sup;}
-       if(*param < lim_inf) {*param = u = lim_inf;}
-       fu=-Lk(NULL,tree);
-       if (fu < *fc)
          {
-           SHFT(*bx,*cx,u,*cx+MNBRAK_GOLD*(*cx-*bx))
            *param = FABS(u);
-           SHFT(*fb,*fc,fu,-Lk(NULL,tree))
+           if(*param > lim_sup) {*param = u = lim_sup;}
+           if(*param < lim_inf) {*param = u = lim_inf;}
+           fu=-Lk(NULL,tree);
+           if (fu < *fc)
+             {
+               SHFT(*bx,*cx,u,*cx+MNBRAK_GOLD*(*cx-*bx))
+                 *param = FABS(u);
+               SHFT(*fb,*fc,fu,-Lk(NULL,tree))
+                 }
          }
-     }
        else if ((u-ulim)*(ulim-*cx) >= lim_inf)
-     {
-       u=ulim;
-       *param = FABS(u);
-       if(*param > lim_sup) {*param = u = lim_sup;}
-       if(*param < lim_inf) {*param = u = lim_inf;}
-       fu=-Lk(NULL,tree);
-     }
+         {
+           u=ulim;
+           *param = FABS(u);
+           if(*param > lim_sup) {*param = u = lim_sup;}
+           if(*param < lim_inf) {*param = u = lim_inf;}
+           fu=-Lk(NULL,tree);
+         }
        else
-     {
-       u=(*cx)+MNBRAK_GOLD*(*cx-*bx);
-       *param = FABS(u);
-       if(*param > lim_sup) {*param = u = lim_sup;}
-       if(*param < lim_inf) {*param = u = lim_inf;}
-       fu=-Lk(NULL,tree);
-     }
+         {
+           u=(*cx)+MNBRAK_GOLD*(*cx-*bx);
+           *param = FABS(u);
+           if(*param > lim_sup) {*param = u = lim_sup;}
+           if(*param < lim_inf) {*param = u = lim_inf;}
+           fu=-Lk(NULL,tree);
+         }
        SHFT(*ax,*bx,*cx,u)
-       SHFT(*fa,*fb,*fc,fu)
-
-
-     }
+         SHFT(*fa,*fb,*fc,fu)
+         
+         
+         }
    (*ax)=FABS(*ax);
    (*bx)=FABS(*bx);
    (*cx)=FABS(*cx);
@@ -169,6 +166,115 @@ int Generic_Brak(phydbl *param,
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
+int Generic_Brak_Lk(phydbl *param,
+                    phydbl *ax, phydbl *bx, phydbl *cx,
+                    phydbl *fa, phydbl *fb, phydbl *fc,
+                    phydbl min, phydbl max,
+                    phydbl (*obj_func)(t_edge *,t_tree *,supert_tree *),
+                    t_edge *branch, t_tree *tree, supert_tree *stree)
+{
+   phydbl ulim,u,r,q,fu,dum;
+
+   *param = *ax;
+   if(*param < min) *param = min;
+   if(*param > max) *param = max;
+   *fa = -(*obj_func)(branch,tree,stree);
+
+   *param = *bx;
+   if(*param < min) *param = min;
+   if(*param > max) *param = max;
+   *fb = -(*obj_func)(branch,tree,stree);
+
+   if (*fb > *fa) 
+     {
+       SHFT(dum,*ax,*bx,dum)
+       SHFT(dum,*fb,*fa,dum)
+     }
+
+   *cx=(*bx)+MNBRAK_GOLD*(*bx-*ax);
+   *param = *cx;
+   if(*param < min) *param = min;
+   if(*param > max) *param = max;
+   *fc = -(*obj_func)(branch,tree,stree);
+
+   /* printf("\nx la: %f lb: %f lc: %f fa: %f fb: %f fc: %f",*ax,*bx,*cx,*fa,*fb,*fc); */
+   while (*fb > *fc)
+     {       
+       /* printf("\nx la: %f lb: %f lc: %f fa: %f fb: %f fc: %f",*ax,*bx,*cx,*fa,*fb,*fc); */
+       r=(*bx-*ax)*(*fb-*fc);
+       q=(*bx-*cx)*(*fb-*fa);
+       u=(*bx)-((*bx-*cx)*q-(*bx-*ax)*r)/
+         (2.0*SIGN(MAX(FABS(q-r),MNBRAK_TINY),q-r));
+       ulim=(*bx)+MNBRAK_GLIMIT*(*cx-*bx);
+       
+       if((*bx-u)*(u-*cx) > 0.0)
+         {
+           *param = u;
+           if(*param < min) *param = min;
+           if(*param > max) *param = max;
+           fu = -(*obj_func)(branch,tree,stree);
+
+           if (fu < *fc)
+             {
+               *ax=(*bx);
+               *bx=u;
+               *fa=(*fb);
+               *fb=fu;
+               return(0);
+             }
+           else if (fu > *fb)
+             {
+               *cx=u;
+               *fc=fu;
+               return(0);
+             }
+           u=(*cx)+MNBRAK_GOLD*(*cx-*bx);
+           *param = u;
+           if(*param < min) *param = min;
+           if(*param > max) *param = max;
+           fu = -(*obj_func)(branch,tree,stree);
+         }
+       else if ((*cx-u)*(u-ulim) > 0.0)
+         {
+           *param = u;
+           if(*param < min) *param = min;
+           if(*param > max) *param = max;
+           fu = -(*obj_func)(branch,tree,stree);
+
+           if (fu < *fc)
+             {
+               SHFT(*bx,*cx,u,*cx+MNBRAK_GOLD*(*cx-*bx))
+               *param = u;
+               if(*param < min) *param = min;
+               if(*param > max) *param = max;
+               SHFT(*fb,*fc,fu,-(*obj_func)(branch,tree,stree))
+             }
+         }
+       else if ((u-ulim)*(ulim-*cx) >= 0.0)
+         {
+           u=ulim;
+           *param = u;
+           if(*param < min) *param = min;
+           if(*param > max) *param = max;
+           fu = -(*obj_func)(branch,tree,stree);
+         }
+       else
+         {
+           u=(*cx)+MNBRAK_GOLD*(*cx-*bx);
+           *param = u;
+           if(*param < min) *param = min;
+           if(*param > max) *param = max;
+           fu = -(*obj_func)(branch,tree,stree);
+         }
+       SHFT(*ax,*bx,*cx,u)
+       SHFT(*fa,*fb,*fc,fu)
+         }
+   
+   return(0);
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
 
 phydbl Generic_Brent(phydbl ax, phydbl bx, phydbl cx, phydbl tol,
              phydbl *xmin, t_tree *tree, int n_iter_max,
@@ -188,7 +294,7 @@ phydbl Generic_Brent(phydbl ax, phydbl bx, phydbl cx, phydbl tol,
   fw=fv=fx=-Lk(NULL,tree);
   init_lnL = -fw;
 
-  PhyML_Printf("\n. init_lnL = %f a=%f b=%f c=%f\n",init_lnL,ax,bx,cx);
+  /* PhyML_Printf("\n. init_lnL = %f a=%f b=%f c=%f\n",init_lnL,ax,bx,cx); */
 
   for(iter=1;iter<=n_iter_max;iter++)
     {
@@ -241,7 +347,7 @@ phydbl Generic_Brent(phydbl ax, phydbl bx, phydbl cx, phydbl tol,
       (*xmin) = FABS(u);
       fu = -Lk(NULL,tree);
 
-      PhyML_Printf("\n. iter=%d/%d param=%f loglk=%f",iter,BRENT_IT_MAX,*xmin,tree->c_lnL);
+      /* PhyML_Printf("\n. iter=%d/%d param=%f loglk=%f",iter,BRENT_IT_MAX,*xmin,tree->c_lnL); */
 
 /*       if(fu <= fx) */
       if(fu < fx)
@@ -349,13 +455,13 @@ phydbl RRparam_GTR_Golden(phydbl ax, phydbl bx, phydbl cx, phydbl tol,
 
 
 phydbl Br_Len_Golden(phydbl ax, phydbl bx, phydbl cx, phydbl tol,
-             phydbl *xmin, t_edge *b_fcus, t_tree *tree)
+                     phydbl *xmin, t_edge *b_fcus, t_tree *tree)
 {
    phydbl f1,f2,x0,x1,x2,x3;
 
    x0=ax;
    x3=cx;
-   if (FABS(cx-bx) > FABS(bx-ax))
+   if(FABS(cx-bx) > FABS(bx-ax))
      {
        x1=bx;
        x2=bx+GOLDEN_C*(cx-bx);
@@ -365,34 +471,36 @@ phydbl Br_Len_Golden(phydbl ax, phydbl bx, phydbl cx, phydbl tol,
        x2=bx;
        x1=bx-GOLDEN_C*(bx-ax);
      }
-
-   b_fcus->l->v=x1;
+   
+   b_fcus->l->v = x1;
    f1 = -Lk(b_fcus,tree);
-   b_fcus->l->v=x2;
+   b_fcus->l->v = x2;
    f2 = -Lk(b_fcus,tree);
+
    while (FABS(x3-x0) > tol*(FABS(x1)+FABS(x2)))
      {
        if (f2 < f1)
-     {
-       SHFT3(x0,x1,x2,GOLDEN_R*x1+GOLDEN_C*x3)
-       b_fcus->l->v=x2;
-       SHFT2(f1,f2,-Lk(b_fcus,tree))
-     }
+         {
+           SHFT3(x0,x1,x2,GOLDEN_R*x1+GOLDEN_C*x3)
+           b_fcus->l->v = x2;
+           SHFT2(f1,f2,-Lk(b_fcus,tree))
+         }
        else
-     {
-       SHFT3(x3,x2,x1,GOLDEN_R*x2+GOLDEN_C*x0)
-       b_fcus->l->v=x1;
-       SHFT2(f2,f1,-Lk(b_fcus,tree))
-     }
+         {
+           SHFT3(x3,x2,x1,GOLDEN_R*x2+GOLDEN_C*x0)
+           b_fcus->l->v = x1;
+           SHFT2(f2,f1,-Lk(b_fcus,tree))
+         }
      }
+
    if (f1 < f2)
      {
-       *xmin=FABS(x1);
+       *xmin = x1;
        return -f1;
      }
    else
      {
-       *xmin=FABS(x2);
+       *xmin = x2;
        return -f2;
      }
 }
@@ -490,80 +598,75 @@ int Br_Len_Brak(phydbl *ax, phydbl *bx, phydbl *cx,
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-phydbl Br_Len_Brent(phydbl prop_min, phydbl prop_max, t_edge *b_fcus, t_tree *tree)
+phydbl Br_Len_Brent(t_edge *b, t_tree *tree)
 {
-  t_tree *loc_tree;
-  t_edge *loc_b;
   phydbl lk_begin, lk_end;
+  t_edge *mixt_b;
+  t_tree *mixt_tree;
 
-  lk_begin = UNLIKELY;
-  lk_end   = UNLIKELY;
-  loc_tree = tree;
-  loc_b    = b_fcus;
-
-
-  /*! Rewind back to the first mixt_tree */
-  while(loc_tree->prev)
-    {
-      loc_tree = loc_tree->prev;
-      loc_b    = loc_b->prev;
-    }
-
-  if(tree->is_mixt_tree)
+  
+  if(tree->is_mixt_tree == YES)
     {
-      MIXT_Br_Len_Brent(prop_min,prop_max,b_fcus,tree);
-      return loc_tree->c_lnL;
+      MIXT_Br_Len_Brent(b,tree);
+      return tree->c_lnL;
     }
 
-  if(b_fcus->l->onoff == OFF) return loc_tree->c_lnL;
-
-  if(isinf(prop_min) || isnan(prop_min)) prop_min = 1.E-04;
-  if(isinf(prop_max) || isnan(prop_max)) prop_max = 1.E+04;
-
-  lk_begin = Lk(loc_b,loc_tree); /*! We can't assume that the log-lk value is up-to-date */
-
-  Generic_Brent_Lk(&(b_fcus->l->v),
-                   MAX(tree->mod->l_min,MIN(tree->mod->l_max,b_fcus->l->v))*MAX(1.E-04,prop_min),
-                   MAX(tree->mod->l_min,MIN(tree->mod->l_max,b_fcus->l->v))*MIN(1.E+04,prop_max),
-                   tree->mod->s_opt->min_diff_lk_local,
-                   tree->mod->s_opt->brent_it_max,
-                   tree->mod->s_opt->quickdirty,
-                   Wrap_Lk_At_Given_Edge,
-                   loc_b,loc_tree,NULL,NO);
+  lk_begin  = UNLIKELY;
+  lk_end    = UNLIKELY;
+  
+  mixt_tree = tree;
+  while(mixt_tree->prev != NULL) mixt_tree = mixt_tree->prev; 
+  
+  mixt_b = b;
+  while(mixt_b->prev != NULL) mixt_b = mixt_b->prev; 
+  
+  if(b->l->onoff == OFF) return mixt_tree->c_lnL;
 
-  /* if(tree->mod->gamma_mgf_bl == YES) */
-  /*   { */
-  /*     if(b_fcus->num == 0) */
-  /*       { */
-  /*         Generic_Brent_Lk(&(b_fcus->l_var), */
-  /*                          1.E-4,100., */
-  /*                          tree->mod->s_opt->min_diff_lk_local, */
-  /*                          tree->mod->s_opt->brent_it_max, */
-  /*                          tree->mod->s_opt->quickdirty, */
-  /*                          Wrap_Lk_At_Given_Edge,loc_b,loc_tree,NULL); */
-  /*                          /\* Wrap_Lk,NULL,loc_tree,NULL); *\/ */
-  /*       } */
-  /*   } */
+  Set_Update_Eigen_Lr(YES,mixt_tree);
+  Set_Use_Eigen_Lr(NO,mixt_tree);
+  
+  lk_begin = Lk(mixt_b,mixt_tree); /* We can't assume that the log-lk value is up-to-date */
+  
+  Set_Update_Eigen_Lr(NO,mixt_tree);
+  Set_Use_Eigen_Lr(YES,mixt_tree);
+    
+  Br_Len_Newton_Raphson(&(b->l->v),mixt_b,tree->mod->s_opt->brent_it_max,tree->mod->s_opt->min_diff_lk_local,mixt_tree);
+  
+  Update_PMat_At_Given_Edge(mixt_b,mixt_tree);
+  
+  Set_Update_Eigen_Lr(NO,mixt_tree);
+  Set_Use_Eigen_Lr(NO,mixt_tree);
 
-  lk_end = loc_tree->c_lnL;
+  
+  /* lk_begin = Lk(mixt_b,mixt_tree); */
+  /* Generic_Brent_Lk(&(b->l->v), */
+  /*                  tree->mod->l_min, */
+  /*                  tree->mod->l_max, */
+  /*                  tree->mod->s_opt->min_diff_lk_local, */
+  /*                  tree->mod->s_opt->brent_it_max, */
+  /*                  tree->mod->s_opt->quickdirty, */
+  /*                  Wrap_Lk_At_Given_Edge, */
+  /*                  mixt_b,mixt_tree,NULL,NO); */
+  
 
+  lk_end = mixt_tree->c_lnL;
 
+  
   if(lk_end < lk_begin - tree->mod->s_opt->min_diff_lk_local)
     {
-      PhyML_Printf("\n== prop_min: %f prop_max: %f l: %f var:%f",prop_min,prop_max,b_fcus->l->v,b_fcus->l_var->v);
+      PhyML_Printf("\n== l: %f var:%f",b->l->v,b->l_var->v);
       PhyML_Printf("\n== lk_beg = %f lk_end = %f",lk_begin, lk_end);
       PhyML_Printf("\n== Err. in file %s at line %d",__FILE__,__LINE__);
       Exit("\n");
     }
 
-
-  return loc_tree->c_lnL;
+  return mixt_tree->c_lnL;
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-void Round_Optimize(t_tree *tree, calign *data, int n_round_max)
+void Round_Optimize(t_tree *tree, int n_round_max)
 {
   int n_round,each;
   phydbl lk_old, lk_new;
@@ -573,28 +676,20 @@ void Round_Optimize(t_tree *tree, calign *data, int n_round_max)
   n_round = 0;
   each = 0;
 
-  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);
-
+    {      
+      if(tree->mod->s_opt->opt_bl || tree->mod->s_opt->constrained_br_len) Optimize_Br_Len_Serie(tree);
+      
       if((tree->mod->s_opt->opt_bl || tree->mod->s_opt->constrained_br_len) &&
-         (tree->mod->s_opt->print) &&
-         (!tree->io->quiet)) Print_Lk(tree,"[Branch lengths     ]");
-
-      Set_Both_Sides(YES,tree);
-      Lk(NULL,tree);
+         (tree->verbose > VL2) &&
+         (tree->io->quiet == NO)) Print_Lk(tree,"[Branch lengths     ]");
 
+      /* printf("\n. [%d] %f ",n_round,tree->c_lnL); fflush(NULL); */
+      
       if(!each)
         {
-          each = 1;
-          Optimiz_All_Free_Param(tree,(tree->io->quiet)?(0):(tree->mod->s_opt->print));
-          Set_Both_Sides(YES,tree);
-          Lk(NULL,tree);
+          each = 3;
+          Optimiz_All_Free_Param(tree,(tree->io->quiet)?(0):(tree->verbose > VL2));
         }
 
       lk_new = tree->c_lnL;
@@ -603,19 +698,16 @@ void Round_Optimize(t_tree *tree, calign *data, int n_round_max)
           PhyML_Printf("\n== lk_new = %f lk_old = %f diff = %f",lk_new,lk_old,lk_new-lk_old);
           Exit("\n== Optimisation failed ! (Round_Optimize)\n");
         }
-      if(FABS(lk_new - lk_old) < tree->mod->s_opt->min_diff_lk_local) {
-//          DUMP_D(FABS(lk_new - lk_old));
-//          DUMP_I(n_round);
-          break;
-      }
-      else {
+      if(FABS(lk_new - lk_old) < tree->mod->s_opt->min_diff_lk_local) break;
+      else 
+        {
           lk_old  = lk_new;
-      }
+        }
       n_round++;
       each--;
     }
-
-  Optimiz_All_Free_Param(tree,(tree->io->quiet)?(0):(tree->mod->s_opt->print));
+  
+  /* Optimiz_All_Free_Param(tree,(tree->io->quiet)?(0):(tree->verbose > VL2)); */
 
 }
 
@@ -624,10 +716,15 @@ void Round_Optimize(t_tree *tree, calign *data, int n_round_max)
 
 void Optimize_Br_Len_Serie(t_tree *tree)
 {
+  phydbl lk_init,lk_end;
+  
+  Set_Both_Sides(NO,tree);
+  Lk(NULL,tree);
+  
+  lk_init = tree->c_lnL;
+
   if(tree->mod->gamma_mgf_bl == YES)
     {
-      phydbl lk_init = tree->c_lnL;
-
       Generic_Brent_Lk(&(tree->mod->l_var_sigma),
                        tree->mod->l_var_min,
                        tree->mod->l_var_max,
@@ -642,18 +739,19 @@ void Optimize_Br_Len_Serie(t_tree *tree)
           PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__);
         }
 
-      if((tree->io->quiet)?(0):(tree->mod->s_opt->print))
+      if((tree->io->quiet)?(0):(tree->verbose > VL2))
         {
           Print_Lk(tree,"[Branch len. var.   ]");
           PhyML_Printf("[%10f]",tree->mod->l_var_sigma);
         }
     }
 
+  
   if(tree->n_root && tree->ignore_root == NO)
     {
-      Update_P_Lk(tree,tree->n_root->b[1],tree->n_root);
+      Update_Partial_Lk(tree,tree->n_root->b[1],tree->n_root);
       Optimize_Br_Len_Serie_Post(tree->n_root,tree->n_root->v[1],tree->n_root->b[1],tree);
-      Update_P_Lk(tree,tree->n_root->b[2],tree->n_root);
+      Update_Partial_Lk(tree,tree->n_root->b[2],tree->n_root);
       Optimize_Br_Len_Serie_Post(tree->n_root,tree->n_root->v[2],tree->n_root->b[2],tree);
     }
   else if(tree->n_root && tree->ignore_root == YES)
@@ -670,6 +768,14 @@ void Optimize_Br_Len_Serie(t_tree *tree)
     {
       Optimize_Br_Len_Serie_Post(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree->a_nodes[0]->b[0],tree);
     }
+
+  lk_end = tree->c_lnL;
+
+  if(lk_end < lk_init - tree->mod->s_opt->min_diff_lk_local)
+    {
+      PhyML_Printf("\n== lk_init: %f lk_end: %f",lk_init,lk_end);
+      Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
+    }
 }
 
 /*////////////////////////////////////////////////////////////
@@ -680,8 +786,6 @@ void Optimize_Br_Len_Multiplier(t_tree *mixt_tree, int verbose)
   phydbl lk_init;
   t_tree *tree;
 
-
-
   tree = mixt_tree;
   
   do
@@ -726,11 +830,11 @@ void Optimize_Br_Len_Multiplier(t_tree *mixt_tree, int verbose)
 void Optimize_Br_Len_Serie_Post(t_node *a, t_node *d, t_edge *b_fcus, t_tree *tree)
 {
   int i;
-  phydbl l_infa,l_infb;
   phydbl lk_init;
 
+  
   lk_init = tree->c_lnL;
-
+  
   if(tree->mod->s_opt->constrained_br_len == YES)
     {
       Generic_Brent_Lk(&(tree->mod->br_len_mult->v),
@@ -749,67 +853,57 @@ void Optimize_Br_Len_Serie_Post(t_node *a, t_node *d, t_edge *b_fcus, t_tree *tr
       return;
     }
 
-  l_infa = tree->mod->l_max/b_fcus->l->v;
-  l_infb = tree->mod->l_min/b_fcus->l->v;
-
-  Set_Both_Sides(YES,tree);
-
-  if(tree->io->mod->s_opt->opt_bl == YES) Br_Len_Brent(l_infb,l_infa,b_fcus,tree);
+  if(tree->io->mod->s_opt->opt_bl == YES) Br_Len_Brent(b_fcus,tree);
 
   if(tree->c_lnL < lk_init - tree->mod->s_opt->min_diff_lk_local)
     {
-      PhyML_Printf("\n== %f %f %G",l_infa,l_infb,b_fcus->l->v);
       PhyML_Printf("\n== %f -- %f",lk_init,tree->c_lnL);
       PhyML_Printf("\n== Edge: %d",b_fcus->num);
       PhyML_Printf("\n== is_mixt_tree: %d",tree->is_mixt_tree);
-      PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__);
-      Warn_And_Exit("");
+      Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
     }
 
   if(d->tax) return;
 
-  if(tree->n_root)
+  if(tree->n_root && tree->ignore_root == NO)
     {
-      For(i,3)
+      for(i=0;i<3;++i)
         {
           if(d->v[i] != a && d->b[i] != tree->e_root)
             {
-              Update_P_Lk(tree,d->b[i],d);
+              Update_Partial_Lk(tree,d->b[i],d);
               Optimize_Br_Len_Serie_Post(d,d->v[i],d->b[i],tree);
             }
         }
       
-      For(i,3)
+      for(i=0;i<3;++i)
         if(d->v[i] == a || d->b[i] == tree->e_root) 
-          Update_P_Lk(tree,d->b[i],d);
+          Update_Partial_Lk(tree,d->b[i],d);
     }
   else
     {
-      For(i,3)
+      // Ok if root exists but require traversal to be initiated from a node != root
+      for(i=0;i<3;++i)
         {
           if(d->v[i] != a)
             {
-              Update_P_Lk(tree,d->b[i],d);
+              Update_Partial_Lk(tree,d->b[i],d);
               Optimize_Br_Len_Serie_Post(d,d->v[i],d->b[i],tree);
             }
         }
-      
-      For(i,3) 
-        if(d->v[i] == a) 
-          Update_P_Lk(tree,d->b[i],d);
+      Update_Partial_Lk(tree,b_fcus,d);
     }
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Optimiz_Ext_Br(t_tree *tree)
 {
   int i;
-  t_edge *b,*ori;
-  phydbl l_infa,l_infb;
-  phydbl lk_init,l_init;
+  t_edge *b;
+  phydbl lk_init;
+  scalar_dbl *l_init,*v_init;
 
   lk_init = tree->c_lnL;
 
@@ -817,30 +911,54 @@ void Optimiz_Ext_Br(t_tree *tree)
     {
       b = tree->a_edges[i];
       if((b->left->tax) || (b->rght->tax))
-    {
-
-      l_init = b->l->v;
+        {
+          
+          l_init = Duplicate_Scalar_Dbl(b->l);          
+          v_init = Duplicate_Scalar_Dbl(b->l_var);          
+          
+          Br_Len_Brent(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;
 }
@@ -888,11 +1006,11 @@ void Optimiz_All_Free_Param(t_tree *tree, int verbose)
     /* 					tree->mod->s_opt->quickdirty); */
 
           Generic_Brent_Lk(&(tree->mod->m4mod->delta),
-                   0.01,10.,
-                   tree->mod->s_opt->min_diff_lk_local,
-                   tree->mod->s_opt->brent_it_max,
-                   tree->mod->s_opt->quickdirty,
-                   Wrap_Lk,NULL,tree,NULL,NO);
+                           0.01,10.,
+                           tree->mod->s_opt->min_diff_lk_local,
+                           tree->mod->s_opt->brent_it_max,
+                           tree->mod->s_opt->quickdirty,
+                           Wrap_Lk,NULL,tree,NULL,NO);
 
           if(verbose)
             {
@@ -911,7 +1029,7 @@ void Optimiz_All_Free_Param(t_tree *tree, int verbose)
           
           Switch_Eigen(YES,tree->mod);
           
-          For(rcat,tree->mod->m4mod->n_h)
+          for(rcat=0;rcat<tree->mod->m4mod->n_h;rcat++)
             {
               /* 	      Optimize_Single_Param_Generic(tree,&(tree->mod->m4mod->multipl_unscaled[rcat]), */
               /* 					    .01,10., */
@@ -933,7 +1051,7 @@ void Optimiz_All_Free_Param(t_tree *tree, int verbose)
                 }
             }
           
-          For(rcat,tree->mod->m4mod->n_h)
+          for(rcat=0;rcat<tree->mod->m4mod->n_h;rcat++)
             {
               
               /*  	      Optimize_Single_Param_Generic(tree,&(tree->mod->m4mod->h_fq_unscaled[rcat]), */
@@ -997,23 +1115,21 @@ void Optimiz_All_Free_Param(t_tree *tree, int verbose)
       if(tree->mod->io->datatype == NT)
         {
           if(tree->mod->whichmodel == GTR || tree->mod->whichmodel == CUSTOM)
-            {
-              
+            {              
               Switch_Eigen(YES,tree->mod);
               
-              For(i,5) tree->mod->m4mod->o_rr[i] = LOG(tree->mod->m4mod->o_rr[i]);
+              for(i=0;i<5;i++) tree->mod->m4mod->o_rr[i] = log(tree->mod->m4mod->o_rr[i]);
               
               failed = YES;
               
-              /* BFGS(tree,tree->mod->m4mod->o_rr,5,1.e-5,tree->mod->s_opt->min_diff_lk_local,1.e-5,NO,YES, */
               BFGS(tree,tree->mod->m4mod->o_rr,5,1.e-5,tree->mod->s_opt->min_diff_lk_local,1.e-5,YES,NO,
                    &Return_Abs_Lk,
                    &Num_Derivative_Several_Param,
                    &Lnsrch,&failed);
               
-              For(i,5) tree->mod->m4mod->o_rr[i] = EXP(tree->mod->m4mod->o_rr[i]);
+              for(i=0;i<5;i++) tree->mod->m4mod->o_rr[i] = exp(tree->mod->m4mod->o_rr[i]);
               
-              For(i,5)
+              for(i=0;i<5;i++)
                 {
                   /* 	      Optimize_Single_Param_Generic(tree,&(tree->mod->m4mod->o_rr[i]), */
                   /* 					    1.E-20,1.E+10, */
@@ -1077,7 +1193,7 @@ void BFGS(t_tree *tree,
   phydbl *init,*sign;
 
   hessin = (phydbl **)mCalloc(n,sizeof(phydbl *));
-  For(i,n) hessin[i] = (phydbl *)mCalloc(n,sizeof(phydbl));
+  for(i=0;i<n;i++) hessin[i] = (phydbl *)mCalloc(n,sizeof(phydbl));
   dg   = (phydbl *)mCalloc(n,sizeof(phydbl ));
   g    = (phydbl *)mCalloc(n,sizeof(phydbl ));
   pnew = (phydbl *)mCalloc(n,sizeof(phydbl ));
@@ -1087,13 +1203,13 @@ void BFGS(t_tree *tree,
   sign = (phydbl *)mCalloc(n,sizeof(phydbl ));
 
 
-  For(i,n) init[i] = p[i];
+  for(i=0;i<n;i++) init[i] = p[i];
 
 
   /*! p is log transformed */
-  if(logt == YES) For(i,n) p[i] = EXP(MIN(1.E+2,p[i]));
+  if(logt == YES) for(i=0;i<n;i++) p[i] = exp(MIN(1.E+2,p[i]));
   fp=(*func)(tree);
-  if(logt == YES) For(i,n) p[i] = LOG(p[i]);
+  if(logt == YES) for(i=0;i<n;i++) p[i] = log(p[i]);
   
   /* PhyML_Printf("\n. ENTER BFGS WITH: %f\n",fp); */
   
@@ -1139,20 +1255,20 @@ void BFGS(t_tree *tree,
         {
           if(fp > fp_old)
             {
-              For(i,n) p[i] = init[i];
+              for(i=0;i<n;i++) p[i] = init[i];
               *failed = YES;
             }
           
-          if(logt == YES) For(i,n) p[i] = EXP(MIN(1.E+2,p[i]));
-          For(i,n) sign[i] = p[i] > .0 ? 1. : -1.;
-          if(is_positive == YES) For(i,n) p[i] = FABS(p[i]);
+          if(logt == YES) for(i=0;i<n;i++) p[i] = exp(MIN(1.E+2,p[i]));
+          for(i=0;i<n;i++) sign[i] = p[i] > .0 ? 1. : -1.;
+          if(is_positive == YES) for(i=0;i<n;i++) p[i] = FABS(p[i]);
           (*func)(tree);
-          if(is_positive == YES) For(i,n) p[i] *= sign[i];
-          if(logt == YES) For(i,n) p[i] = LOG(p[i]);
+          if(is_positive == YES) for(i=0;i<n;i++) p[i] *= sign[i];
+          if(logt == YES) for(i=0;i<n;i++) p[i] = log(p[i]);
           
-          if(is_positive == YES) For(i,n) p[i] = FABS(p[i]);
+          if(is_positive == YES) for(i=0;i<n;i++) p[i] = FABS(p[i]);
           
-          For(i,n) Free(hessin[i]);
+          for(i=0;i<n;i++) Free(hessin[i]);
           free(hessin);
           free(xi);
           free(pnew);
@@ -1178,16 +1294,16 @@ void BFGS(t_tree *tree,
       if (test < gtol)
         {
           *failed = NO;
-          if(logt == YES) For(i,n) p[i] = EXP(MIN(1.E+2,p[i]));
-          For(i,n) sign[i] = p[i] > .0 ? 1. : -1.;
-          if(is_positive == YES) For(i,n) p[i] = FABS(p[i]);
+          if(logt == YES) for(i=0;i<n;i++) p[i] = exp(MIN(1.E+2,p[i]));
+          for(i=0;i<n;i++) sign[i] = p[i] > .0 ? 1. : -1.;
+          if(is_positive == YES) for(i=0;i<n;i++) p[i] = FABS(p[i]);
           (*func)(tree);
-          if(is_positive == YES) For(i,n) p[i] *= sign[i];
-          if(logt == YES) For(i,n) p[i] = LOG(p[i]);
+          if(is_positive == YES) for(i=0;i<n;i++) p[i] *= sign[i];
+          if(logt == YES) for(i=0;i<n;i++) p[i] = log(p[i]);
           
-          if(is_positive == YES) For(i,n) p[i] = FABS(p[i]);
+          if(is_positive == YES) for(i=0;i<n;i++) p[i] = FABS(p[i]);
           
-          For(i,n) Free(hessin[i]);
+          for(i=0;i<n;i++) Free(hessin[i]);
           free(hessin);
           free(xi);
           free(pnew);
@@ -1238,7 +1354,7 @@ void BFGS(t_tree *tree,
     }
   /*   PhyML_Printf("\n. Too many iterations in BFGS...\n"); */
   *failed = YES;
-  For(i,n) Free(hessin[i]);
+  for(i=0;i<n;i++) Free(hessin[i]);
   free(hessin);
   free(xi);
   free(pnew);
@@ -1285,7 +1401,7 @@ void BFGS_Nonaligned(t_tree *tree,
   phydbl *init,*sign;
 
   hessin = (phydbl **)mCalloc(n,sizeof(phydbl *));
-  For(i,n) hessin[i] = (phydbl *)mCalloc(n,sizeof(phydbl));
+  for(i=0;i<n;i++) hessin[i] = (phydbl *)mCalloc(n,sizeof(phydbl));
   dg   = (phydbl *)mCalloc(n,sizeof(phydbl ));
   g    = (phydbl *)mCalloc(n,sizeof(phydbl ));
   pnew = (phydbl *)mCalloc(n,sizeof(phydbl ));
@@ -1294,11 +1410,11 @@ void BFGS_Nonaligned(t_tree *tree,
   init = (phydbl *)mCalloc(n,sizeof(phydbl ));
   sign = (phydbl *)mCalloc(n,sizeof(phydbl ));
 
-  For(i,n) init[i] = (*(p[i]));
+  for(i=0;i<n;i++) init[i] = (*(p[i]));
 
-  if(logt == YES) For(i,n) (*(p[i])) = EXP(MIN(1.E+2,*(p[i])));
+  if(logt == YES) for(i=0;i<n;i++) (*(p[i])) = exp(MIN(1.E+2,*(p[i])));
   fp=(*func)(tree);
-  if(logt == YES) For(i,n) (*(p[i])) = LOG(*(p[i]));
+  if(logt == YES) for(i=0;i<n;i++) (*(p[i])) = log(*(p[i]));
 
   fp_old = fp;
 
@@ -1334,117 +1450,117 @@ void BFGS_Nonaligned(t_tree *tree,
 
       test=0.0;
       for (i=0;i<n;i++)
-    {
-      temp=xi[i]/MAX(*(p[i]),1.0);
-      /* printf("\n. x[i]=%G p[i]=%f",xi[i],*(p[i])); */
-      if (temp > test) test=temp;
-    }
-
-      if (test < TOLX || (FABS(fp_old-fp) < difff && its > 1))
-    {
-
-      if(fp > fp_old)
         {
-              For(i,n) (*(p[i])) = init[i];
-          *failed = 1;
+          temp=xi[i]/MAX(*(p[i]),1.0);
+          /* printf("\n. x[i]=%G p[i]=%f",xi[i],*(p[i])); */
+          if (temp > test) test=temp;
         }
 
-          if(logt == YES) For(i,n) (*(p[i])) = EXP(MIN(1.E+2,*(p[i])));
-          For(i,n) sign[i] = *(p[i]) > .0 ? 1. : -1.;
-          if(is_positive == YES) For(i,n) *(p[i]) = FABS(*(p[i]));
-      (*func)(tree);
-          if(is_positive == YES) For(i,n) *(p[i]) *= sign[i];
-          if(logt == YES) For(i,n) (*(p[i])) = LOG(*(p[i]));
-
-          if(is_positive == YES) For(i,n) *(p[i]) = FABS(*(p[i]));
-
-      For(i,n) Free(hessin[i]);
-      free(hessin);
-      free(xi);
-      free(pnew);
-      free(hdg);
-      free(g);
-      free(dg);
+      if (test < TOLX || (FABS(fp_old-fp) < difff && its > 1))
+        {
+          
+          if(fp > fp_old)
+            {
+              for(i=0;i<n;i++) (*(p[i])) = init[i];
+              *failed = 1;
+            }
+          
+          if(logt == YES) for(i=0;i<n;i++) (*(p[i])) = exp(MIN(1.E+2,*(p[i])));
+          for(i=0;i<n;i++) sign[i] = *(p[i]) > .0 ? 1. : -1.;
+          if(is_positive == YES) for(i=0;i<n;i++) *(p[i]) = FABS(*(p[i]));
+          (*func)(tree);
+          if(is_positive == YES) for(i=0;i<n;i++) *(p[i]) *= sign[i];
+          if(logt == YES) for(i=0;i<n;i++) (*(p[i])) = log(*(p[i]));
+          
+          if(is_positive == YES) for(i=0;i<n;i++) *(p[i]) = FABS(*(p[i]));
+          
+          for(i=0;i<n;i++) Free(hessin[i]);
+          free(hessin);
+          free(xi);
+          free(pnew);
+          free(hdg);
+          free(g);
+          free(dg);
           free(init);
           free(sign);
-      return;
-    }
-
+          return;
+        }
+      
       for (i=0;i<n;i++) dg[i]=g[i];
-
+      
       (*dfunc_nonaligned)(tree,p,n,step_size,logt,func,g,is_positive);
-
+      
       test=0.0;
       den=MAX(fret,1.0);
       for (i=0;i<n;i++)
-    {
-      temp=g[i]*MAX(*(p[i]),1.0)/den;
-      if (temp > test) test=temp;
-    }
-
+        {
+          temp=g[i]*MAX(*(p[i]),1.0)/den;
+          if (temp > test) test=temp;
+        }
+      
       if (test < gtol)
-    {
-          if(logt == YES) For(i,n) (*(p[i])) = EXP(MIN(1.E+2,*(p[i])));
-          For(i,n) sign[i] = *(p[i]) > .0 ? 1. : -1.;
-          if(is_positive == YES) For(i,n) *(p[i]) = FABS(*(p[i]));
-      (*func)(tree);
-          if(is_positive == YES) For(i,n) *(p[i]) *= sign[i];
-          if(logt == YES) For(i,n) (*(p[i])) = LOG(*(p[i]));
-
-          if(is_positive == YES) For(i,n) *(p[i]) = FABS(*(p[i]));
-
-      For(i,n) Free(hessin[i]);
-      free(hessin);
-      free(xi);
-      free(pnew);
-      free(hdg);
-      free(g);
-      free(dg);
+        {
+          if(logt == YES) for(i=0;i<n;i++) (*(p[i])) = exp(MIN(1.E+2,*(p[i])));
+          for(i=0;i<n;i++) sign[i] = *(p[i]) > .0 ? 1. : -1.;
+          if(is_positive == YES) for(i=0;i<n;i++) *(p[i]) = FABS(*(p[i]));
+          (*func)(tree);
+          if(is_positive == YES) for(i=0;i<n;i++) *(p[i]) *= sign[i];
+          if(logt == YES) for(i=0;i<n;i++) (*(p[i])) = log(*(p[i]));
+          
+          if(is_positive == YES) for(i=0;i<n;i++) *(p[i]) = FABS(*(p[i]));
+          
+          for(i=0;i<n;i++) Free(hessin[i]);
+          free(hessin);
+          free(xi);
+          free(pnew);
+          free(hdg);
+          free(g);
+          free(dg);
           free(init);
           free(sign);
-      return;
-    }
-
-    for (i=0;i<n;i++) dg[i]=g[i]-dg[i];
-
-    for (i=0;i<n;i++)
-      {
-    hdg[i]=0.0;
-    for (j=0;j<n;j++) hdg[i] += hessin[i][j]*dg[j];
-      }
-
-    fac=fae=sumdg=sumxi=0.0;
-    for (i=0;i<n;i++)
-      {
-    fac += dg[i]*xi[i];
-    fae += dg[i]*hdg[i];
-    sumdg += SQR(dg[i]);
-    sumxi += SQR(xi[i]);
-      }
-
-    if(fac*fac > EPS*sumdg*sumxi)
-      {
-    fac=1.0/fac;
-    fad=1.0/fae;
-    for (i=0;i<n;i++) dg[i]=fac*xi[i]-fad*hdg[i];
-    for (i=0;i<n;i++)
-      {
-        for (j=0;j<n;j++)
-          {
-        hessin[i][j] += fac*xi[i]*xi[j]
-          -fad*hdg[i]*hdg[j]+fae*dg[i]*dg[j];
-          }
-      }
-      }
-    for (i=0;i<n;i++)
-      {
-    xi[i]=0.0;
-    for (j=0;j<n;j++) xi[i] -= hessin[i][j]*g[j];
-      }
+          return;
+        }
+      
+      for (i=0;i<n;i++) dg[i]=g[i]-dg[i];
+      
+      for (i=0;i<n;i++)
+        {
+          hdg[i]=0.0;
+          for (j=0;j<n;j++) hdg[i] += hessin[i][j]*dg[j];
+        }
+      
+      fac=fae=sumdg=sumxi=0.0;
+      for (i=0;i<n;i++)
+        {
+          fac += dg[i]*xi[i];
+          fae += dg[i]*hdg[i];
+          sumdg += SQR(dg[i]);
+          sumxi += SQR(xi[i]);
+        }
+      
+      if(fac*fac > EPS*sumdg*sumxi)
+        {
+          fac=1.0/fac;
+          fad=1.0/fae;
+          for (i=0;i<n;i++) dg[i]=fac*xi[i]-fad*hdg[i];
+          for (i=0;i<n;i++)
+            {
+              for (j=0;j<n;j++)
+                {
+                  hessin[i][j] += fac*xi[i]*xi[j]
+                    -fad*hdg[i]*hdg[j]+fae*dg[i]*dg[j];
+                }
+            }
+        }
+      for (i=0;i<n;i++)
+        {
+          xi[i]=0.0;
+          for (j=0;j<n;j++) xi[i] -= hessin[i][j]*g[j];
+        }
     }
   PhyML_Printf("\n. Too many iterations in BFGS...\n");
   *failed = YES;
-  For(i,n) Free(hessin[i]);
+  for(i=0;i<n;i++) Free(hessin[i]);
   free(hessin);
   free(xi);
   free(pnew);
@@ -1478,16 +1594,16 @@ int Lnsrch(t_tree *tree, int n, phydbl *xold, phydbl fold,
   local_xold = (phydbl *)mCalloc(n,sizeof(phydbl));
   sign       = (phydbl *)mCalloc(n,sizeof(phydbl));
 
-  For(i,n) local_xold[i] = xold[i];
+  for(i=0;i<n;i++) local_xold[i] = xold[i];
   
   *check=0;
   for(sum=0.0,i=0;i<n;i++) sum += p[i]*p[i];
   sum=SQRT(sum);
   /* PhyML_Printf("\n. lnsrch sum: %f",sum); */
-  if(sum > stpmax) For(i,n) p[i] *= stpmax/sum;
-  /* For(i,n) PhyML_Printf("\n. lnsrch p[i]: %f",p[i]); */
+  if(sum > stpmax) for(i=0;i<n;i++) p[i] *= stpmax/sum;
+  /* for(i=0;i<n;i++) PhyML_Printf("\n. lnsrch p[i]: %f",p[i]); */
   slope=0.0;
-  For(i,n) slope += g[i]*p[i];
+  for(i=0;i<n;i++) slope += g[i]*p[i];
   /* PhyML_Printf("\n. lnsrch slope: %f",slope); */
   test=0.0;
   for(i=0;i<n;i++)
@@ -1499,7 +1615,7 @@ int Lnsrch(t_tree *tree, int n, phydbl *xold, phydbl fold,
   alam=1.0;
   for (;;)
     {
-      For(i,n)
+      for(i=0;i<n;i++)
         {
           x[i]=local_xold[i]+alam*p[i];
           xold[i] = x[i];
@@ -1510,28 +1626,28 @@ int Lnsrch(t_tree *tree, int n, phydbl *xold, phydbl fold,
       
       if(i==n)
         {
-          if(logt == YES) For(i,n) xold[i] = EXP(MIN(1.E+2,xold[i]));
-          For(i,n) sign[i] = xold[i] < .0 ? -1. : 1.;
-          if(is_positive == YES) For(i,n) xold[i] = FABS(xold[i]);
-          /* For(i,n) PhyML_Printf("\n. <<>> %f",xold[i]); */
+          if(logt == YES) for(i=0;i<n;i++) xold[i] = exp(MIN(1.E+2,xold[i]));
+          for(i=0;i<n;i++) sign[i] = xold[i] < .0 ? -1. : 1.;
+          if(is_positive == YES) for(i=0;i<n;i++) xold[i] = FABS(xold[i]);
+          /* for(i=0;i<n;i++) PhyML_Printf("\n. <<>> %f",xold[i]); */
           *f=Return_Abs_Lk(tree);
-          if(is_positive == YES) For(i,n) xold[i] *= sign[i];
-          if(logt == YES) For(i,n) xold[i] = LOG(xold[i]);
+          if(is_positive == YES) for(i=0;i<n;i++) xold[i] *= sign[i];
+          if(logt == YES) for(i=0;i<n;i++) xold[i] = log(xold[i]);
         }
       else *f=1.+fold+ALF*alam*slope;
       if (alam < alamin)
         {
           *check=1;
-          For(i,n) xold[i] = local_xold[i];
-          if(is_positive == YES) For(i,n) xold[i] = FABS(xold[i]);
+          for(i=0;i<n;i++) xold[i] = local_xold[i];
+          if(is_positive == YES) for(i=0;i<n;i++) xold[i] = FABS(xold[i]);
           Free(local_xold);
           Free(sign);
           return 0;
         }
       else if (*f <= fold+ALF*alam*slope)
         {
-          For(i,n) xold[i] = local_xold[i];
-          if(is_positive == YES) For(i,n) xold[i] = FABS(xold[i]);
+          for(i=0;i<n;i++) xold[i] = local_xold[i];
+          if(is_positive == YES) for(i=0;i<n;i++) xold[i] = FABS(xold[i]);
           Free(local_xold);
           Free(sign);
           return 0;
@@ -1592,7 +1708,7 @@ int Lnsrch_Nonaligned(t_tree *tree, int n, phydbl **xold, phydbl fold,
   local_xold = (phydbl *)mCalloc(n,sizeof(phydbl));
   sign       = (phydbl *)mCalloc(n,sizeof(phydbl));
 
-  For(i,n) local_xold[i] = *(xold[i]);
+  for(i=0;i<n;i++) local_xold[i] = *(xold[i]);
 
   *check=0;
   for(sum=0.0,i=0;i<n;i++) sum += p[i]*p[i];
@@ -1619,28 +1735,28 @@ int Lnsrch_Nonaligned(t_tree *tree, int n, phydbl **xold, phydbl fold,
 
       if(i==n)
     {
-          if(logt == YES) For(i,n) *(xold[i]) = EXP(MIN(1.E+2,*(xold[i])));
-          For(i,n) sign[i]    = *(xold[i]) < .0 ? -1. : 1.;
-          if(is_positive == YES) For(i,n) *(xold[i]) = FABS(*(xold[i]));
+          if(logt == YES) for(i=0;i<n;i++) *(xold[i]) = exp(MIN(1.E+2,*(xold[i])));
+          for(i=0;i<n;i++) sign[i]    = *(xold[i]) < .0 ? -1. : 1.;
+          if(is_positive == YES) for(i=0;i<n;i++) *(xold[i]) = FABS(*(xold[i]));
       *f=Return_Abs_Lk(tree);
-          if(is_positive == YES) For(i,n) *(xold[i]) *= sign[i];
-          if(logt == YES) For(i,n) *(xold[i]) = LOG(*(xold[i]));
+          if(is_positive == YES) for(i=0;i<n;i++) *(xold[i]) *= sign[i];
+          if(logt == YES) for(i=0;i<n;i++) *(xold[i]) = log(*(xold[i]));
     }
       else *f=1.+fold+ALF*alam*slope;
 
       if (alam < alamin)
     {
       *check=1;
-      For(i,n) *(xold[i]) = local_xold[i];
-          if(is_positive == YES) For(i,n) *(xold[i]) = FABS(*(xold[i]));
+      for(i=0;i<n;i++) *(xold[i]) = local_xold[i];
+          if(is_positive == YES) for(i=0;i<n;i++) *(xold[i]) = FABS(*(xold[i]));
       Free(local_xold);
           Free(sign);
       return 0;
     }
       else if (*f <= fold+ALF*alam*slope)
     {
-      For(i,n) *(xold[i]) = local_xold[i];
-          if(is_positive) For(i,n) *(xold[i]) = FABS(*(xold[i]));
+      for(i=0;i<n;i++) *(xold[i]) = local_xold[i];
+          if(is_positive) for(i=0;i<n;i++) *(xold[i]) = FABS(*(xold[i]));
       Free(local_xold);
           Free(sign);
       return 0;
@@ -1760,7 +1876,6 @@ int Dist_F_Brak(phydbl *ax, phydbl *bx, phydbl *cx, phydbl *F, phydbl *param, t_
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 phydbl Dist_F_Brent(phydbl ax, phydbl bx, phydbl cx, phydbl tol, int n_iter_max,
             phydbl *param, phydbl *F, t_mod *mod)
 {
@@ -1768,7 +1883,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 +1891,95 @@ 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;
+  
+  /* printf("\n. bx=%f f: %f %f %f %f fx: %f",bx,mod->e_frq->pi->v[0],mod->e_frq->pi->v[1],mod->e_frq->pi->v[2],mod->e_frq->pi->v[3],fx); */
+  assert(isnan(fx) == FALSE);
+  assert(isinf(fx) == FALSE);
 
   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;
-    }
-
-      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))
+         ((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)
+         )
         {
-          d=BRENT_CGOLD*(e=(x >= xm ? a-x : b-x));
-          /*                   PhyML_Printf("Golden section step\n"); */
+          *param = x;
+          curr_lnL = Lk_Dist(F,*param,mod);
+          return -curr_lnL;
         }
-      else
+      
+      if(FABS(e) > tol1)
         {
-          d=p/q;
-          u=x+d;
-          if (u-a < tol2 || b-u < tol2)
-        d=SIGN(tol1,xm-x);
-          /*                   PhyML_Printf("Parabolic 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=BRENT_CGOLD*(e=(x >= xm ? a-x : b-x));
-      /*               PhyML_Printf("Golden section step (default)\n"); */
-    }
-
+        {
+          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,9 +2206,9 @@ 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;
+          for(i=0;i<n_alpha;i++) if(tree->mod->ras->alpha == alpha[i]) break;
 
           if(i == n_alpha)
             {
@@ -2103,13 +2223,13 @@ int Optimiz_Alpha_And_Pinv(t_tree *mixt_tree, int verbose)
                   if(tree->mod->ras->n_catg > 1)
                     {
                       Generic_Brent_Lk(&(tree->mod->ras->alpha->v),
-                                       tree->mod->ras->alpha->v/2.,100.,
+                                       ALPHA_MIN,ALPHA_MAX,
                                        tree->mod->s_opt->min_diff_lk_local,
                                        tree->mod->s_opt->brent_it_max,
                                        tree->mod->s_opt->quickdirty,
                                        Wrap_Lk,NULL,mixt_tree,NULL,NO);
                     }
-                  if(verbose)
+                  if(verbose == YES)
                     {
                       Print_Lk(mixt_tree,"[Alpha              ]");
                       PhyML_Printf("[%10f]",tree->mod->ras->alpha->v);
@@ -2128,8 +2248,11 @@ int Optimiz_Alpha_And_Pinv(t_tree *mixt_tree, int verbose)
 
                   tree->mod->s_opt->skip_tree_traversal = NO;
 
-                  Print_Lk(mixt_tree,"[P-inv              ]");
-                  PhyML_Printf("[%10f]",tree->mod->ras->pinvar->v);
+                  if(verbose == YES)
+                    {
+                      Print_Lk(mixt_tree,"[P-inv              ]");
+                      PhyML_Printf("[%10f]",tree->mod->ras->pinvar->v);
+                    }
                 }
             }
         }
@@ -2140,350 +2263,108 @@ int Optimiz_Alpha_And_Pinv(t_tree *mixt_tree, int verbose)
   if(alpha) Free(alpha);
 
   return 1;
+}
 
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
 
-  /* t_tree *tree; */
-  /* int    iter; */
-  /* phydbl best_alpha, best_pinv, best_mult; */
-  /* phydbl slope, intercept; */
-  /* phydbl lk_b, lk_a; */
-  /* phydbl f0,f1,f2,x0,x1,x2,x3; */
-  /* phydbl pinv0, pinv1; */
-  /* phydbl a, b, c; */
-  /* phydbl fa, fb, fc; */
-  /* phydbl K; */
-  /* phydbl alpha0, alpha1; */
-  /* phydbl best_lnL; */
-  /* scalar_dbl **alpha; */
-  /* int n_alpha; */
-  /* int i; */
+static phydbl Br_Len_Newton_Raphson(phydbl *l, t_edge *b, int n_iter_max, phydbl tol, t_tree *tree)
+{
+  short int converged;
+  phydbl dl,d2l,ratio; 
+  phydbl init_lnL,old_lnL;
+  int iter;
+  phydbl best_l, best_lnL;
 
-  /* Switch_Eigen(NO,mixt_tree->mod); */
 
-  /* alpha    = NULL; */
-  /* n_alpha  = 0; */
-  /* tree     = mixt_tree; */
+  // Warning: make sure eigen_lr vectors are already up-to-date 
 
-  /* do */
-  /*   { */
-  /*     For(i,n_alpha) if(tree->mod->ras->alpha == alpha[i]) break; */
+  Set_Use_Eigen_Lr(YES,tree);
+  assert(isnan(*l) == FALSE);
+  dLk(l,b,tree);
 
-  /*     if(i == n_alpha) */
-  /*       { */
-  /*         if(!alpha) alpha = (scalar_dbl **)mCalloc(1,sizeof(scalar_dbl *)); */
-  /*         else       alpha = (scalar_dbl **)mRealloc(alpha,n_alpha+1,sizeof(scalar_dbl *)); */
-          
-  /*         alpha[n_alpha] = tree->mod->ras->alpha; */
-  /*         n_alpha++; */
+  /* Lk(b,tree); */
 
-  /*         if((tree->mod->s_opt->opt_pinvar) && (tree->mod->s_opt->opt_alpha) && (tree->mod->ras->n_catg > 1)) */
-  /*           {               */
-  /*             lk_b     = UNLIKELY; */
-  /*             lk_a     = UNLIKELY; */
-              
-  /*             /\* PhyML_Printf("\n\n. %p Init lnL = %f alpha=%f pinv=%f", *\/ */
-  /*             /\*              tree, *\/ */
-  /*             /\*              mixt_tree->c_lnL, *\/ */
-  /*             /\*              tree->mod->ras->alpha, *\/ */
-  /*             /\*              tree->mod->ras->pinvar->v); *\/ */
-              
-  /*             /\* Two (full) steps to compute  pinv_alpha_slope & pinv_alpha_intercept *\/ */
-              
-  /*             Set_Both_Sides(YES,mixt_tree); */
-  /*             Lk(NULL,mixt_tree); */
-  /*             lk_b = mixt_tree->c_lnL; */
-              
-  /*             Optimize_Br_Len_Serie(mixt_tree); */
-              
-  /*             Set_Both_Sides(NO,mixt_tree); */
-              
-  /*             Optimize_Single_Param_Generic(mixt_tree,&(tree->mod->ras->alpha->v),0.01,100., */
-  /*                                           mixt_tree->mod->s_opt->min_diff_lk_local, */
-  /*                                           mixt_tree->mod->s_opt->brent_it_max, */
-  /*                                           mixt_tree->mod->s_opt->quickdirty); */
-              
-  /*             Optimize_Single_Param_Generic(mixt_tree,&(tree->mod->ras->pinvar->v),.0001,0.9999, */
-  /*                                           tree->mod->s_opt->min_diff_lk_local, */
-  /*                                           tree->mod->s_opt->brent_it_max, */
-  /*                                           tree->mod->s_opt->quickdirty); */
-              
-  /*             pinv0  = tree->mod->ras->pinvar->v; */
-  /*             alpha0 = tree->mod->ras->alpha->v; */
-  /*             f0 = mixt_tree->c_lnL; */
-              
-  /*             Set_Both_Sides(YES,mixt_tree); */
-  /*             Lk(NULL,mixt_tree); */
-              
-  /*             Optimize_Br_Len_Serie(mixt_tree); */
-              
-  /*             Set_Both_Sides(NO,mixt_tree); */
-  /*             Optimize_Single_Param_Generic(mixt_tree,&(tree->mod->ras->alpha->v),0.01,100., */
-  /*                                           tree->mod->s_opt->min_diff_lk_local, */
-  /*                                           tree->mod->s_opt->brent_it_max, */
-  /*                                           tree->mod->s_opt->quickdirty); */
-              
-  /*             Optimize_Single_Param_Generic(mixt_tree,&(tree->mod->ras->pinvar->v),.0001,0.9999, */
-  /*                                           tree->mod->s_opt->min_diff_lk_local, */
-  /*                                           tree->mod->s_opt->brent_it_max, */
-  /*                                           tree->mod->s_opt->quickdirty); */
-              
-  /*             lk_a = mixt_tree->c_lnL; */
-              
-  /*             pinv1  = tree->mod->ras->pinvar->v; */
-  /*             alpha1 = tree->mod->ras->alpha->v; */
-  /*             f1 = mixt_tree->c_lnL; */
-  /*             best_lnL = f1; */
-              
-  /*             if(lk_a < lk_b - mixt_tree->mod->s_opt->min_diff_lk_local) */
-  /*               { */
-  /*                 PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); */
-  /*                 Exit("\n"); */
-  /*               } */
-  /*             else if(FABS(lk_a - lk_b) < mixt_tree->mod->s_opt->min_diff_lk_local) */
-  /*               { */
-  /*                 if(alpha) Free(alpha); */
-  /*                 return 1; */
-  /*               } */
-              
-  /*             Record_Br_Len(mixt_tree); */
-  /*             best_alpha = tree->mod->ras->alpha->v; */
-  /*             best_pinv  = tree->mod->ras->pinvar->v; */
-  /*             best_mult  = tree->mod->br_len_mult->v; */
-              
-  /*             /\* PhyML_Printf("\n\n. Init lnL after std opt = %f [%f] best_alpha=%f best_pinv=%f",mixt_tree->c_lnL,Lk(NULL,mixt_tree),best_alpha,best_pinv); *\/ */
-  /*             /\* PhyML_Printf("\n. Best_lnL = %f %d",best_lnL,tree->mod->ras->invar); *\/ */
-              
-  /*             slope     = (pinv1 - pinv0)/(alpha1 - alpha0); */
-  /*             intercept = pinv1 - slope * alpha1; */
-              
-              
-  /*             /\* printf("\n. slope = %f pinv1=%f pinv0=%f alpha1=%f alpha0=%f", *\/ */
-  /*             /\*        slope,pinv1,pinv0,alpha1,alpha0); *\/ */
-              
-              
-  /*             if((slope > 0.001) && (slope < 1./0.001)) */
-  /*               { */
-  /*                 /\* PhyML_Printf("\n. pinv0 = %f, pinv1 = %f, alpha0 = %f, alpha1 = %f",pinv0,pinv1,alpha0,alpha1); *\/ */
-  /*                 /\* PhyML_Printf("\n. slope = %f intercept = %f",slope,intercept); *\/ */
-                  
-  /*                 K = 0.381966; */
-                  
-  /*                 if(alpha1 < alpha0) */
-  /*                   { */
-  /*                     c  = alpha0; */
-  /*                     b  = alpha1; */
-  /*                     fc = f0; */
-  /*                     fb = f1; */
-                      
-  /*                     a = (0.1 < alpha1)?(0.1):(0.5*alpha1); */
-  /*                     tree->mod->ras->alpha->v = a; */
-  /*                     tree->mod->ras->pinvar->v = slope * tree->mod->ras->alpha->v + intercept; */
-  /*                     if(tree->mod->ras->pinvar->v > 1.0) tree->mod->ras->pinvar->v = 0.9; */
-  /*                     if(tree->mod->ras->pinvar->v < 0.0) tree->mod->ras->pinvar->v = 0.001; */
-  /*                     Set_Both_Sides(YES,mixt_tree); */
-  /*                     Lk(NULL,mixt_tree); */
-                      
-  /*                     Optimize_Br_Len_Serie(mixt_tree); */
-                      
-  /*                     fa = mixt_tree->c_lnL; */
-                      
-  /*                     iter = 0; */
-                      
-  /*                     /\* PhyML_Printf("\n. a=%f, b=%f, c=%f, fa=%f, fb=%f, fc=%f (alpha=%f pinv=%f)",a,b,c,fa,fb,fc,tree->mod->ras->alpha->v,tree->mod->ras->pinvar->v); *\/ */
-                      
-  /*                     while(fa > fb) */
-  /*                       { */
-  /*                         a = a/5.; */
-  /*                         tree->mod->ras->alpha->v = a; */
-  /*                         tree->mod->ras->pinvar->v = slope * tree->mod->ras->alpha->v + intercept; */
-  /*                         if(tree->mod->ras->pinvar->v > 1.0) tree->mod->ras->pinvar->v = 0.9; */
-  /*                         if(tree->mod->ras->pinvar->v < 0.0) tree->mod->ras->pinvar->v = 0.001; */
-  /*                         Set_Both_Sides(YES,mixt_tree); */
-  /*                         Lk(NULL,mixt_tree); */
-  /*                         Optimize_Br_Len_Serie(mixt_tree); */
-  /*                         fa = mixt_tree->c_lnL; */
-  /*                         /\* PhyML_Printf("\n1 a=%f, b=%f, c=%f, fa=%f, fb=%f, fc=%f",a,b,c,fa,fb,fc); *\/ */
-  /*                         if(iter++ > 10) */
-  /*                           { */
-  /*                             if(alpha) Free(alpha); */
-  /*                             return 0; */
-  /*                           } */
-  /*                       } */
-  /*                   } */
-  /*                 else */
-  /*                   { */
-  /*                     a  = alpha0; */
-  /*                     b  = alpha1; */
-  /*                     fa = f0; */
-  /*                     fb = f1; */
-                      
-  /*                     c = (alpha1 < 2.)?(2.0):(2.*alpha1); */
-  /*                     tree->mod->ras->alpha->v = c; */
-  /*                     tree->mod->ras->pinvar->v = slope * tree->mod->ras->alpha->v + intercept; */
-  /*                     if(tree->mod->ras->pinvar->v > 1.0) tree->mod->ras->pinvar->v = 0.9; */
-  /*                     if(tree->mod->ras->pinvar->v < 0.0) tree->mod->ras->pinvar->v = 0.001; */
-  /*                     Set_Both_Sides(YES,mixt_tree); */
-  /*                     Lk(NULL,mixt_tree); */
-  /*                     Optimize_Br_Len_Serie(mixt_tree); */
-  /*                     fc = mixt_tree->c_lnL; */
-                      
-  /*                     /\* PhyML_Printf("\n. a=%f, b=%f, c=%f, fa=%f, fb=%f, fc=%f (alpha=%f pinv=%f)",a,b,c,fa,fb,fc,tree->mod->ras->alpha->v,tree->mod->ras->pinvar->v); *\/ */
-                      
-  /*                     iter = 0; */
-  /*                     while(fc > fb) */
-  /*                       { */
-  /*                         c = c*2.; */
-  /*                         tree->mod->ras->alpha->v = c; */
-  /*                         tree->mod->ras->pinvar->v = slope * tree->mod->ras->alpha->v + intercept; */
-  /*                         if(tree->mod->ras->pinvar->v > 1.0) tree->mod->ras->pinvar->v = 0.9; */
-  /*                         if(tree->mod->ras->pinvar->v < 0.0) tree->mod->ras->pinvar->v = 0.001; */
-  /*                         Set_Both_Sides(YES,mixt_tree); */
-  /*                         Lk(NULL,mixt_tree); */
-  /*                         Optimize_Br_Len_Serie(mixt_tree); */
-  /*                         fc = mixt_tree->c_lnL; */
-  /*                         /\* PhyML_Printf("\n2 a=%f, b=%f, c=%f, fa=%f, fb=%f, fc=%f",a,b,c,fa,fb,fc); *\/ */
-  /*                         if(iter++ > 10) */
-  /*                           { */
-  /*                             if(alpha) Free(alpha); */
-  /*                             return 0; */
-  /*                           } */
-  /*                       } */
-  /*                   } */
-                  
-                  
-  /*                 if(FABS(b - c) > FABS(a - b)) */
-  /*                   { */
-  /*                     x0 = a; x1 = b; x3 = c; */
-  /*                     x2 = b + K * FABS(b - c); */
-                      
-  /*                     f0 = fa; */
-  /*                     f1 = fb; */
-  /*                     tree->mod->ras->alpha->v = x2; */
-  /*                     tree->mod->ras->pinvar->v = slope * tree->mod->ras->alpha->v + intercept; */
-  /*                     if(tree->mod->ras->pinvar->v > 1.0) tree->mod->ras->pinvar->v = 0.9; */
-  /*                     if(tree->mod->ras->pinvar->v < 0.0) tree->mod->ras->pinvar->v = 0.001; */
-  /*                     Set_Both_Sides(YES,mixt_tree); */
-  /*                     Lk(NULL,mixt_tree); */
-  /*                     Optimize_Br_Len_Serie(mixt_tree); */
-  /*                     f2 = mixt_tree->c_lnL; */
-  /*                   } */
-  /*                 else /\* |b -c| < |a - b| *\/ */
-  /*                   { */
-  /*                     x0 = a; x2 = b; x3 = c; */
-  /*                     x1 = b - K * FABS(b - a); */
-                      
-  /*                     f0 = fa; */
-  /*                     f2 = fb; */
-  /*                     tree->mod->ras->alpha->v = x1; */
-  /*                     tree->mod->ras->pinvar->v = slope * tree->mod->ras->alpha->v + intercept; */
-  /*                     if(tree->mod->ras->pinvar->v > 1.0) tree->mod->ras->pinvar->v = 0.9; */
-  /*                     if(tree->mod->ras->pinvar->v < 0.0) tree->mod->ras->pinvar->v = 0.001; */
-  /*                     Set_Both_Sides(YES,mixt_tree); */
-  /*                     Lk(NULL,mixt_tree); */
-  /*                     Optimize_Br_Len_Serie(mixt_tree); */
-  /*                     f1 = mixt_tree->c_lnL; */
-  /*                   } */
-                  
-  /*                 iter = 0; */
-  /*                 do */
-  /*                   { */
-  /*                     /\* PhyML_Printf("\n. x0=%f, x1=%f, x2=%f, x3=%f, f0=%f, f1=%f, f2=%f, f3=%f", *\/ */
-  /*                     /\* 	 x0,x1,x2,x3,f0,f1,f2,f3); *\/ */
-                      
-  /*                     if(f1 > f2) */
-  /*                       { */
-  /*                         x3 = x2; */
-  /*                         x2 = x1; */
-  /*                         x1 = x2 - K * FABS(x2 - x0); */
-                          
-  /*                         f2 = f1; */
-                          
-  /*                         tree->mod->ras->alpha->v = x1; */
-  /*                         tree->mod->ras->pinvar->v = slope * tree->mod->ras->alpha->v + intercept; */
-  /*                         if(tree->mod->ras->pinvar->v > 1.0) tree->mod->ras->pinvar->v = 0.9; */
-  /*                         if(tree->mod->ras->pinvar->v < 0.0) tree->mod->ras->pinvar->v = 0.001; */
-  /*                         Set_Both_Sides(YES,mixt_tree); */
-  /*                         Lk(NULL,mixt_tree); */
-  /*                         Optimize_Br_Len_Serie(mixt_tree); */
-  /*                         f1 = mixt_tree->c_lnL; */
-  /*                         if(f1 > best_lnL) */
-  /*                           { */
-  /*                             Record_Br_Len(mixt_tree); */
-  /*                             best_alpha = tree->mod->ras->alpha->v; */
-  /*                             best_pinv  = tree->mod->ras->pinvar->v; */
-  /*                             best_mult  = tree->mod->br_len_mult->v; */
-  /*                             /\* PhyML_Printf("\n>.< New alpha=%f pinv=%f",best_alpha,best_pinv); *\/ */
-  /*                           } */
-  /*                         /\* PhyML_Printf("\n> f1=%f",f1); *\/ */
-  /*                       } */
-  /*                     else /\* f1 < f2 *\/ */
-  /*                       { */
-  /*                         x0 = x1; */
-  /*                         x1 = x2; */
-  /*                         x2 = x2 + K * FABS(x3 - x2); */
-                          
-  /*                         f0 = f1; */
-  /*                         f1 = f2; */
-                          
-  /*                         tree->mod->ras->alpha->v = x2; */
-  /*                         tree->mod->ras->pinvar->v = slope * tree->mod->ras->alpha->v + intercept; */
-  /*                         if(tree->mod->ras->pinvar->v > 1.0) tree->mod->ras->pinvar->v = 0.9; */
-  /*                         if(tree->mod->ras->pinvar->v < 0.0) tree->mod->ras->pinvar->v = 0.001; */
-  /*                         Set_Both_Sides(YES,mixt_tree); */
-  /*                         Lk(NULL,mixt_tree); */
-  /*                         Optimize_Br_Len_Serie(mixt_tree); */
-  /*                         f2 = mixt_tree->c_lnL; */
-  /*                         if(f2 > best_lnL) */
-  /*                           { */
-  /*                             Record_Br_Len(mixt_tree); */
-  /*                             best_alpha = tree->mod->ras->alpha->v; */
-  /*                             best_pinv  = tree->mod->ras->pinvar->v; */
-  /*                             best_mult  = tree->mod->br_len_mult->v; */
-  /*                             /\* PhyML_Printf("\n>o< New alpha=%f pinv=%f",best_alpha,best_pinv); *\/ */
-  /*                           } */
-  /*                         /\* PhyML_Printf("\n> f2=%f",f2); *\/ */
-  /*                       } */
-                      
-  /*                     if(FABS(f1 - f2) < 0.01) break; */
-                      
-  /*                     iter++; */
-                      
-  /*                   }while(iter < 100); */
-  /*               } */
-              
-  /*             tree->mod->ras->alpha->v  = best_alpha; */
-  /*             tree->mod->ras->pinvar->v = best_pinv; */
-  /*             tree->mod->br_len_mult->v = best_mult; */
-  /*             Restore_Br_Len(mixt_tree); */
-  /*             Set_Both_Sides(YES,mixt_tree); */
-  /*             Lk(NULL,mixt_tree); */
-              
-  /*             if(verbose) */
-  /*               { */
-  /*                 Print_Lk(mixt_tree,"[Alpha              ]"); */
-  /*                 PhyML_Printf("[%10f]",tree->mod->ras->alpha->v); */
-  /*                 Print_Lk(mixt_tree,"[P-inv              ]"); */
-  /*                 PhyML_Printf("[%10f]",tree->mod->ras->pinvar->v); */
-  /*               } */
-  /*           } */
-  /*       } */
-
-  /*     tree = tree->next_mixt; */
+  best_lnL = old_lnL = init_lnL = tree->c_lnL;
+  best_l = *l;
 
-  /*   } */
-  /* while(tree); */
+  /* PhyML_Printf("\n Begin NR loop (lnL: %f dlnL: %f d2lnL: %f) l: %12f num: %d",tree->c_lnL,tree->c_dlnL,tree->c_d2lnL,*l,b->num); */
+  
+  converged = NO;
+  iter = 0;
+  do
+    {
+      old_lnL = tree->c_lnL;
+      dl      = tree->c_dlnL;
+      d2l     = tree->c_d2lnL;
+
+      /* PhyML_Printf("\n cur_l:%12f lnL:%12f dl:%12G d2l:%12G delta:%12G", */
+      /*              *l, */
+      /*              tree->c_lnL, */
+      /*              dl, */
+      /*              d2l, */
+      /*              old_lnL-tree->c_lnL); */
+
+      if(d2l > 0.0)
+        {
+          *l *= 0.1;
+        }
+      else
+        {
+          ratio = dl/d2l;
+          if(isnan(ratio) == NO) *l -= dl/d2l;
+        }
+      
+      if(*l < tree->mod->l_min) *l = tree->mod->l_min;
+      if(*l > tree->mod->l_max) *l = tree->mod->l_max;
+  
+      if(isnan(*l) == TRUE)
+        {
+          PhyML_Printf("\n\n== dl=%f d2l:%f",dl,d2l);
+          assert(FALSE);
+        }
+      
+
+      Set_Use_Eigen_Lr(YES,tree);
+      dLk(l,b,tree);
+
+      /* PhyML_Printf(" -- new_l: %12f lk: %f ratio: %G",*l,tree->c_lnL,ratio); */
+      
+      iter++;
+      if(iter > n_iter_max) break;
+
+      if(tree->c_lnL > best_lnL)
+        {
+          best_lnL = tree->c_lnL;
+          best_l   = *l;
+        }
+
+
+      if(FABS(tree->c_lnL-old_lnL) < tol) converged = YES;
+      if(FABS(dl) < 1.E-2) converged = YES;
+    }
+  while(converged == NO);
+  
+  *l = best_l;
+  tree->c_lnL = best_lnL;
   
-  /* /\* PhyML_Printf("\n\n. Init lnL after golden opt = %f [%f] best_alpha=%f best_pinv=%f",tree->c_lnL,Lk(tree),best_alpha,best_pinv); *\/ */
+  /* Set_Use_Eigen_Lr(NO,tree); */
+  /* tree->c_lnL = Lk(b,tree); */
 
-  /* if(alpha) Free(alpha); */
+  /* printf("\n. init: %f current: %f l: %f",init_lnL,tree->c_lnL,b->l->v); */
+  /* Exit("\n"); */
+  /* assert(best_lnL > init_lnL-tol); */
+  
+  /* Set_Use_Eigen_Lr(YES,tree); */
+  /* dLk(l,b,tree); */
+  /* PhyML_Printf("\n End NR loop (lnL: %f dlnL: %f d2lnL: %f) l: %12f",tree->c_lnL,tree->c_dlnL,tree->c_d2lnL,*l); */
 
-  /* return 1; */
+  return tree->c_lnL;
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 phydbl Generic_Brent_Lk(phydbl *param, phydbl ax, phydbl cx, phydbl tol,
                         int n_iter_max, int quickdirty,
                         phydbl (*obj_func)(t_edge *,t_tree *,supert_tree *),
@@ -2499,37 +2380,36 @@ phydbl Generic_Brent_Lk(phydbl *param, phydbl ax, phydbl cx, phydbl tol,
   a=((ax < cx) ? ax : cx);
   b=((ax > cx) ? ax : cx);
   x=w=v=bx;
-  old_lnL = UNLIKELY;
   (*param) = bx;
-  if(logt == YES) (*param) = EXP(MIN(1.E+2,*param));
+  if(logt == YES) (*param) = exp(MIN(1.E+2,*param));
   fw=fv=fx=fu=-(*obj_func)(branch,tree,stree);
-  if(logt == YES) (*param) = LOG(*param);
-  init_lnL = -fw;
-
-  /* PhyML_Printf("\n. %p %p %p init_lnL = %f a=%f b=%f c=%f",branch,tree,stree,init_lnL,ax,bx,cx); */
+  if(logt == YES) (*param) = log(*param);
+  init_lnL = old_lnL = fw;
+  
+  /* PhyML_Printf("\n. %p %p %p init_lnL=%f fu=%f ax=%f cx=%f param=%f",branch,tree,stree,init_lnL,fu,ax,cx,*param); */
   
   for(iter=1;iter<=BRENT_IT_MAX;iter++)
     {
       xm=0.5*(a+b);
       tol2=2.0*(tol1=tol*x+BRENT_ZEPS);
       
-      if((fu > init_lnL + tol) && (quickdirty))
+      if((fu < init_lnL + tol) && (quickdirty == YES) && (iter > 1))
         {
           (*param) = x;
-          if(logt == YES) (*param) = EXP(MIN(1.E+2,*param));
+          if(logt == YES) (*param) = exp(MIN(1.E+2,*param));
           fu = (*obj_func)(branch,tree,stree);
-          if(logt == YES) (*param) = LOG(*param);
+          if(logt == YES) (*param) = log(*param);
+          /* printf("\n. return %f [%f] %d",fu,*param,iter); */
           return fu;
         }
 
-/*       if(((FABS(cur_lnL-old_lnL) < tol) && (cur_lnL > init_lnL - tol)) || (iter > n_iter_max - 1)) */
-      if((FABS(fu-old_lnL) < tol) || (iter > n_iter_max - 1))
+      if((FABS(fu-old_lnL) < tol && iter > 1) || (iter > n_iter_max - 1))
         {
           (*param) = x;
-          if(logt == YES) (*param) = EXP(MIN(1.E+2,*param));
+          if(logt == YES) (*param) = exp(MIN(1.E+2,*param));
           fu = (*obj_func)(branch,tree,stree);
-          if(logt == YES) (*param) = LOG(*param);
-    /* 	  Exit("\n"); */
+          if(logt == YES) (*param) = log(*param);
+          /* printf("\n. return %f [%f] %d",*param,fu,iter); */
           return fu;
         }
 
@@ -2546,30 +2426,29 @@ phydbl Generic_Brent_Lk(phydbl *param, phydbl ax, phydbl cx, phydbl tol,
           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"); */
+              /* PhyML_Printf("\n. Golden section step"); */
             }
           else
             {
               d=p/q;
               u=x+d;
               if (u-a < tol2 || b-u < tol2) d=SIGN(tol1,xm-x);
-              /* PhyML_Printf(" Parabolic step [e=%f]\n",e); */
-            }
+              /* PhyML_Printf("\n. Parabolic step [e=%f]",e); */
             }
+        }
       else
         {
           d=BRENT_CGOLD*(e=(x >= xm ? a-x : b-x));
-          /* PhyML_Printf(" Golden section step (default) [e=%f tol1=%f a=%f b=%f d=%f]\n",e,tol1,a,b,d); */
+          /* PhyML_Printf("\n. Golden section step (default) [e=%f tol1=%f a=%f b=%f d=%f x=%f]",e,tol1,a,b,d,x); */
         }
 
       u=(FABS(d) >= tol1 ? x+d : x+SIGN(tol1,d));
       (*param) = u;
       old_lnL = fu;
-      if(logt == YES) (*param) = EXP(MIN(1.E+2,*param));
+      if(logt == YES) (*param) = exp(MIN(1.E+2,*param));
       fu = -(*obj_func)(branch,tree,stree);
-      if(logt == YES) (*param) = LOG(*param);
-
-      /* PhyML_Printf("\n. iter=%d/%d param=%f lnL=%f",iter,BRENT_IT_MAX,*param,fu); */
+      if(logt == YES) (*param) = log(*param);
+      /* PhyML_Printf("\n. iter=%d/%d param=%f lnL=%f u: %f x: %f d: %f logt: %d",iter,BRENT_IT_MAX,*param,fu,u,x,d,logt); */
 
       if(fu <= fx)
         {
@@ -2580,7 +2459,6 @@ phydbl Generic_Brent_Lk(phydbl *param, phydbl ax, phydbl cx, phydbl tol,
       else
         {
           if (u < x) a=u; else b=u;
-    /* 	  if (fu <= fw || w == x) */
           if (fu < fw || FABS(w-x) < SMALL)
             {
               v=w;
@@ -2588,7 +2466,7 @@ phydbl Generic_Brent_Lk(phydbl *param, phydbl ax, phydbl cx, phydbl tol,
               fv=fw;
               fw=fu;
             }
-    /* 	  else if (fu <= fv || v == x || v == w) */
+          /* 	  else if (fu <= fv || v == x || v == w) */
           else if (fu < fv || FABS(v-x) < SMALL || FABS(v-w) < SMALL)
             {
               v=u;
@@ -2597,7 +2475,7 @@ phydbl Generic_Brent_Lk(phydbl *param, phydbl ax, phydbl cx, phydbl tol,
         }
     }
 
-  Exit("\n. Too many iterations in Generic_Brent_Lk !");
+  Exit("\n== Too many iterations in Generic_Brent_Lk !");
   return(-1);
   /* Not Reached ??  *param=x;   */
   /* Not Reached ??  return fx; */
@@ -2620,9 +2498,6 @@ void Round_Optimize_Node_Heights(t_tree *tree)
   new_lnL = Lk(NULL,tree);
 
 
-  printf("\n. cur_lnL = %f new_lnL=%f",cur_lnL,new_lnL);
-
-
   n_iter = 0;
   while(fabs(new_lnL - cur_lnL) > tree->mod->s_opt->min_diff_lk_local)
     {
@@ -2631,12 +2506,12 @@ void Round_Optimize_Node_Heights(t_tree *tree)
       Opt_Node_Heights_Recurr(tree);
 
       Generic_Brent_Lk(&(tree->rates->clock_r),
-                   tree->rates->min_clock,
-                   tree->rates->max_clock,
-                   tree->mod->s_opt->min_diff_lk_local,
-                   tree->mod->s_opt->brent_it_max,
-                   tree->mod->s_opt->quickdirty,
-                   Wrap_Lk,NULL,tree,NULL,NO);
+                       tree->rates->min_clock,
+                       tree->rates->max_clock,
+                       tree->mod->s_opt->min_diff_lk_local,
+                       tree->mod->s_opt->brent_it_max,
+                       tree->mod->s_opt->quickdirty,
+                       Wrap_Lk,NULL,tree,NULL,NO);
 
       printf("\n. cur_lnL=%f new_lnL=%f clock_r=%G root height=%f",
          cur_lnL,new_lnL,tree->rates->clock_r,tree->rates->nd_t[tree->n_root->num]);
@@ -2656,14 +2531,14 @@ void Opt_Node_Heights_Recurr(t_tree *tree)
   Opt_Node_Heights_Recurr_Pre(tree->n_root,tree->n_root->v[1],tree);
 
   Generic_Brent_Lk(&(tree->rates->nd_t[tree->n_root->num]),
-           MIN(tree->rates->t_prior_max[tree->n_root->num],
-               MIN(tree->rates->nd_t[tree->n_root->v[2]->num],
-               tree->rates->nd_t[tree->n_root->v[1]->num])),
-           tree->rates->t_prior_min[tree->n_root->num],
-           tree->mod->s_opt->min_diff_lk_local,
-           tree->mod->s_opt->brent_it_max,
-           tree->mod->s_opt->quickdirty,
-           Wrap_Lk,NULL,tree,NULL,NO);
+                   MIN(tree->rates->t_prior_max[tree->n_root->num],
+                       MIN(tree->rates->nd_t[tree->n_root->v[2]->num],
+                           tree->rates->nd_t[tree->n_root->v[1]->num])),
+                   tree->rates->t_prior_min[tree->n_root->num],
+                   tree->mod->s_opt->min_diff_lk_local,
+                   tree->mod->s_opt->brent_it_max,
+                   tree->mod->s_opt->quickdirty,
+                   Wrap_Lk,NULL,tree,NULL,NO);
 }
 
 //////////////////////////////////////////////////////////////
@@ -2681,7 +2556,7 @@ void Opt_Node_Heights_Recurr_Pre(t_node *a, t_node *d, t_tree *tree)
       t_node *v2,*v3;
 
       v2 = v3 = NULL;
-      For(i,3)
+      for(i=0;i<3;i++)
     if((d->v[i] != a) && (d->b[i] != tree->e_root))
       {
         if(!v2) { v2 = d->v[i]; }
@@ -2711,11 +2586,11 @@ void Opt_Node_Heights_Recurr_Pre(t_node *a, t_node *d, t_tree *tree)
         }
 
       Generic_Brent_Lk(&(tree->rates->nd_t[d->num]),
-               t_min,t_max,
-               tree->mod->s_opt->min_diff_lk_local,
-               tree->mod->s_opt->brent_it_max,
-               tree->mod->s_opt->quickdirty,
-               Wrap_Lk,NULL,tree,NULL,NO);
+                       t_min,t_max,
+                       tree->mod->s_opt->min_diff_lk_local,
+                       tree->mod->s_opt->brent_it_max,
+                       tree->mod->s_opt->quickdirty,
+                       Wrap_Lk,NULL,tree,NULL,NO);
 
       /* printf("\n. t%d = %f [%f;%f] lnL = %f",d->num,tree->rates->nd_t[d->num],t_min,t_max,tree->c_lnL); */
 
@@ -2743,7 +2618,7 @@ void Optimize_RR_Params(t_tree *mixt_tree, int verbose)
     {
       if(tree->next) tree = tree->next;
       
-      For(i,n_r_mat) if(tree->mod->r_mat == r_mat[i]) break;
+      for(i=0;i<n_r_mat;i++) if(tree->mod->r_mat == r_mat[i]) break;
       
       if(i == n_r_mat) // tree->mod->r_mat was not found before
         {
@@ -2759,7 +2634,7 @@ void Optimize_RR_Params(t_tree *mixt_tree, int verbose)
             {
               int failed,i;
               
-              For(i,tree->mod->r_mat->n_diff_rr) tree->mod->r_mat->rr_val->v[i] = LOG(tree->mod->r_mat->rr_val->v[i]);
+              for(i=0;i<tree->mod->r_mat->n_diff_rr;i++) tree->mod->r_mat->rr_val->v[i] = log(tree->mod->r_mat->rr_val->v[i]);
               
               failed = YES;
               
@@ -2772,20 +2647,21 @@ void Optimize_RR_Params(t_tree *mixt_tree, int verbose)
                        &Lnsrch,&failed);
                 }
 
-              For(i,tree->mod->r_mat->n_diff_rr) tree->mod->r_mat->rr_val->v[i] = EXP(tree->mod->r_mat->rr_val->v[i]);
+              for(i=0;i<tree->mod->r_mat->n_diff_rr;i++) tree->mod->r_mat->rr_val->v[i] = exp(tree->mod->r_mat->rr_val->v[i]);
               
 
               if(failed == YES)
                 {
-                  For(i,tree->mod->r_mat->n_diff_rr)
+                  for(i=0;i<tree->mod->r_mat->n_diff_rr;i++)
                     if(i != 5)
                       {
                         Generic_Brent_Lk(&(tree->mod->r_mat->rr_val->v[i]),
-                                         1.E-2,1.E+2,
+                                         RR_MIN,RR_MAX,
                                          tree->mod->s_opt->min_diff_lk_local,
                                          tree->mod->s_opt->brent_it_max,
                                          tree->mod->s_opt->quickdirty,
                                          Wrap_Lk,NULL,mixt_tree,NULL,NO);
+                        
                       }
                 }
               
@@ -2826,9 +2702,9 @@ void Optimize_TsTv(t_tree *mixt_tree, int verbose)
 
   do
     {
-      if(tree->next) tree = tree->next;
+      if(tree->is_mixt_tree == YES) tree = tree->next;
       
-      For(i,n_tstv) if(tree->mod->kappa == tstv[i]) break;
+      for(i=0;i<n_tstv;i++) if(tree->mod->kappa == tstv[i]) break;
       
       if(i == n_tstv)
         {
@@ -2837,10 +2713,17 @@ void Optimize_TsTv(t_tree *mixt_tree, int verbose)
           tstv[n_tstv] = tree->mod->kappa;
           n_tstv++;
           
-          if(tree->mod->s_opt->opt_kappa)
+          if(tree->mod->s_opt->opt_kappa == YES)
             {
+              phydbl a,c;
+              
+              /* a = tree->mod->kappa->v * .1; */
+              /* c = tree->mod->kappa->v * 10.; */
+              a = TSTV_MIN;
+              c = TSTV_MAX;
+                            
               Generic_Brent_Lk(&(tree->mod->kappa->v),
-                               0.1,100.,
+                               a,c,
                                tree->mod->s_opt->min_diff_lk_local,
                                tree->mod->s_opt->brent_it_max,
                                tree->mod->s_opt->quickdirty,
@@ -2883,8 +2766,7 @@ void Optimize_Pinv(t_tree *mixt_tree, int verbose)
 
   do
     {
-
-      For(i,n_pinv) if(tree->mod->ras->pinvar == pinv[i]) break;
+      for(i=0;i<n_pinv;i++) if(tree->mod->ras->pinvar == pinv[i]) break;
 
       if(i == n_pinv)
         {
@@ -2892,11 +2774,11 @@ 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,
+                               PINV_MIN,PINV_MAX,
                                tree->mod->s_opt->min_diff_lk_local,
                                tree->mod->s_opt->brent_it_max,
                                tree->mod->s_opt->quickdirty,
@@ -2904,13 +2786,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);
@@ -2937,9 +2819,10 @@ void Optimize_Alpha(t_tree *mixt_tree, int verbose)
 
   do
     {
+
       if(tree->mod->s_opt->opt_alpha == YES && tree->mod->ras->n_catg > 1)
         {
-          For(i,n_alpha) if(tree->mod->ras->alpha == alpha[i]) break;
+          for(i=0;i<n_alpha;i++) if(tree->mod->ras->alpha == alpha[i]) break;
 
           if(i == n_alpha)
             {
@@ -2952,10 +2835,11 @@ void Optimize_Alpha(t_tree *mixt_tree, int verbose)
                  tree->mod->ras->free_mixt_rates == NO &&
                  tree->mod->s_opt->opt_pinvar == NO)
                 {
+                  
                   if(tree->mod->ras->n_catg > 1)
                     {
                       Generic_Brent_Lk(&(tree->mod->ras->alpha->v),
-                                       tree->mod->ras->alpha->v/2.,100.,
+                                       ALPHA_MIN,ALPHA_MAX,
                                        tree->mod->s_opt->min_diff_lk_local,
                                        tree->mod->s_opt->brent_it_max,
                                        tree->mod->s_opt->quickdirty,
@@ -2999,6 +2883,7 @@ void Optimize_Free_Rate(t_tree *mixt_tree, int verbose)
               fast = YES;
               lk_before = tree->c_lnL;
               Optimize_Free_Rate_Weights(tree,fast,verbose);
+              lk_after = tree->c_lnL;
               Optimize_Free_Rate_Rr(tree,fast,verbose);
               lk_after = tree->c_lnL;
 
@@ -3019,13 +2904,13 @@ void Optimize_Free_Rate(t_tree *mixt_tree, int verbose)
               lk_before = tree->c_lnL;
 
               /* For(i,2*tree->n_otu-3) x[pos++] = &(tree->a_edges[i]->l->v); */
-              For(i,tree->mod->ras->n_catg) x[pos++] = tree->mod->ras->gamma_rr_unscaled->v+i;
-              For(i,tree->mod->ras->n_catg) x[pos++] = tree->mod->ras->gamma_r_proba_unscaled->v+i;
+              for(i=0;i<tree->mod->ras->n_catg;i++) x[pos++] = tree->mod->ras->gamma_rr_unscaled->v+i;
+              for(i=0;i<tree->mod->ras->n_catg;i++) x[pos++] = tree->mod->ras->gamma_r_proba_unscaled->v+i;
 
-              /* For(i,2*tree->n_otu-3 + 2*tree->mod->ras->n_catg) *(x[i]) = LOG(MAX(1.E-10,*(x[i]))); */
+              /* For(i,2*tree->n_otu-3 + 2*tree->mod->ras->n_catg) *(x[i]) = log(MAX(1.E-10,*(x[i]))); */
               /* For(i,2*tree->mod->ras->n_catg) printf("\n:: %12f",*(x[i])); fflush(NULL); */
-              For(i,2*tree->mod->ras->n_catg) *(x[i]) = LOG(MAX(1.E-10,*(x[i])));
-              /* For(i,2*tree->n_otu-3 + 2*tree->mod->ras->n_catg) printf("\n<> %12f",*(x[i])); */
+              For(i,2*tree->mod->ras->n_catg) *(x[i]) = log(MAX(1.E-10,*(x[i])));
+              /* For(i,2*tree->mod->ras->n_catg) printf("\n>> %12f",*(x[i])); fflush(NULL); */
               /* For(i,2*tree->mod->ras->n_catg) printf("\n<> %12f",*(x[i])); fflush(NULL); */
 
               failed = YES;
@@ -3036,8 +2921,8 @@ void Optimize_Free_Rate(t_tree *mixt_tree, int verbose)
                               &Lnsrch_Nonaligned,&failed);
 
 
-              /* For(i,2*tree->n_otu-3 + 2*tree->mod->ras->n_catg) *(x[i]) = EXP(*(x[i])); */
-              For(i,2*tree->mod->ras->n_catg) *(x[i]) = EXP(MIN(1.E+2,*(x[i])));
+              /* For(i,2*tree->n_otu-3 + 2*tree->mod->ras->n_catg) *(x[i]) = exp(*(x[i])); */
+              For(i,2*tree->mod->ras->n_catg) *(x[i]) = exp(MIN(1.E+2,*(x[i])));
 
               lk_after = tree->c_lnL;
 
@@ -3079,7 +2964,7 @@ void Optimize_Free_Rate_Rr(t_tree *tree, int fast, int verbose)
 
       if(fast == YES)
         {
-          For(i,tree->mod->ras->n_catg) tree->mod->ras->skip_rate_cat[i] = YES;
+          for(i=0;i<tree->mod->ras->n_catg;i++) tree->mod->ras->skip_rate_cat[i] = YES;
           tree->mod->ras->normalise_rr                                   = NO;
 
           wm = Weighted_Mean(tree->mod->ras->gamma_rr_unscaled->v,
@@ -3091,18 +2976,22 @@ void Optimize_Free_Rate_Rr(t_tree *tree, int fast, int verbose)
         }
 
 
-      For(i,tree->mod->ras->n_catg-1)
+      for(i=0;i<tree->mod->ras->n_catg-1;i++)
         {
           if(fast == YES) tree->mod->ras->skip_rate_cat[i] = NO;
 
+          phydbl a,c;
+          
+          a = tree->mod->ras->gamma_rr_unscaled->v[i] * .1;
+          c = tree->mod->ras->gamma_rr_unscaled->v[i] * 10.;
+          
           Generic_Brent_Lk(&(tree->mod->ras->gamma_rr_unscaled->v[i]),
-                           0.0,
-                           100.,
+                           a,c,
                            tree->mod->s_opt->min_diff_lk_local,
                            tree->mod->s_opt->brent_it_max,
                            tree->mod->s_opt->quickdirty,
                            Wrap_Lk,NULL,tree,NULL,NO);
-
+          
           if(fast == YES) tree->mod->ras->skip_rate_cat[i] = YES;
 
           lk_after = tree->c_lnL;
@@ -3117,7 +3006,7 @@ void Optimize_Free_Rate_Rr(t_tree *tree, int fast, int verbose)
 
       if(fast == YES)
         {
-          For(i,tree->mod->ras->n_catg) tree->mod->ras->skip_rate_cat[i] = NO;
+          for(i=0;i<tree->mod->ras->n_catg;i++) tree->mod->ras->skip_rate_cat[i] = NO;
           tree->mod->ras->normalise_rr                                   = YES;
 
           wm = Weighted_Mean(tree->mod->ras->gamma_rr_unscaled->v,
@@ -3133,10 +3022,15 @@ void Optimize_Free_Rate_Rr(t_tree *tree, int fast, int verbose)
   else
     {
       int i;
-      For(i,tree->mod->ras->n_catg-1)
+      for(i=0;i<tree->mod->ras->n_catg-1;i++)
         {
+          phydbl a,c;
+          
+          a = tree->mod->ras->gamma_rr_unscaled->v[i] * .1;
+          c = tree->mod->ras->gamma_rr_unscaled->v[i] * 10.;
+                    
           Generic_Brent_Lk(&(tree->mod->ras->gamma_rr_unscaled->v[i]),
-                           1.E-2,100.,
+                           a,c,
                            tree->mod->s_opt->min_diff_lk_local,
                            tree->mod->s_opt->brent_it_max,
                            tree->mod->s_opt->quickdirty,
@@ -3156,7 +3050,7 @@ void Optimize_Free_Rate_Rr(t_tree *tree, int fast, int verbose)
   if(verbose) Print_Lk(tree,"[Rate class values  ]");
 
   /* int i; */
-  /* For(i,tree->mod->ras->n_catg) */
+  /* for(i=0;i<tree->mod->ras->n_catg;i++) */
   /*   { */
   /*     printf("\n+ c %2d p: %15f r: %15f up: %15f ur: %5f", */
   /*            i+1, */
@@ -3172,9 +3066,9 @@ void Optimize_Free_Rate_Rr(t_tree *tree, int fast, int verbose)
   /* int i; */
   /* printf("\n"); */
   /* printf("X*X %f ",tree->c_lnL); */
-  /* /\* For(i,tree->mod->ras->n_catg) printf("%f ",tree->mod->ras->gamma_rr_unscaled->v[i]); *\/ */
-  /* For(i,tree->mod->ras->n_catg) printf("%f ",tree->mod->ras->gamma_rr->v[i]); */
-  /* For(i,tree->mod->ras->n_catg) printf("%f ",tree->mod->ras->gamma_r_proba->v[i]); */
+  /* /\* for(i=0;i<tree->mod->ras->n_catg;i++) printf("%f ",tree->mod->ras->gamma_rr_unscaled->v[i]); *\/ */
+  /* for(i=0;i<tree->mod->ras->n_catg;i++) printf("%f ",tree->mod->ras->gamma_rr->v[i]); */
+  /* for(i=0;i<tree->mod->ras->n_catg;i++) printf("%f ",tree->mod->ras->gamma_r_proba->v[i]); */
   /* For(i,2*tree->n_otu-3) printf("%f ",tree->a_edges[i]->l->v); */
 }
 
@@ -3204,15 +3098,19 @@ void Optimize_Free_Rate_Weights(t_tree *tree, int fast, int verbose)
       For(i,2*tree->n_otu-1) tree->a_edges[i]->l->v /= (wm * tree->mod->ras->free_rate_mr->v);
     }
 
-  For(i,tree->mod->ras->n_catg-1)
+  for(i=0;i<tree->mod->ras->n_catg-1;i++)
     {
+      phydbl a,c;
+      
+      a = tree->mod->ras->gamma_r_proba_unscaled->v[i] * .1;
+      c = tree->mod->ras->gamma_r_proba_unscaled->v[i] * 10.;
+            
       Generic_Brent_Lk(&(tree->mod->ras->gamma_r_proba_unscaled->v[i]),
-                       0.0,
-                       100.,
+                       a,c,
                        tree->mod->s_opt->min_diff_lk_local,
                        tree->mod->s_opt->brent_it_max,
                        tree->mod->s_opt->quickdirty,
-                       Wrap_Lk,NULL,tree,NULL,NO);
+                       Wrap_Lk,NULL,tree,NULL,NO);      
     }
 
   if(tree->mod->s_opt->skip_tree_traversal == YES && fast == YES)
@@ -3260,44 +3158,49 @@ void Optimize_State_Freqs(t_tree *mixt_tree, int verbose)
     {
       if(tree->next) tree = tree->next;
 
-      For(i,n_freqs) if(tree->mod->e_frq->pi_unscaled == freqs[i]) break;
+      for(i=0;i<n_freqs;i++) if(tree->mod->e_frq->pi_unscaled == freqs[i]) break;
 
       if(i == n_freqs)
-    {
-      if(!freqs) freqs = (vect_dbl **)mCalloc(1,sizeof(vect_dbl *));
-      else       freqs = (vect_dbl **)mRealloc(freqs,n_freqs+1,sizeof(vect_dbl *));
-      freqs[n_freqs] = tree->mod->e_frq->pi_unscaled;
-      n_freqs++;
-
-      if((tree->mod->s_opt->opt_state_freq) && (tree->io->datatype == NT))
         {
-          failed = YES;
-
-          BFGS(mixt_tree,tree->mod->e_frq->pi_unscaled->v,tree->mod->ns,1.e-5,tree->mod->s_opt->min_diff_lk_local,1.e-5,NO,YES,
-               &Return_Abs_Lk,
-               &Num_Derivative_Several_Param,
-               &Lnsrch,&failed);
+          if(!freqs) freqs = (vect_dbl **)mCalloc(1,sizeof(vect_dbl *));
+          else       freqs = (vect_dbl **)mRealloc(freqs,n_freqs+1,sizeof(vect_dbl *));
+          freqs[n_freqs] = tree->mod->e_frq->pi_unscaled;
+          n_freqs++;
           
-          if(failed == YES)
-        {
-          For(i,tree->mod->ns)
+          if((tree->mod->s_opt->opt_state_freq) && (tree->io->datatype == NT))
             {
-              Generic_Brent_Lk(&(tree->mod->e_frq->pi_unscaled->v[i]),
-                       0.,100.,
-                       tree->mod->s_opt->min_diff_lk_local,
-                       tree->mod->s_opt->brent_it_max,
-                       tree->mod->s_opt->quickdirty,
-                       Wrap_Lk,NULL,mixt_tree,NULL,NO);
-            }
-        }
+              failed = YES;
 
-          if(verbose)
-        {
-          Print_Lk(mixt_tree,"[Nucleotide freqs.  ]");
-        }
+              BFGS(mixt_tree,tree->mod->e_frq->pi_unscaled->v,tree->mod->ns,1.e-5,tree->mod->s_opt->min_diff_lk_local,1.e-5,NO,YES,
+                   &Return_Abs_Lk,
+                   &Num_Derivative_Several_Param,
+                   &Lnsrch,&failed);
+              
+              if(failed == YES)
+                {
+                  for(i=0;i<tree->mod->ns;i++)
+                    {
+                      phydbl a,c;
+                      
+                      a = tree->mod->e_frq->pi_unscaled->v[i] * .1;
+                      c = tree->mod->e_frq->pi_unscaled->v[i] * 10.;
+                      
+                      Generic_Brent_Lk(&(tree->mod->e_frq->pi_unscaled->v[i]),
+                                       a,c,
+                                       tree->mod->s_opt->min_diff_lk_local,
+                                       tree->mod->s_opt->brent_it_max,
+                                       tree->mod->s_opt->quickdirty,
+                                       Wrap_Lk,NULL,mixt_tree,NULL,NO);      
+                    }
+                }
+              
+              if(verbose)
+                {
+                  Print_Lk(mixt_tree,"[Nucleotide freqs.  ]");
+                }
+            }
         }
-    }
-
+      
       tree = tree->next;
 
     }
@@ -3326,13 +3229,18 @@ void Optimize_Rmat_Weights(t_tree *mixt_tree, int verbose)
     {
       do
         {
+          phydbl a,c;
+          
+          a = r_mat_weight->v * .1;
+          c = r_mat_weight->v * 10.;
+          
           Generic_Brent_Lk(&(r_mat_weight->v),
-                           0.,100.,
+                           a,c,
                            mixt_tree->mod->s_opt->min_diff_lk_local,
                            mixt_tree->mod->s_opt->brent_it_max,
                            mixt_tree->mod->s_opt->quickdirty,
-                           Wrap_Lk,NULL,mixt_tree,NULL,NO);
-          
+                           Wrap_Lk,NULL,mixt_tree,NULL,NO);      
+
           if(verbose)
             {
               Print_Lk(mixt_tree,"[Rate mat. weights  ]");
@@ -3365,12 +3273,17 @@ void Optimize_Efrq_Weights(t_tree *mixt_tree, int verbose)
     {
       do
         {
+          phydbl a,c;
+          
+          a = e_frq_weight->v * .1;
+          c = e_frq_weight->v * 10.;
+          
           Generic_Brent_Lk(&(e_frq_weight->v),
-                           0.,100.,
+                           a,c,
                            mixt_tree->mod->s_opt->min_diff_lk_local,
                            mixt_tree->mod->s_opt->brent_it_max,
                            mixt_tree->mod->s_opt->quickdirty,
-                           Wrap_Lk,NULL,mixt_tree,NULL,NO);
+                           Wrap_Lk,NULL,mixt_tree,NULL,NO);      
           
           if(verbose)
             {
@@ -3408,7 +3321,7 @@ void Optimize_Lambda(t_tree *mixt_tree, int verbose)
     {
       if(tree->next) tree = tree->next;
 
-      For(i,n_lambda) if(tree->mod->lambda == lambda[i]) break;
+      for(i=0;i<n_lambda;i++) if(tree->mod->lambda == lambda[i]) break;
 
       if(i == n_lambda)
     {
@@ -3420,12 +3333,12 @@ void Optimize_Lambda(t_tree *mixt_tree, int verbose)
       if(tree->mod->s_opt->opt_lambda)
         {
           Generic_Brent_Lk(&(tree->mod->lambda->v),
-                   0.001,100.,
-                   tree->mod->s_opt->min_diff_lk_local,
-                   tree->mod->s_opt->brent_it_max,
-                   tree->mod->s_opt->quickdirty,
-                   Wrap_Lk,NULL,mixt_tree,NULL,NO);
-
+                           0.001,100.,
+                           tree->mod->s_opt->min_diff_lk_local,
+                           tree->mod->s_opt->brent_it_max,
+                           tree->mod->s_opt->quickdirty,
+                           Wrap_Lk,NULL,mixt_tree,NULL,NO);
+          
           if(verbose)
         {
           Print_Lk(mixt_tree,"[Lambda             ]");
diff --git a/src/optimiz.h b/src/optimiz.h
index 58e0dff..29572e3 100644
--- a/src/optimiz.h
+++ b/src/optimiz.h
@@ -27,7 +27,7 @@ void      Optimiz_Ext_Br(t_tree *tree);
 void      Optimize_Param_Parall(t_tree *tree);
 phydbl    Optimize_Branch_Quad(t_tree *tree, calign *cdata, t_edge *b_fcus);
 void      Optimize_After_Hide(t_tree *tree, calign *cdata, t_node *h);
-void      Round_Optimize(t_tree *tree, calign *data, int n_round_max);
+void      Round_Optimize(t_tree *tree, int n_round_max);
 int       Dist_Seq_Brak(phydbl *ax, phydbl *bx, phydbl *cx, 
 			phydbl *fa, phydbl *fb, phydbl *fc, 
 			calign *data, int num1, int num2, t_mod *mod);
@@ -45,7 +45,7 @@ phydbl    Alpha_Golden(phydbl ax, phydbl bx, phydbl cx, phydbl tol,phydbl *xmin,
 		       t_tree *tree, calign *cdata);
 phydbl    Br_Len_Golden(phydbl ax, phydbl bx, phydbl cx, phydbl tol, 
 			phydbl *xmin, t_edge *b_fcus, t_tree *tree);
-phydbl Br_Len_Brent(phydbl prop_min, phydbl prop_max, t_edge *b_fcus, t_tree *tree);
+phydbl Br_Len_Brent(t_edge *b_fcus, t_tree *tree);
 int       Br_Len_Brak(phydbl *ax, phydbl *bx, phydbl *cx, 
 		      phydbl *fa, phydbl *fb, phydbl *fc, 
 		      t_edge *b_fcus, t_tree *tree);
@@ -116,6 +116,12 @@ void BFGS_Nonaligned(t_tree *tree,
 
 
 void Optimize_Single_Param_Generic(t_tree *tree, phydbl *param, phydbl lim_inf, phydbl lim_sup, phydbl tol, int n_max_iter, int quickdirty);
+int Generic_Brak_Lk(phydbl *param,
+                    phydbl *ax, phydbl *bx, phydbl *cx,
+                    phydbl *fa, phydbl *fb, phydbl *fc,
+                    phydbl min, phydbl max,
+                    phydbl (*obj_func)(t_edge *,t_tree *,supert_tree *),
+                    t_edge *branch, t_tree *tree, supert_tree *stree);
 int Generic_Brak(phydbl *param,
 		 phydbl *ax, phydbl *bx, phydbl *cx, 
 		 phydbl *fa, phydbl *fb, phydbl *fc,
diff --git a/src/pars.c b/src/pars.c
index 08fc76d..cec313a 100644
--- a/src/pars.c
+++ b/src/pars.c
@@ -1,7 +1,7 @@
 /*
 
-PHYML :  a program that  computes maximum likelihood  phyLOGenies from
-DNA or AA homoLOGous sequences
+PHYML :  a program that  computes maximum likelihood  phylogenies from
+DNA or AA homologous sequences
 
 Copyright (C) Stephane Guindon. Oct 2003 onward
 
@@ -21,18 +21,25 @@ 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)
+  for(site=0;site<n_patterns;site++)
     {
       tree->site_pars[site] = 0;
       tree->curr_site       = site;
@@ -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;
 }
 
@@ -60,7 +62,7 @@ void Post_Order_Pars(t_node *a, t_node *d, t_tree *tree)
   if(d->tax) return;
   else
     {
-      For(i,3)
+      for(i=0;i<3;i++)
     {
       if(d->v[i] != a)
         Post_Order_Pars(d,d->v[i],tree);
@@ -79,22 +81,22 @@ void Pre_Order_Pars(t_node *a, t_node *d, t_tree *tree)
   if(d->tax) return;
   else
     {
-      For(i,3)
-    {
-      if(d->v[i] != a)
+      for(i=0;i<3;i++)
         {
-          Get_All_Partial_Pars(tree,d->b[i],d->v[i],d);
-          Pre_Order_Pars(d,d->v[i],tree);
+          if(d->v[i] != a)
+            {
+              Get_All_Partial_Pars(tree,d->b[i],d->v[i],d);
+              Pre_Order_Pars(d,d->v[i],tree);
+            }
         }
     }
-    }
 }
 
 /*********************************************************/
 
 void Get_All_Partial_Pars(t_tree *tree, t_edge *b_fcus, t_node *a, t_node *d)
 {
-  Update_P_Pars(tree,b_fcus,d);
+  Update_Partial_Pars(tree,b_fcus,d);
 }
 
 /*********************************************************/
@@ -106,7 +108,7 @@ void Site_Pars(t_tree *tree)
 
 /*********************************************************/
 
-void Init_P_Pars_Tips(t_tree *tree)
+void Init_Partial_Pars_Tips(t_tree *tree)
 {
   int curr_site,i,j;
   short int *state_v;
@@ -116,46 +118,44 @@ void Init_P_Pars_Tips(t_tree *tree)
 
   state_v = (short int *)mCalloc(tree->mod->ns,sizeof(short int));
 
-
-
-  For(curr_site,tree->data->crunch_len)
-    {
-      For(i,tree->n_otu)
+  for(curr_site=0;curr_site<tree->data->crunch_len;curr_site++)
     {
-      if(tree->a_nodes[i]->b[0]->rght->tax != 1)
+      for(i=0;i<tree->n_otu;i++)
         {
+          if(tree->a_nodes[i]->b[0]->rght->tax != 1)
+            {
 	      PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__);
-          Exit("\n");
-        }
-
-      if(tree->io->datatype == NT)
-        {
-          Init_Tips_At_One_Site_Nucleotides_Int(tree->a_nodes[i]->c_seq->state[curr_site],
-                            0,
-                            state_v);
-          For(j,tree->mod->ns) tree->a_nodes[i]->b[0]->p_pars_r[curr_site*dim1+j] = MAX_PARS;
-          For(j,tree->mod->ns) if(state_v[j] > 0.5) tree->a_nodes[i]->b[0]->p_pars_r[curr_site*dim1+j] =  0;
-        }
-      else if(tree->io->datatype == AA)
-        {
-          Init_Tips_At_One_Site_AA_Int(tree->a_nodes[i]->c_seq->state[curr_site],
-                       0,
-                       state_v);
-          For(j,tree->mod->ns) tree->a_nodes[i]->b[0]->p_pars_r[curr_site*dim1+j] = MAX_PARS;
-          For(j,tree->mod->ns) if(state_v[j] > 0.5) tree->a_nodes[i]->b[0]->p_pars_r[curr_site*dim1+j] =  0;
-        }
-      else if(tree->io->datatype == GENERIC)
-        {
-          Init_Tips_At_One_Site_Generic_Int(tree->a_nodes[i]->c_seq->state+curr_site*tree->mod->io->state_len,
-                        tree->mod->ns,
-                        tree->mod->io->state_len,
-                        0,
-                        state_v);
-          For(j,tree->mod->ns) tree->a_nodes[i]->b[0]->p_pars_r[curr_site*dim1+j] = MAX_PARS;
-          For(j,tree->mod->ns) if(state_v[j] > 0.5) tree->a_nodes[i]->b[0]->p_pars_r[curr_site*dim1+j] =  0;
+              Exit("\n");
+            }
+          
+          if(tree->io->datatype == NT)
+            {
+              Init_Tips_At_One_Site_Nucleotides_Int(tree->a_nodes[i]->c_seq->state[curr_site],
+                                                    0,
+                                                    state_v);
+              for(j=0;j<tree->mod->ns;j++) tree->a_nodes[i]->b[0]->p_pars_r[curr_site*dim1+j] = MAX_PARS;
+              for(j=0;j<tree->mod->ns;j++) if(state_v[j] > 0.5) tree->a_nodes[i]->b[0]->p_pars_r[curr_site*dim1+j] =  0;
+            }
+          else if(tree->io->datatype == AA)
+            {
+              Init_Tips_At_One_Site_AA_Int(tree->a_nodes[i]->c_seq->state[curr_site],
+                                           0,
+                                           state_v);
+              for(j=0;j<tree->mod->ns;j++) tree->a_nodes[i]->b[0]->p_pars_r[curr_site*dim1+j] = MAX_PARS;
+              for(j=0;j<tree->mod->ns;j++) if(state_v[j] > 0.5) tree->a_nodes[i]->b[0]->p_pars_r[curr_site*dim1+j] =  0;
+            }
+          else if(tree->io->datatype == GENERIC)
+            {
+              Init_Tips_At_One_Site_Generic_Int(tree->a_nodes[i]->c_seq->state+curr_site*tree->mod->io->state_len,
+                                                tree->mod->ns,
+                                                tree->mod->io->state_len,
+                                                0,
+                                                state_v);
+              for(j=0;j<tree->mod->ns;j++) tree->a_nodes[i]->b[0]->p_pars_r[curr_site*dim1+j] = MAX_PARS;
+              for(j=0;j<tree->mod->ns;j++) if(state_v[j] > 0.5) tree->a_nodes[i]->b[0]->p_pars_r[curr_site*dim1+j] =  0;
+            }
         }
     }
-    }
   Free(state_v);
 }
 
@@ -168,15 +168,15 @@ void Init_Ui_Tips(t_tree *tree)
 
   state_v = (short int *)mCalloc(tree->mod->ns,sizeof(short int));
 
-  For(curr_site,tree->data->crunch_len)
+  for(curr_site=0;curr_site<tree->data->crunch_len;curr_site++)
     {
-      For(i,tree->n_otu)
+      for(i=0;i<tree->n_otu;++i)
         {
           if(tree->io->datatype == NT)
             {
               if(tree->a_nodes[i]->b[0]->rght->tax != 1)
                 {
-                  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");
                 }
               
@@ -187,7 +187,7 @@ void Init_Ui_Tips(t_tree *tree)
               /* 					    0, */
               /* 					    state_v);	       */
               tree->a_nodes[i]->b[0]->ui_r[curr_site] = 0;
-              For(j,tree->mod->ns) tree->a_nodes[i]->b[0]->ui_r[curr_site] += (unsigned int)(state_v[j] * POW(2,j));
+              for(j=0;j<tree->mod->ns;j++) tree->a_nodes[i]->b[0]->ui_r[curr_site] += (int)(state_v[j] * POW(2,j));
             }
           else if(tree->io->datatype == AA)
             {
@@ -198,7 +198,7 @@ void Init_Ui_Tips(t_tree *tree)
               /* 				   0, */
               /* 				   state_v); */
               tree->a_nodes[i]->b[0]->ui_r[curr_site] = 0;
-              For(j,tree->mod->ns) tree->a_nodes[i]->b[0]->ui_r[curr_site] += (unsigned int)(state_v[j] * POW(2,j));
+              for(j=0;j<tree->mod->ns;j++) tree->a_nodes[i]->b[0]->ui_r[curr_site] += (int)(state_v[j] * POW(2,j));
             }
           else if(tree->io->datatype == GENERIC)
             {
@@ -213,7 +213,7 @@ void Init_Ui_Tips(t_tree *tree)
               /* 					0, */
               /* 					state_v); */
               tree->a_nodes[i]->b[0]->ui_r[curr_site] = 0;
-              For(j,tree->mod->ns) tree->a_nodes[i]->b[0]->ui_r[curr_site] += (unsigned int)(state_v[j] * POW(2,j));
+              for(j=0;j<tree->mod->ns;j++) tree->a_nodes[i]->b[0]->ui_r[curr_site] += (int)(state_v[j] * POW(2,j));
             }
         }
     }
@@ -221,7 +221,7 @@ void Init_Ui_Tips(t_tree *tree)
   
   For(br,2*tree->n_otu-3)
     {
-      For(curr_site,tree->data->crunch_len)
+      for(curr_site=0;curr_site<tree->data->crunch_len;curr_site++)
         {
           tree->a_edges[br]->pars_r[curr_site] = 0;
           tree->a_edges[br]->pars_l[curr_site] = 0;
@@ -234,7 +234,7 @@ void Init_Ui_Tips(t_tree *tree)
 
 /*********************************************************/
 
-void Update_P_Pars(t_tree *tree, t_edge *b_fcus, t_node *n)
+void Update_Partial_Pars(t_tree *tree, t_edge *b_fcus, t_node *n)
 {
 /*
            |
@@ -246,15 +246,22 @@ void Update_P_Pars(t_tree *tree, t_edge *b_fcus, t_node *n)
         /     \
 */
 
-  int i,j;
-  int site;
-  unsigned int *ui, *ui_v1, *ui_v2;
+  unsigned int i,j;
+  unsigned int site;
+  int *ui, *ui_v1, *ui_v2;
   int *p_pars_v1, *p_pars_v2, *p_pars;
   int *pars, *pars_v1, *pars_v2;
-  int n_patterns;
   int min_v1,min_v2;
   int v;
-  int dim1;
+  
+  const unsigned int ns = tree->mod->ns;
+  const unsigned int n_patterns = tree->n_pattern;
+
+  if(tree->is_mixt_tree)
+    {
+      MIXT_Update_Partial_Pars(tree,b_fcus,n);
+      return;
+    }
 
   if((tree->io->do_alias_subpatt == YES) &&
      (tree->update_alias_subpatt == YES))
@@ -262,128 +269,124 @@ void Update_P_Pars(t_tree *tree, t_edge *b_fcus, t_node *n)
 
   if(n->tax) return;
 
-  dim1 = tree->mod->ns;
   ui = ui_v1 = ui_v2 = NULL;
   p_pars = p_pars_v1 = p_pars_v2 = NULL;
   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)
+      for(site=0;site<n_patterns;++site)
         {
-          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=0;i<ns;++i)
+            {
+              min_v1 = MAX_PARS;
+              for(j=0;j<ns;++j)
+                {
+                  v = p_pars_v1[site*ns+j] + tree->step_mat[i*ns+j];
+                  if(v < min_v1) min_v1 = v;
+                }
+              
+              min_v2 = MAX_PARS;
+              for(j=0;j<ns;++j)
+                {
+                  v = p_pars_v2[site*ns+j] + tree->step_mat[i*ns+j];
+                  if(v < min_v2) min_v2 = v;
+                }
+              p_pars[site*ns+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])
+      for(site=0;site<n_patterns;++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];
+            }          
         }
-
-    }
     }
 }
 
@@ -392,43 +395,42 @@ void Update_P_Pars(t_tree *tree, t_edge *b_fcus, t_node *n)
 int Pars_Core(t_edge *b, t_tree *tree)
 {
   int site;
-  int i,j;
+  unsigned int i,j;
   int site_pars;
   int min_l,min_r;
   int v;
-  int dim1;
-
-  dim1 = tree->mod->ns;
+  
+  const unsigned int ns = tree->mod->ns;
   site = tree->curr_site;
   site_pars = MAX_PARS;
 
   if(tree->mod->s_opt->general_pars)
     {
-      For(i,tree->mod->ns)
-    {
-      min_l = MAX_PARS;
-      For(j,tree->mod->ns)
+      for(i=0;i<ns;++i)
         {
-          v = b->p_pars_l[site*dim1+j] + tree->step_mat[i*tree->mod->ns+j];
-          if(v < min_l) min_l = v;
-        }
-
-      min_r = MAX_PARS;
-      For(j,tree->mod->ns)
-        {
-          v = b->p_pars_r[site*dim1+j] + tree->step_mat[i*tree->mod->ns+j];
-          if(v < min_r) min_r = v;
+          min_l = MAX_PARS;
+          for(j=0;j<ns;++j)
+            {
+              v = b->p_pars_l[site*ns+j] + tree->step_mat[i*ns+j];
+              if(v < min_l) min_l = v;
+            }
+          
+          min_r = MAX_PARS;
+          for(j=0;j<ns;++j)
+            {
+              v = b->p_pars_r[site*ns+j] + tree->step_mat[i*ns+j];
+              if(v < min_r) min_r = v;
+            }
+          
+          if((min_l + min_r) < site_pars) site_pars = min_l + min_r;
         }
-
-      if((min_l + min_r) < site_pars) site_pars = min_l + min_r;
-    }
     }
   else
     {
       site_pars = b->pars_l[site] + b->pars_r[site];
       if(!(b->ui_l[site] & b->ui_r[site])) site_pars++;
     }
-
+  
   return site_pars;
 }
 
@@ -447,7 +449,7 @@ int One_Pars_Step(t_edge *b,t_tree *tree)
   Set_Both_Sides(YES,tree);
   Pars(NULL,tree);
 
-  For(site,tree->n_pattern)
+  for(site=0;site<tree->n_pattern;site++)
     {
       if(!(b->ui_l[site] & b->ui_r[site])) break;
     }
@@ -469,7 +471,7 @@ int Pars_At_Given_Edge(t_edge *b, t_tree *tree)
   n_patterns = tree->n_pattern;
 
   tree->c_pars = .0;
-  For(site,n_patterns)
+  for(site=0;site<n_patterns;site++)
     {
       tree->site_pars[site] = 0;
       tree->curr_site = site;
@@ -483,8 +485,8 @@ int Pars_At_Given_Edge(t_edge *b, t_tree *tree)
 
 int Update_Pars_At_Given_Edge(t_edge *b_fcus, t_tree *tree)
 {
-  Update_P_Pars(tree,b_fcus,b_fcus->left);
-  Update_P_Pars(tree,b_fcus,b_fcus->rght);
+  Update_Partial_Pars(tree,b_fcus,b_fcus->left);
+  Update_Partial_Pars(tree,b_fcus,b_fcus->rght);
   tree->c_pars = Pars(b_fcus,tree);
   return tree->c_pars;
 }
@@ -942,9 +944,146 @@ void Get_Step_Mat(t_tree *tree)
 
     }
 
-  For(i,tree->mod->ns) tree->step_mat[i*tree->mod->ns+i] = 0;
+  for(i=0;i<tree->mod->ns;i++) tree->step_mat[i*tree->mod->ns+i] = 0;
 }
 
 /*********************************************************/
-
 /*********************************************************/
+/*********************************************************/
+/*********************************************************/
+/*********************************************************/
+/*********************************************************/
+/*********************************************************/
+
+// Tree should be ready for likelihood analysis when calling
+// this function.
+void Stepwise_Add_Pars(t_tree *tree)
+{
+  t_edge **residuals,**targets,*best_target;
+  int *nd_idx,i,j,n_targets,*tg_idx;
+
+  residuals   = (t_edge **)mCalloc(tree->n_otu-3,sizeof(t_edge *));
+  targets     = (t_edge **)mCalloc(2*tree->n_otu-3,sizeof(t_edge *));
+  best_target = NULL;
+  nd_idx      = Permutate(tree->n_otu-3);
+
+  // Remove all tips except that corresponding to a_nodes[0], 
+  // a_nodes[1] and a_nodes[2].  
+  for(i=0;i<tree->n_otu-3;++i)
+    {
+      Prune_Subtree(tree->a_nodes[i+3]->v[0],                   
+                    tree->a_nodes[i+3],
+                    NULL,
+                    residuals+i,
+                    tree);
+    }
+
+  // Initial targets
+  n_targets = 3;
+  for(i=0;i<n_targets;i++) targets[i] = tree->a_nodes[i]->b[0];
+
+  // Regraft each tip on the tree at most parsimonious position
+  for(i=0;i<tree->n_otu-3;++i)
+    {
+      Set_Both_Sides(YES,tree);
+      Pars(NULL,tree);
+
+      /* printf("\n. [%d/%d]",i,tree->n_otu-3); */
+
+      tree->best_pars = 1E+8;
+      best_target = NULL;
+      tg_idx      = Permutate(n_targets);
+
+      for(j=0;j<n_targets;j++)
+        {
+          Graft_Subtree(targets[tg_idx[j]],
+                        tree->a_nodes[nd_idx[i]+3]->v[0],
+                        NULL,
+                        residuals[i],
+                        NULL,
+                        tree);
+          
+          Update_Partial_Pars(tree,
+                        tree->a_nodes[nd_idx[i]+3]->b[0],
+                        tree->a_nodes[nd_idx[i]+3]->v[0]);
+          Pars(tree->a_nodes[nd_idx[i]+3]->b[0],tree);
+          
+
+          if(tree->c_pars < tree->best_pars)
+            {
+              tree->best_pars = tree->c_pars;
+              best_target = targets[tg_idx[j]];
+            }
+          
+          Prune_Subtree(tree->a_nodes[nd_idx[i]+3]->v[0],                        
+                        tree->a_nodes[nd_idx[i]+3],
+                        NULL,
+                        residuals+i,
+                        tree);
+        }
+
+      assert(best_target);
+            
+      Graft_Subtree(best_target,
+                    tree->a_nodes[nd_idx[i]+3]->v[0],
+                    NULL,
+                    residuals[i],
+                    NULL,
+                    tree);
+      
+      targets[n_targets]   = residuals[i]; 
+      targets[n_targets+1] = tree->a_nodes[nd_idx[i]+3]->b[0];
+      
+      Free(tg_idx);
+      n_targets+=2;
+    }
+
+  /* printf("\n. pars: %d",tree->c_pars); */
+  /* Exit("\n"); */
+
+  Free(nd_idx);
+  Free(residuals);
+  Free(targets);
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
diff --git a/src/pars.h b/src/pars.h
index c6831ac..ce3c86e 100644
--- a/src/pars.h
+++ b/src/pars.h
@@ -27,13 +27,16 @@ void Pre_Order_Pars(t_node *a, t_node *d, t_tree *tree);
 void Get_Partial_Pars(t_tree *tree, t_edge *b_fcus, t_node *a, t_node *d);
 void Site_Pars(t_tree *tree);
 void Init_Ui_Tips(t_tree *tree);
-void Update_P_Pars(t_tree *tree, t_edge *b_fcus, t_node *n);
+void Update_Partial_Pars(t_tree *tree, t_edge *b_fcus, t_node *n);
 int Pars_At_Given_Edge(t_edge *b, t_tree *tree);
 void Get_All_Partial_Pars(t_tree *tree, t_edge *b_fcus, t_node *a, t_node *d);
 int Update_Pars_At_Given_Edge(t_edge *b_fcus, t_tree *tree);
-void Init_P_Pars_Tips(t_tree *tree);
+void Init_Partial_Pars_Tips(t_tree *tree);
 void Get_Step_Mat(t_tree *tree);
 int Pars_Core(t_edge *b, t_tree *tree);
 int One_Pars_Step(t_edge *b,t_tree *tree);
+void Stepwise_Add_Pars(t_tree *tree);
+void Backup_Partial_Pars(t_node *d, t_edge *b, t_tree *tree);
+void Restore_Partial_Pars(t_node *d, t_edge *b, t_tree *tree);
 
 #endif
diff --git a/src/phyrex.c b/src/phyrex.c
index aea1700..3c4e8d8 100644
--- a/src/phyrex.c
+++ b/src/phyrex.c
@@ -21,9 +21,8 @@ the GNU public licence. See http://www.opensource.org for details.
 
 int PHYREX_Main(int argc, char *argv[])
 {
-  return(PHYREX_Main_Estimate(argc,argv));
-  /* return(PHYREX_Main_Simulate(argc,argv)); */
-
+  /* return(PHYREX_Main_Estimate(argc,argv)); */
+  return(PHYREX_Main_Simulate(argc,argv));
 }
 
 //////////////////////////////////////////////////////////////
@@ -79,7 +78,7 @@ int PHYREX_Main_Estimate(int argc, char *argv[])
 
   /* Allocate coordinates for all the tips first (will grow afterwards) */
   ldsk_a = (t_ldsk **)mCalloc(tree->n_otu,sizeof(t_ldsk *));
-  For(i,tree->n_otu) 
+  for(i=0;i<tree->n_otu;i++) 
     {
       ldsk_a[i] = PHYREX_Make_Lindisk_Node(n_dim);
       PHYREX_Init_Lindisk_Node(ldsk_a[i],disk,n_dim);
@@ -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,16 @@ 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);
+  /* seed = 32076; /\* !!!!!!!!!! *\/ */
   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); */
+  tree = PHYREX_Simulate_Independent_Loci(n_otus,500,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);
@@ -188,7 +166,7 @@ int PHYREX_Main_Simulate(int argc, char *argv[])
   res = PHYREX_MCMC(tree);
 
   disk = tree->disk;
-  For(i,disk->n_ldsk_a) Free_Ldisk(disk->ldsk_a[i]);
+  for(i=0;i<disk->n_ldsk_a;i++) Free_Ldisk(disk->ldsk_a[i]);
   while(disk->prev)
     {
       disk = disk->prev;
@@ -211,7 +189,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);
@@ -221,13 +199,233 @@ int PHYREX_Main_Simulate(int argc, char *argv[])
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
+
+t_tree *PHYREX_Simulate_Independent_Loci(int n_otu, int n_loci, phydbl w, phydbl h, int r_seed)
+{
+  t_tree *tree;
+  int n_dim,i;
+  t_phyrex_mod *mmod;
+  option *io;
+  t_mod *mod;
+  t_opt *s_opt;
+  calign *cdata;
+  phydbl min_neigh, max_neigh;
+  phydbl area, neigh;
+  phydbl T;
+  phydbl Ne,maxNe,minNe;
+  int locus_idx;
+
+  n_dim = 2; // 2-dimensional landscape
+  area  = w * h;
+
+  io    = (option *)Make_Input();
+  mod   = (t_mod *)Make_Model_Basic();
+  s_opt = (t_opt *)Make_Optimiz();
+
+  Set_Defaults_Input(io);
+  Set_Defaults_Model(mod);
+  Set_Defaults_Optimiz(s_opt);
+
+
+  // io stuff
+  io->mod      = mod;
+  mod->io      = io;
+  mod->s_opt   = s_opt;
+  io->r_seed   = r_seed;
+  io->n_otu    = n_otu;
+  io->init_len = n_loci; /* sequence length */
+  io->data     = Make_Empty_Alignment(io);
+  io->colalias = NO;
+
+  Make_Model_Complete(io->mod);
+  Set_Model_Name(io->mod);
+
+  cdata = Compact_Data(io->data,io);
+  Free_Seq(io->data,io->n_otu);
+  
+  Print_Settings(io);
+
+
+  // tree stuff
+  tree = Make_Tree_From_Scratch(n_otu,cdata);
+  Random_Tree(tree);
+  Connect_CSeqs_To_Nodes(cdata,io,tree);
+  tree->rates = RATES_Make_Rate_Struct(tree->n_otu);
+  RATES_Init_Rate_Struct(tree->rates,io->rates,tree->n_otu);
+    
+  tree->data      = cdata;
+  tree->mod       = mod;
+  tree->io        = io;
+  tree->n_pattern = tree->data->crunch_len;
+
+  Init_Model(cdata,mod,io);
+      
+  tree->mod->ras->n_catg = 1;
+  tree->mod->whichmodel  = HKY85;
+  tree->mod->kappa->v    = 4.0;
+    
+  Prepare_Tree_For_Lk(tree);
+
+
+
+  // migrep model stuff */
+  mmod = PHYREX_Make_Migrep_Model(n_dim);
+  tree->mmod = mmod;
+  PHYREX_Init_Migrep_Mod(mmod,n_dim,w,h);
+
+
+  /* /\* Death proba param *\/ */
+  /* mmod->mu = Uni(); */
+  /* /\* Theta (radius) *\/ */
+  /* mmod->rad = Uni()*(1.0 - 0.2) + 0.2; */
+  /* /\* Rate of events *\/ */
+  /* mmod->lbda = 1.0; */
+  /* /\* Population density *\/ */
+  /* mmod->rho = Uni()*(3.0 - 0.1) + 0.1; */
+
+
+  /* Death proba param */
+  mmod->mu = 0.8;
+  /* Theta (radius) */
+  mmod->rad = 1000.;
+  /* Rate of events */
+  mmod->lbda = 1.0*w*h;
+  /* Population density */
+  mmod->rho = 1.;
+
+  
+  /* Dispersal parameter */
+  mmod->sigsq = 4.*pow(mmod->rad,4)*mmod->lbda*PI*mmod->mu/area;
+  
+  // Duration of a generation in number of events
+  mmod->gen_cal_time = 1./(2.*mmod->mu*pow(mmod->rad,2)/pow(w*h,2)*
+                           (sqrt(2.)*mmod->rad*exp(-.5*pow(h/mmod->rad,2)) + h*sqrt(PI)*erf(sqrt(2.)*h/(2.*mmod->rad)) - sqrt(2.)*mmod->rad)*
+                           (sqrt(2.)*mmod->rad*exp(-.5*pow(w/mmod->rad,2)) + w*sqrt(PI)*erf(sqrt(2.)*w/(2.*mmod->rad)) - sqrt(2.)*mmod->rad));
+  // Divide by rate of events per calendar time unit to get duration of gen. in calendar time unit
+  mmod->gen_cal_time *= 1./mmod->lbda;
+
+  
+  PhyML_Printf("\n. lambda=%G; mu=%G; rad=%G; clockr=%G; sigsq=%G; neigh=%G; N=%G; rhoe=%G one_gen=%G",
+               mmod->lbda,
+               mmod->mu,
+               mmod->rad,
+               tree->rates->clock_r,
+               mmod->sigsq,
+               2./mmod->mu,
+               area*2./(4*PI*mmod->sigsq*mmod->mu),
+               2./(4.*PI*mmod->sigsq*mmod->mu),
+               mmod->gen_cal_time);
+  fflush(NULL);
+
+  
+  // Initialize position of sampled individuals
+  tree->disk = PHYREX_Make_Disk_Event(mmod->n_dim,tree->n_otu);
+  PHYREX_Init_Disk_Event(tree->disk,mmod->n_dim,NULL);
+  tree->disk->time             = 0.0;
+  tree->disk->mmod             = mmod;
+  tree->disk->centr->lonlat[0] = .5*mmod->lim->lonlat[0];
+  tree->disk->centr->lonlat[1] = .5*mmod->lim->lonlat[1];      
+  tree->disk->n_ldsk_a         = tree->n_otu;  
+  
+  for(i=0;i<tree->n_otu;++i) 
+    {
+      char *s;
+      tree->disk->ldsk_a[i] = PHYREX_Make_Lindisk_Node(mmod->n_dim);
+      PHYREX_Init_Lindisk_Node(tree->disk->ldsk_a[i],tree->disk,mmod->n_dim);
+      s = (char *)mCalloc(strlen(tree->disk->ldsk_a[i]->coord->id)+1+20,sizeof(char));
+      strcpy(s,tree->disk->ldsk_a[i]->coord->id);
+      strcat(s,"_deme0\0");
+      Free(tree->disk->ldsk_a[i]->coord->id);
+      tree->disk->ldsk_a[i]->coord->id = s;
+    }
+      
+  for(i=0;i<tree->n_otu;i++)
+    {
+      tree->disk->ldsk_a[i]->coord->lonlat[0] = Uni()*tree->mmod->lim->lonlat[0]; // longitude
+      tree->disk->ldsk_a[i]->coord->lonlat[1] = Uni()*tree->mmod->lim->lonlat[1]; // latitude
+    }
+
+
+
+  // Generate sequences
+  locus_idx = 0;
+  do
+    {
+      PHYREX_Simulate_Backward_Core(NO,tree->disk,tree);
+  
+      // Random selection of a pair. Print out physical distances
+      // between tips and time of coalescence for this pair, at this
+      // particular locus
+      {
+        int *permut = Permutate(tree->n_otu);
+        t_ldsk *lin1 = tree->disk->ldsk_a[permut[0]];
+        t_ldsk *lin2 = tree->disk->ldsk_a[permut[1]];
+        phydbl dist =
+          sqrt(pow(lin1->coord->lonlat[0]-lin2->coord->lonlat[0],2) +
+               pow(lin1->coord->lonlat[1]-lin2->coord->lonlat[1],2));
+
+        t_dsk *disk = tree->disk;
+        do
+          {
+            if(disk->ldsk == lin1->prev) lin1 = lin1->prev;
+            if(disk->ldsk == lin2->prev) lin2 = lin2->prev;
+            if(lin1 == lin2) break; // found MRCA
+            disk = disk->prev;
+          }
+        while(disk);
+
+        assert(lin1 && lin2);
+        
+        PhyML_Printf("\n. #$# %G %G",dist,lin1->disk->time);
+      }
+      
+      PHYREX_Ldsk_To_Tree(tree);  
+
+      Update_Ancestors(tree->n_root,tree->n_root->v[2],tree);
+      Update_Ancestors(tree->n_root,tree->n_root->v[1],tree);
+      RATES_Fill_Lca_Table(tree);
+
+      T = PHYREX_Tree_Height(tree);
+
+      tree->rates->bl_from_rt = YES;
+      tree->rates->clock_r    = 0.01/FABS(T);
+      tree->rates->model      = STRICTCLOCK;
+
+      RATES_Update_Cur_Bl(tree);
+
+      Evolve(tree->data,tree->mod,locus_idx,tree);
+      
+      t_dsk *disk = tree->disk->prev;
+      while(disk->prev)
+        {
+          disk = disk->prev;
+          if(disk->next->ldsk != NULL) Free_Ldisk(disk->next->ldsk);
+          Free_Disk(disk->next);
+        }
+
+      locus_idx++;
+    }
+  while(locus_idx < n_loci);
+
+  tree->data->format = IBDSIM;
+  PhyML_Printf("\n\n");
+  Print_CSeq(stdout,NO,tree->data,tree);
+
+
+  Exit("\n");
+
+  return tree;
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
 // Simulate Etheridge-Barton model backwards in time, following n_otu lineages
-// on a rectangle of dimension width x height
+// on a rectangle of dimension width w x h
 // See Kelleher, Barton & Etheridge, Bioinformatics, 2013.
-t_tree *PHYREX_Simulate(int n_otu, int n_sites, phydbl width, phydbl height, int r_seed)
+t_tree *PHYREX_Simulate(int n_otu, int n_sites, phydbl w, phydbl h, int r_seed)
 {  
   t_tree *tree;
-  int n_dim;
+  int n_dim,i;
   t_phyrex_mod *mmod;
   t_dsk *disk;
   option *io;
@@ -245,7 +443,7 @@ t_tree *PHYREX_Simulate(int n_otu, int n_sites, phydbl width, phydbl height, int
   phydbl Ne,maxNe,minNe;
 
   n_dim = 2; // 2-dimensional landscape
-  area  = width * height;
+  area  = w * h;
 
   io    = (option *)Make_Input();
   mod   = (t_mod *)Make_Model_Basic();
@@ -261,7 +459,7 @@ t_tree *PHYREX_Simulate(int n_otu, int n_sites, phydbl width, phydbl height, int
   io->r_seed   = r_seed;
 
   io->n_otu    = n_otu;
-  io->init_len = 500; /* sequence length */
+  io->init_len = 10; /* sequence length */
 
   io->data = Make_Empty_Alignment(io);
 
@@ -290,7 +488,7 @@ t_tree *PHYREX_Simulate(int n_otu, int n_sites, phydbl width, phydbl height, int
   /* Allocate migrep model */
   mmod = PHYREX_Make_Migrep_Model(n_dim);
   tree->mmod = mmod;
-  PHYREX_Init_Migrep_Mod(mmod,n_dim,width,height);
+  PHYREX_Init_Migrep_Mod(mmod,n_dim,w,h);
 
 
   do
@@ -309,33 +507,27 @@ t_tree *PHYREX_Simulate(int n_otu, int n_sites, phydbl width, phydbl height, int
   mmod->mu = 2./neigh;
 
   /* Theta (radius) */
-  tree->mmod->rad = Uni()*(4.0 - 1.5) + 1.5;
-
+  mmod->rad = Uni()*(3.0 - 0.5) + 0.5;
   mmod->sigsq = neigh / (4.*PI*Ne/area);
-
-  tree->mmod->lbda = area * mmod->sigsq / (4.*PI*tree->mmod->mu*POW(tree->mmod->rad,4));
-
+  mmod->lbda = area * mmod->sigsq / (4.*PI*mmod->mu*pow(mmod->rad,4));
+  mmod->rho = Uni()*(10.0 - 0.1) + 0.1;
+  // Duration of a generation in number of events
+  mmod->gen_cal_time = 1./(2.*mmod->mu*pow(mmod->rad,2)/pow(w*h,2)*
+                           (sqrt(2.)*mmod->rad*exp(-.5*pow(h/mmod->rad,2)) + h*sqrt(PI)*erf(sqrt(2.)*h/(2.*mmod->rad)) - sqrt(2.)*mmod->rad)*
+                           (sqrt(2.)*mmod->rad*exp(-.5*pow(w/mmod->rad,2)) + w*sqrt(PI)*erf(sqrt(2.)*w/(2.*mmod->rad)) - sqrt(2.)*mmod->rad));
+  // Divide by rate of events per calendar time unit to get duration of gen. in calendar time unit
+  mmod->gen_cal_time *= 1./mmod->lbda;
   
-  /* mmod->lbda  = 0.04; */
-  /* mmod->mu    = 0.16; */
-  /* mmod->rad   = 2.75; */
+  /* /\* !!!!!!!!!!!!! *\/ */
+  /* mmod->lbda  = 1.0; */
+  /* mmod->mu    = 0.5; */
+  /* mmod->rad   = 1.E+10; */
   /* 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);
-    
+  PHYREX_Simulate_Backward_Core(YES,tree->disk,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);
@@ -361,26 +553,49 @@ t_tree *PHYREX_Simulate(int n_otu, int n_sites, phydbl width, phydbl height, int
   tree->mod->kappa->v      = 4.0;
     
   Prepare_Tree_For_Lk(tree);
-  Evolve(tree->data,tree->mod,tree);
+  Evolve(tree->data,tree->mod,0,tree);
 
-  if(tree->mod->s_opt->greedy) Init_P_Lk_Tips_Double(tree);
-  else                         Init_P_Lk_Tips_Int(tree);
-  Init_P_Lk_Loc(tree);
+
+  if(tree->mod->s_opt->greedy) Init_Partial_Lk_Tips_Double(tree);
+  else                         Init_Partial_Lk_Tips_Int(tree);
+  Init_Partial_Lk_Loc(tree);
 
   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);
+
+  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));
 
-  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. Spatial coordinates: ");
+  for(i=0;i<tree->n_otu;i++)
+    {
+      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);
 }
@@ -388,48 +603,42 @@ t_tree *PHYREX_Simulate(int n_otu, int n_sites, phydbl width, phydbl height, int
 /*////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////*/
 // Simulate Etheridge-Barton model backwards in time, following n_otu lineages
-// on a rectangle of dimension width x height
+// on a rectangle of dimension width x h
 phydbl PHYREX_Simulate_Backward_Core(int new_loc, t_dsk *init_disk, t_tree *tree)
 {
-  t_dsk *disk;
-  t_ldsk *new_ldsk,**ldsk_a,**ldsk_a_tmp;
-  int i,j,n_disk,n_lineages,n_dim,n_hit,n_lineages_new,err;
-  phydbl dt_dsk,curr_t,prob_hit,u;
+  t_dsk *disk,*new_disk;
+  int i,j;
+  phydbl prob_hit,u;
   t_phyrex_mod *mmod;
-  phydbl lnL;
 
   mmod  = tree->mmod;
-  n_dim = tree->mmod->n_dim;
 
   if(new_loc == YES)
     {
-      init_disk = PHYREX_Make_Disk_Event(n_dim,tree->n_otu);
-      PHYREX_Init_Disk_Event(init_disk,n_dim,NULL);
+      init_disk = PHYREX_Make_Disk_Event(mmod->n_dim,tree->n_otu);
+      PHYREX_Init_Disk_Event(init_disk,mmod->n_dim,NULL);
       init_disk->time             = 0.0;
       init_disk->mmod             = mmod;
       init_disk->centr->lonlat[0] = .5*mmod->lim->lonlat[0];
       init_disk->centr->lonlat[1] = .5*mmod->lim->lonlat[1];      
       init_disk->n_ldsk_a         = tree->n_otu;  
       tree->disk                  = init_disk;
-    }
 
-  if(new_loc == YES)
-    {      
-      For(i,tree->n_otu) 
+      for(i=0;i<tree->n_otu;++i) 
         {
           char *s;
-          init_disk->ldsk_a[i] = PHYREX_Make_Lindisk_Node(n_dim);
-          PHYREX_Init_Lindisk_Node(init_disk->ldsk_a[i],init_disk,n_dim);
+          init_disk->ldsk_a[i] = PHYREX_Make_Lindisk_Node(mmod->n_dim);
+          PHYREX_Init_Lindisk_Node(init_disk->ldsk_a[i],init_disk,mmod->n_dim);
           s = (char *)mCalloc(strlen(init_disk->ldsk_a[i]->coord->id)+1+20,sizeof(char));
           strcpy(s,init_disk->ldsk_a[i]->coord->id);
           strcat(s,"_deme0\0");
           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)
+      for(i=0;i<tree->n_otu;i++)
         {
           init_disk->ldsk_a[i]->coord->lonlat[0] = Uni()*tree->mmod->lim->lonlat[0]; // longitude
           init_disk->ldsk_a[i]->coord->lonlat[1] = Uni()*tree->mmod->lim->lonlat[1]; // latitude
@@ -437,67 +646,61 @@ phydbl PHYREX_Simulate_Backward_Core(int new_loc, t_dsk *init_disk, t_tree *tree
           /* init_disk->ldsk_a[i]->coord->lonlat[1] = (i%(int)SQRT(tree->n_otu)+1)*tree->mmod->lim->lonlat[1]/(SQRT(tree->n_otu)+1); // latitude */
         }
     }
-
-
-  /* Allocate coordinates for all the tips first (will grow afterwards) */
-  ldsk_a = (t_ldsk **)mCalloc(tree->n_otu,sizeof(t_ldsk *));
-  For(i,tree->n_otu) ldsk_a[i] = init_disk->ldsk_a[i];
-  
-  /* Allocate and initialise for next event */
-  init_disk->prev = PHYREX_Make_Disk_Event(n_dim,tree->n_otu);
-  PHYREX_Init_Disk_Event(init_disk->prev,n_dim,NULL);
-  init_disk->prev->next = init_disk;
+ 
+  disk = init_disk;
+  tree->disk = init_disk;
+
+  /* Create new disk */
+  new_disk = PHYREX_Make_Disk_Event(mmod->n_dim,tree->n_otu);
+  PHYREX_Init_Disk_Event(new_disk,mmod->n_dim,NULL);
+  new_disk->time = disk->time + Rexp(mmod->lbda);
+  new_disk->n_ldsk_a = tree->n_otu;
+  for(i=0;i<new_disk->n_ldsk_a;++i) 
+    {
+      new_disk->ldsk_a[i] = PHYREX_Make_Lindisk_Node(mmod->n_dim);
+      PHYREX_Init_Lindisk_Node(new_disk->ldsk_a[i],new_disk,mmod->n_dim);
+      new_disk->ldsk_a[i] = disk->ldsk_a[i];
+    }
+  disk->prev = new_disk;
+  new_disk->next = disk;
 
   /* Move to it */
-  disk = init_disk->prev;
+  disk = disk->prev;
 
-  ldsk_a_tmp = (t_ldsk **)mCalloc(tree->n_otu,sizeof(t_ldsk *));
 
-  curr_t     = init_disk->time;
-  dt_dsk     = 0.0;
-  n_lineages = init_disk->n_ldsk_a;
-  n_disk     = 0;
-  lnL        = 0.0;
   do
-    {      
+    {
+      /* Create new disk */
+      new_disk = PHYREX_Make_Disk_Event(mmod->n_dim,1);
+      Free(new_disk->ldsk_a);
+      new_disk->ldsk_a = NULL;
+      new_disk->n_ldsk_a = 0;
+      PHYREX_Init_Disk_Event(new_disk,mmod->n_dim,NULL);
+      disk->prev = new_disk;      
+      new_disk->next = disk;
+
+
       /* Time of next event */
-      dt_dsk = Rexp(mmod->lbda);
-      curr_t -= dt_dsk;
-      
-      /* Coordinates of next event */
+      new_disk->time = disk->time + Rexp(mmod->lbda);
+
+      /* Coordinates of current event */
       disk->centr->lonlat[0] = Uni()*mmod->lim->lonlat[0];
       disk->centr->lonlat[1] = Uni()*mmod->lim->lonlat[1];      
-
-      /* Density for waiting time to next event */
-      lnL += (LOG(mmod->lbda) - mmod->lbda*dt_dsk);
       
-      /* Uniform density for disk center */
-      For(j,mmod->n_dim) lnL -= LOG(mmod->lim->lonlat[j]);
-
-      disk->time = curr_t;
-      disk->mmod = mmod;
-
-      /* printf("\n. Disk %s has %d lindisk nodes and %d disks under",disk->id,disk->n_ldsk_a,disk->n_disk_under); */
-
-      /* New lindisk (will not be used if no lineage is hit)  */
-      new_ldsk = PHYREX_Make_Lindisk_Node(n_dim);
-      PHYREX_Init_Lindisk_Node(new_ldsk,disk,n_dim);
-
-      /* Sample the location of new_ldsk. */
-      /* Takes into account the limits of the landscape */
+      /* Parent ?*/
+      disk->ldsk = PHYREX_Make_Lindisk_Node(mmod->n_dim);
+      PHYREX_Init_Lindisk_Node(disk->ldsk,disk,mmod->n_dim);
+            
+      /* Its location */
       switch(mmod->name)
         {
-        case PHYREX_UNIFORM: { PHYREX_Runif_Rectangle_Overlap(new_ldsk,disk,mmod); break; }
-        case PHYREX_NORMAL:  { PHYREX_Rnorm_Trunc(new_ldsk,disk,mmod); break; }
-        default : { Generic_Exit(__FILE__,__LINE__,__FUNCTION__); break; }
+        case PHYREX_UNIFORM: { PHYREX_Runif_Rectangle_Overlap(disk->ldsk,disk,mmod); break; }
+        case PHYREX_NORMAL:  { PHYREX_Rnorm_Trunc(disk->ldsk,disk,mmod); break; }
         }
 
-      n_hit          = 0;
-      n_lineages_new = 0;
-      For(i,n_lineages)
+      /* Which lineages in disk->ldsk_a are hit? -> populate new_disk->ldsk_a */
+      for(i=0;i<disk->n_ldsk_a;++i)
         {
-          ldsk_a[i]->prev = NULL;
-          
           prob_hit = -1.;
           switch(mmod->name)
             {
@@ -508,256 +711,468 @@ phydbl PHYREX_Simulate_Backward_Core(int new_loc, t_dsk *init_disk, t_tree *tree
               }
             case PHYREX_NORMAL:  
               { 
-                prob_hit = LOG(mmod->mu);
-                For(j,mmod->n_dim) prob_hit += -POW(ldsk_a[i]->coord->lonlat[j] - disk->centr->lonlat[j],2)/(2.*POW(mmod->rad,2));
-                prob_hit = EXP(prob_hit);
+                prob_hit = log(mmod->mu);
+                for(j=0;j<mmod->n_dim;++j) prob_hit += -POW(disk->ldsk_a[i]->coord->lonlat[j] - disk->centr->lonlat[j],2)/(2.*POW(mmod->rad,2));
+                prob_hit = exp(prob_hit);
                 break; 
               }
             }
           
-          if(PHYREX_Is_In_Disk(ldsk_a[i]->coord,disk,mmod) == YES) 
+          if(PHYREX_Is_In_Disk(disk->ldsk_a[i]->coord,disk,mmod) == YES)
             {
               u = Uni();
-              if(!(u > prob_hit))
+              if(u > prob_hit) // disk->ldsk_a[i] is not hit -> becomes a member of new_disk->ldsk_a
                 {
-                  lnL += LOG(prob_hit);
-                  
-                  PHYREX_Make_Lindisk_Next(new_ldsk);
-
-                  ldsk_a[i]->prev                    = new_ldsk;
-                  new_ldsk->is_hit                   = YES;
-                  new_ldsk->next[new_ldsk->n_next-1] = ldsk_a[i]; 
-                  disk->ldsk                         = new_ldsk;
-
-                  n_hit++;
-
-                  if(n_hit == 1)
-                    {
-                      ldsk_a_tmp[n_lineages_new] = new_ldsk;
-                      n_lineages_new++;
-                    }
+                  if(new_disk->n_ldsk_a == 0) new_disk->ldsk_a = (t_ldsk **)mCalloc(1,sizeof(t_ldsk *));
+                  else new_disk->ldsk_a = (t_ldsk **)mRealloc(new_disk->ldsk_a,new_disk->n_ldsk_a+1,sizeof(t_ldsk *));
+                  new_disk->ldsk_a[new_disk->n_ldsk_a] = disk->ldsk_a[i];
+                  new_disk->n_ldsk_a++;
                 }
               else
                 {
-                  lnL += LOG(1. - prob_hit);
-                }                
+                  // disk->ldsk_a[i] is hit -> coalesce (or just jump) to parent (i.e., disk->ldsk)
+                  disk->ldsk_a[i]->prev = disk->ldsk;
+
+                  PHYREX_Make_Lindisk_Next(disk->ldsk);
+                  disk->ldsk->next[disk->ldsk->n_next-1] = disk->ldsk_a[i];
+                }
             }
+                 
+        }
           
-          if(ldsk_a[i]->prev == NULL) /* Lineage was not hit */
-            {              
-              ldsk_a_tmp[n_lineages_new] = ldsk_a[i];
-              n_lineages_new++;
-            }
+      if(disk->n_ldsk_a == new_disk->n_ldsk_a) // No hit
+        {          
+          Free_Ldisk(disk->ldsk); // Free parent 
+          disk->ldsk = NULL;
         }
-
-      if(n_hit >= 1)
+      else
         {
-          phydbl log_dens_coal;
-          log_dens_coal = 0.0;
-          For(j,mmod->n_dim) log_dens_coal += Log_Dnorm_Trunc(new_ldsk->coord->lonlat[j],
-                                                              disk->centr->lonlat[j],
-                                                              mmod->rad,
-                                                              0.0,
-                                                              mmod->lim->lonlat[j],&err);
-          lnL += log_dens_coal;          
-        }      
+          new_disk->ldsk_a = (t_ldsk **)mRealloc(new_disk->ldsk_a,new_disk->n_ldsk_a+1,sizeof(t_ldsk *));
+          new_disk->ldsk_a[new_disk->n_ldsk_a] = disk->ldsk;
+          new_disk->n_ldsk_a++;
+        }
       
-      assert(!((n_hit > 0) && (n_lineages_new != n_lineages - n_hit + 1)));
-
-      if(n_hit > 0) n_lineages -= (n_hit-1);
- 
-      if(n_hit == 0) Free_Ldisk(new_ldsk);
+      if(new_disk->n_ldsk_a == 1) break;
       
-      n_disk++;
-
-      Free(ldsk_a);
+      disk = new_disk;
+    }
+  while(1);
 
+  disk->prev = NULL;
 
-      if(n_lineages == 1) break;
 
-      ldsk_a = (t_ldsk **)mCalloc(tree->n_otu,sizeof(t_ldsk *));
-      For(i,n_lineages) ldsk_a[i] = ldsk_a_tmp[i];
-      
-      disk->prev = PHYREX_Make_Disk_Event(n_dim,tree->n_otu);
-      PHYREX_Init_Disk_Event(disk->prev,n_dim,NULL);
-      disk->prev->next = disk;
-      
+  /* do */
+  /*   { */
+  /*     PhyML_Printf("\n. disk %s n_next: %d",disk->id,disk->ldsk?disk->ldsk->n_next:-1); */
+  /*     disk = disk->next; */
+  /*   } */
+  /* while(disk); */
 
-      disk = disk->prev;
-    }
-  while(1);
 
-  Free(ldsk_a_tmp);
+  /* PHYREX_Print_Struct('#',tree); */
+  /* Exit("\n"); */
 
-  return(lnL);
+  return(-1.);
 }
 
 /*////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////*/
 // 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)
+// on a rectangle of dimension width x h
+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;
+  t_dsk *disk,*new_disk;
+  t_ldsk *ldsk,**ldsk_a_pop,**ldsk_a_samp,**ldsk_a_tmp,**ldsk_a_tips,*new_ldsk;
+  t_ll *ldsk_list,*dum_ll;
+  int i,j,n_disk,n_dim,n_otu,init_pop_size,curr_pop_size,parent_id,n_lineages,sample_size,n_poly,*permut,n_sampled_demes;
+  phydbl sum,*parent_prob,prob_death,tree_height,max_x,max_y,trans_x,trans_y,t_sim, one_gen;
   short int dies,n_remain;
   t_phyrex_mod *mmod;
   t_poly **poly;
+  t_sarea *area;
+  short int *is_sampled;
+  phydbl w,h;
+  phydbl cx,cy;
+  phydbl lx,ly;
+  int n_survive,n_offspring, n_gen;
+  
+  mmod          = tree->mmod;
+  n_dim         = 2;
+  n_otu         = tree->n_otu;
+  w             = mmod->lim->lonlat[0];
+  h             = mmod->lim->lonlat[1];
+  init_pop_size = mmod->rho*w*h;
+  n_gen         = 10; // number of generations to simulate
+  one_gen       = mmod->gen_cal_time; // time duration of one generation (calendar unit)
+  t_sim         = n_gen * one_gen; // total simulation duration (calendar unit)
 
-  mmod     = tree->mmod;
-  n_dim    = tree->mmod->n_dim;
-  n_otu    = tree->n_otu;
-  /* pop_size = (int)(tree->mmod->rho * tree->mmod->lim->lonlat[0] * tree->mmod->lim->lonlat[1]); */
-  pop_size = 100*n_otu;
 
-  parent_prob = (phydbl *)mCalloc(pop_size,sizeof(phydbl));
 
+  printf("\n. one_gen: %f",one_gen);
+  
   /* Allocate and initialise first disk event */
-  disk = PHYREX_Make_Disk_Event(n_dim,pop_size);
+  disk = PHYREX_Make_Disk_Event(n_dim,init_pop_size);
   PHYREX_Init_Disk_Event(disk,n_dim,NULL);
+  disk->time = 0.0;
+  disk->prev = NULL;
+  disk->n_ldsk_a = init_pop_size;
+  
+  /* Allocate coordinates for all individuals in the starting population */
+  ldsk_list = NULL;
+  i = 0;
+  do
+    {
+      ldsk = PHYREX_Make_Lindisk_Node(n_dim);
+      PHYREX_Init_Lindisk_Node(ldsk,disk,n_dim);
+      Push_Bottom_Linked_List(ldsk,&ldsk_list,NO);
+      i++;
+    }
+  while(i != init_pop_size);
 
-  /* Allocate coordinates for all the individuals in the population */
-  ldsk_a_pop = (t_ldsk **)mCalloc(pop_size,sizeof(t_ldsk *));
-  For(i,pop_size)
+  
+  /* Fill in array of lineages on the first disk */  
+  dum_ll = ldsk_list->head;
+  i = 0;
+  do
     {
-      ldsk_a_pop[i] = PHYREX_Make_Lindisk_Node(n_dim);
-      PHYREX_Init_Lindisk_Node(ldsk_a_pop[i],disk,n_dim);
+      disk->ldsk_a[i] = (t_ldsk *)dum_ll->v;
+      dum_ll = dum_ll->next;
+      i++;
     }
+  while(dum_ll != NULL);
 
-  /* Generate coordinates for all individuals */
-  For(i,pop_size)
+  
+  
+  /* Generate coordinates for all individuals in starting population */
+  for(i=0;i<init_pop_size;i++)
     {
-      ldsk_a_pop[i]->coord->lonlat[0] = Uni()*tree->mmod->lim->lonlat[0]; // longitude
-      ldsk_a_pop[i]->coord->lonlat[1] = Uni()*tree->mmod->lim->lonlat[1]; // latitude
+      disk->ldsk_a[i]->coord->lonlat[0] = Uni()*w; // longitude
+      disk->ldsk_a[i]->coord->lonlat[1] = Uni()*h; // latitude
     }
 
-  disk->prev = NULL;
-  curr_t = 0.0;
-  dt_dsk = 0.0;
+  
   n_disk = 0;
   do
     {
+      /* Create new disk */
+      new_disk = PHYREX_Make_Disk_Event(n_dim,1);
+      Free(new_disk->ldsk_a);
+      new_disk->ldsk_a = NULL;
+      PHYREX_Init_Disk_Event(new_disk,n_dim,NULL);
+      new_disk->prev = disk;      
+      disk->next = new_disk;
+      n_disk++;
+
+            
       /* Coordinates of event */
-      disk->centr->lonlat[0] = Uni()*mmod->lim->lonlat[0];
-      disk->centr->lonlat[1] = Uni()*mmod->lim->lonlat[1];
+      new_disk->centr->lonlat[0] = Uni()*mmod->lim->lonlat[0];
+      new_disk->centr->lonlat[1] = Uni()*mmod->lim->lonlat[1];
 
-      /* Select one parent */
-      For(i,pop_size)
-        {
-          switch(mmod->name)
-            {
-            case PHYREX_UNIFORM:
-              {
-                if(PHYREX_Is_In_Disk(ldsk_a_pop[i]->coord,disk,mmod) == YES)
-                  parent_prob[i] = 1.0;
-                else
-                  parent_prob[i] = 0.0;
-                break;
-              }
-            case PHYREX_NORMAL:
-              {
-                parent_prob[i] = 0.0;
-                For(j,mmod->n_dim) parent_prob[i] += -POW(ldsk_a_pop[i]->coord->lonlat[j] - disk->centr->lonlat[j],2)/(2.*POW(mmod->rad,2));
-                parent_prob[i] = EXP(parent_prob[i]);
-                break;
-              }
-            }
-        }
-      sum = 0.0;
-      For(i,pop_size) sum += parent_prob[i];
-      For(i,pop_size) parent_prob[i] /= sum;
+      cx = new_disk->centr->lonlat[0];
+      cy = new_disk->centr->lonlat[1];
       
-      parent_id  = Sample_i_With_Proba_pi(parent_prob,pop_size);
-      disk->ldsk = ldsk_a_pop[parent_id];
-      ldsk_a_pop[parent_id]->disk = disk;
 
-      /* printf("\n. Disk %s has %s on it",disk->id,ldsk_a_pop[parent_id]->coord->id); */
+      /* Time of new disk */
+      new_disk->time = disk->time + Rexp(mmod->lbda);
 
-      /* Which lineages die in that event? Each lineage that dies off is being replaced
-         with a new one which location is chosen randomly following the model */
-      For(i,pop_size)
+      /* PhyML_Printf("\n. new_disk->time: %f t_sim: %f",new_disk->time,t_sim); */
+      
+      /* Size of current population */
+      curr_pop_size = disk->n_ldsk_a;
+
+      if(curr_pop_size == 0)
         {
-          prob_death = 0.0;
-          switch(mmod->name)
+          PhyML_Printf("\n. Population went extinct after %d events",n_disk);
+          Exit("\n");
+        }
+      
+      
+      if(new_disk->time < t_sim)
+        {
+          /* Select one parent */
+          parent_prob = (phydbl *)mCalloc(curr_pop_size,sizeof(phydbl));
+          for(i=0;i<curr_pop_size;++i)
             {
-            case PHYREX_UNIFORM:
-              {
-                if(PHYREX_Is_In_Disk(ldsk_a_pop[i]->coord,disk,mmod) == YES)
-                  prob_death = mmod->mu;
-                break;
-              }
-            case PHYREX_NORMAL:
-              {
-                prob_death = LOG(mmod->mu);
-                For(j,mmod->n_dim) prob_death += -POW(ldsk_a_pop[i]->coord->lonlat[j] - disk->centr->lonlat[j],2)/(2.*POW(mmod->rad,2));
-                prob_death = EXP(prob_death);
-                break;
-              }
+              lx = disk->ldsk_a[i]->coord->lonlat[0];
+              ly = disk->ldsk_a[i]->coord->lonlat[1];
+              
+              switch(mmod->name)
+                {
+                case PHYREX_UNIFORM:
+                  {
+                    if(PHYREX_Is_In_Disk(disk->ldsk_a[i]->coord,new_disk,mmod) == YES)
+                      parent_prob[i] = 1.0;
+                    else
+                      parent_prob[i] = 0.0;
+                    break;
+                  }
+                case PHYREX_NORMAL:
+                  {
+                    parent_prob[i] = 0.0;
+                    parent_prob[i] += -pow(lx - cx,2)/(2.*pow(mmod->rad,2));
+                    parent_prob[i] += -pow(ly - cy,2)/(2.*pow(mmod->rad,2));
+                    parent_prob[i] = exp(parent_prob[i]);
+                    break;
+                  }
+                }
             }
           
-          dies = NO;
-          if(Uni() < prob_death || i == parent_id) dies = YES; /* Note: parent always dies (not in the model...) */
-
-          if(dies == YES) /* Replace dead lineage with new one */
+          sum = 0.0;
+          for(i=0;i<curr_pop_size;++i) sum += parent_prob[i];
+          
+          if(sum < 1.E-100)
+            {
+              sum = curr_pop_size;
+              for(i=0;i<curr_pop_size;++i) parent_prob[i] = 1.;
+            }
+          
+          for(i=0;i<curr_pop_size;++i) parent_prob[i] /= sum;
+          
+          
+          
+          parent_id = Sample_i_With_Proba_pi(parent_prob,curr_pop_size);
+          new_disk->ldsk = disk->ldsk_a[parent_id];
+                    
+          Free(parent_prob);
+          
+          
+          /* Which lineages survive that event? */
+          n_survive = 0;
+          for(i=0;i<curr_pop_size;++i)
+            {
+              lx = disk->ldsk_a[i]->coord->lonlat[0];
+              ly = disk->ldsk_a[i]->coord->lonlat[1];
+              
+              prob_death = 0.0;
+              switch(mmod->name)
+                {
+                case PHYREX_UNIFORM:
+                  {
+                    if(PHYREX_Is_In_Disk(disk->ldsk_a[i]->coord,new_disk,mmod) == YES)
+                      prob_death = mmod->mu;
+                    break;
+                  }
+                case PHYREX_NORMAL:
+                  {
+                    prob_death = log(mmod->mu);
+                    prob_death += -pow(lx - cx,2)/(2.*pow(mmod->rad,2));
+                    prob_death += -pow(ly - cy,2)/(2.*pow(mmod->rad,2));
+                    prob_death = exp(prob_death);
+                    break;
+                  }
+                }
+              
+              dies = NO;
+              if(Uni() < prob_death) dies = YES;
+              
+              if(dies == NO)
+                {
+                  if(n_survive == 0) new_disk->ldsk_a = (t_ldsk **)mCalloc(1,sizeof(t_ldsk *));
+                  else new_disk->ldsk_a = (t_ldsk **)mRealloc(new_disk->ldsk_a,n_survive+1,sizeof(t_ldsk *));              
+                  new_disk->ldsk_a[n_survive] = disk->ldsk_a[i];
+                  n_survive++;
+                }
+            }
+          
+          /* PhyML_Printf("\n. n_survive: %d",n_survive); */
+          
+          /* Offspring */
+          /* How many? */
+          phydbl r = mmod->rad;
+          phydbl u = mmod->mu;
+          phydbl rho = mmod->rho;
+          phydbl mean =
+            0.5*PI*rho*u*r*r*
+            (erf(0.5*sqrt(2.)/r*(cy-0.0))*erf(0.5*sqrt(2.)/r*(cx-0.0)) +
+             erf(0.5*sqrt(2.)/r*(cy-h))*erf(0.5*sqrt(2.)/r*(cx-w)) -
+             erf(0.5*sqrt(2.)/r*(cy-0.0))*erf(0.5*sqrt(2.)/r*(cx-w)) -
+             erf(0.5*sqrt(2.)/r*(cy-h))*erf(0.5*sqrt(2.)/r*(cx-0.0)));
+          
+          n_offspring = Rpois(mean);
+          
+          new_disk->n_ldsk_a = n_survive + n_offspring;
+          
+          /* PhyML_Printf("\n. n_offspring: %d",n_offspring); */
+          
+          /* Where */
+          for(i=0;i<n_offspring;++i)
             {
-
               /* New lindisk */
               new_ldsk = PHYREX_Make_Lindisk_Node(n_dim);
-              PHYREX_Init_Lindisk_Node(new_ldsk,disk,n_dim);
-          
-              /* Select new location for new lineage replacing the one that just died  */
+              PHYREX_Init_Lindisk_Node(new_ldsk,new_disk,n_dim);
+              Push_Bottom_Linked_List(new_ldsk,&ldsk_list,NO);
+              
+              if(new_disk->ldsk_a == NULL) new_disk->ldsk_a = (t_ldsk **)mCalloc(n_survive+1,sizeof(t_ldsk *));
+              else new_disk->ldsk_a = (t_ldsk **)mRealloc(new_disk->ldsk_a,n_survive+i+1,sizeof(t_ldsk *));              
+              
+              new_disk->ldsk_a[n_survive+i] = new_ldsk;
+              
+              
+              /* Generate new location */
               switch(mmod->name)
                 {
-                case PHYREX_UNIFORM: { PHYREX_Runif_Rectangle_Overlap(new_ldsk,disk,mmod); break; }
-                case PHYREX_NORMAL:  { PHYREX_Rnorm_Trunc(new_ldsk,disk,mmod); break; }
+                case PHYREX_UNIFORM: { PHYREX_Runif_Rectangle_Overlap(new_ldsk,new_disk,mmod); break; }
+                case PHYREX_NORMAL:  { PHYREX_Rnorm_Trunc(new_ldsk,new_disk,mmod); break; }
                 }
-
+              
               /* Connect to parent */
-              new_ldsk->prev = disk->ldsk;
-
-              /* Replace dead individual (thus, number of birth == number of death) */
-              if(i != parent_id) Free_Ldisk(ldsk_a_pop[i]);
-              ldsk_a_pop[i] = new_ldsk;
+              new_ldsk->prev = disk->ldsk_a[parent_id];          
             }
         }
+      else
+        {
+          new_disk->time = t_sim;
+          new_disk->n_ldsk_a = disk->n_ldsk_a;
+          new_disk->ldsk_a = (t_ldsk **)mCalloc(curr_pop_size,sizeof(t_ldsk *));
+          for(i=0;i<curr_pop_size;++i) new_disk->ldsk_a[i] = disk->ldsk_a[i];
+        }
+      
 
-      disk->next = PHYREX_Make_Disk_Event(n_dim,n_otu);
-      PHYREX_Init_Disk_Event(disk->next,n_dim,NULL);
-      disk->next->prev = disk;      
-      disk = disk->next;
-      n_disk++;
-
+      disk = new_disk;
+          
+      /* printf("\n. pop size: %6d # of events: %6d",disk->n_ldsk_a,n_disk); */
+    }
+  while(disk->time < t_sim);
 
-      /* Time of next event */
-      dt_dsk = Rexp(mmod->lbda);
-      curr_t += dt_dsk;
+  
+  /* Dispersal stuff */
+  /* {     */
+  /*   phydbl T = disk->time; // total simulation time (in calendar unit) */
+  /*   t_ldsk *dum_ldsk = disk->ldsk_a[Rand_Int(0,disk->n_ldsk_a-1)]; */
+  /*   t_dsk *dum_dsk = disk; */
+  /*   phydbl s = w*h; // area */
+  /*   printf("\n. s: %f",s); fflush(NULL); */
+  /*   phydbl gentime = 1./(2.*PI*mmod->rad*mmod->rad*mmod->mu*mmod->lbda/s); */
+  /*   phydbl ssq = 0.0; */
+  /*   phydbl curr_pos,prev_pos; */
+  /*   int curr_gen,prev_gen,nhits=0; */
+  /*   prev_pos = dum_ldsk->coord->lonlat[0]; */
+  /*   curr_pos = prev_pos; */
+  /*   curr_gen = prev_gen = 1; */
+  /*   do */
+  /*     {       */
+  /*       curr_gen  = 1 + (int)(dum_dsk->time-T)/gentime; */
+  /*       curr_pos  = dum_ldsk->coord->lonlat[0]; */
+        
+  /*       if(dum_ldsk->disk == dum_dsk) // lineage was born at that time */
+  /*         { */
+  /*           dum_ldsk = dum_ldsk->prev; // jump to parent */
+  /*           nhits++; */
+  /*         } */
+        
+  /*       if(curr_gen != prev_gen) */
+  /*         { */
+  /*           ssq += pow(curr_pos-prev_pos,2); */
+  /*           prev_pos = curr_pos; */
+  /*           prev_gen = curr_gen; */
+  /*         } */
+        
+  /*       dum_dsk = dum_dsk->prev; */
+  /*     } */
+  /*   while(dum_dsk); */
+    
+  /*   PhyML_Printf("\n # var T nhits T/nhits gentime sigsq theta u lambda"); */
+  /*   PhyML_Printf("\n a at z %G %f %d %f %f %f %f %f %f", */
+  /*                (1./(T/gentime))*ssq, */
+  /*                T, */
+  /*                nhits, */
+  /*                T/nhits, */
+  /*                gentime, */
+  /*                4*pow(mmod->rad,4)*mmod->lbda/s*PI*mmod->mu*gentime, */
+  /*                mmod->rad, */
+  /*                mmod->mu, */
+  /*                mmod->lbda); */
+    
+  /*   Exit("\n"); */
+  /* } */
+  
 
-      disk->time = curr_t;
-      disk->mmod = mmod;
-    }
-  while(n_disk < 100000);
+  /* /\* Coalescence stuff *\/ */
+  /* { */
+  /*   t_ldsk *lin1, *lin2; */
+  /*   int n_evts,have_coal,coal_evt; */
+  /*   phydbl T,t; */
+
+  /*   /\* Selection of two lineages at random *\/ */
+  /*   while(disk->next) disk = disk->next; */
+  /*   permut = Permutate(disk->n_ldsk_a); */
+  /*   lin1 = disk->ldsk_a[permut[0]]; */
+  /*   lin2 = disk->ldsk_a[permut[1]]; */
+  /*   Free(permut); */
+    
+  /*   printf("\n. disk->time-lin1->prev->time: %f",disk->time-lin1->prev->disk->time); */
+  /*   printf("\n. disk->time-lin2->prev->time: %f",disk->time-lin2->prev->disk->time); */
+    
+  /*   /\* Go back in time *\/ */
+  /*   curr_t = 0.0; */
+  /*   n_evts = 0; */
+  /*   coal_evt = 0; */
+  /*   have_coal = 0; */
+  /*   T = disk->time; */
+  /*   do */
+  /*     { */
+  /*       if(disk->ldsk) n_evts++; */
+
+  /*       if(disk->ldsk && disk->ldsk == lin1->prev) lin1 = lin1->prev; */
+  /*       if(disk->ldsk && disk->ldsk == lin2->prev) lin2 = lin2->prev; */
+        
+  /*       if(lin1 == lin2) */
+  /*         { */
+  /*           have_coal = 1; */
+  /*           coal_evt  = n_evts; */
+  /*           break; */
+  /*         } */
+        
+  /*       disk = disk->prev; */
+  /*       t=disk?disk->time:0.0; */
+  /*       curr_t = (T-t); */
+               
+  /*       /\* printf("\n>>> coal %d n_evts: %d curr_t: %f disk->time: %f T: %f one_gen: %f", *\/ */
+  /*       /\*        have_coal, *\/ */
+  /*       /\*        n_evts, *\/ */
+  /*       /\*        curr_t, *\/ */
+  /*       /\*        t, *\/ */
+  /*       /\*        T, *\/ */
+  /*       /\*        one_gen); *\/ */
+  /*     } */
+  /*   /\* while(disk && n_evts < 2); *\/ */
+  /*   while(disk && curr_t < one_gen); */
+
+  /*   PhyML_Printf("\n. @ coal : %d %d %f",have_coal,coal_evt,curr_t); */
+  /*   /\* Exit("\n"); *\/ */
+  /* } */
 
-  For(i,pop_size) ldsk_a_pop[i]->disk = disk;
 
+  
+  
   /* Allocate coordinates for all the tips first (will grow afterwards) */
   ldsk_a_samp = (t_ldsk **)mCalloc(n_otu,sizeof(t_ldsk *));
   ldsk_a_tips = (t_ldsk **)mCalloc(n_otu,sizeof(t_ldsk *));
   ldsk_a_tmp  = (t_ldsk **)mCalloc(n_otu,sizeof(t_ldsk *));
 
-  /* Sample individuals (take the first n_otu ldsk within ldsk_a_pop array) */  
-  /* For(i,n_otu) ldsk_a_samp[i] = ldsk_a_pop[i]; */
+  while(disk->next) disk = disk->next;
+  ldsk_a_pop = disk->ldsk_a;
 
+  
+  /* /\* Sample n_otu individuals uniformly at random... *\/   */
+  /* while(disk->next) disk = disk->next;  */
+  /* permut = Permutate(disk->n_ldsk_a); */
+  /* for(i=0;i<n_otu;i++) ldsk_a_samp[i] = ldsk_a_pop[permut[i]]; */
+  /* Free(permut); */
+  /* n_sampled_demes = 1; */
+  
+  
+  /* ... or take samples in random polygons */
   n_poly = n_sites;
+  is_sampled = (short int *)mCalloc(n_poly,sizeof(short int));
 
   do
     {
       poly = (t_poly **)mCalloc(n_poly,sizeof(t_poly *));
-      For(i,n_poly) poly[i] = Rpoly(3); /* triangles */
-      For(i,n_poly)
-        {      
-          For(j,poly[i]->n_poly_vert) 
+      for(i=0;i<n_poly;++i) poly[i] = Rpoly(3); /* triangles */
+      for(i=0;i<n_poly;++i)
+        {
+          for(j=0;j<poly[i]->n_poly_vert;++j)
             {
               poly[i]->poly_vert[j]->lonlat[0] *= mmod->lim->lonlat[0]*0.5;
               poly[i]->poly_vert[j]->lonlat[1] *= mmod->lim->lonlat[1]*0.5;
@@ -765,7 +1180,7 @@ phydbl PHYREX_Simulate_Forward_Core(int n_sites, t_tree *tree)
           
           max_x = 0.0;
           max_y = 0.0;
-          For(j,poly[i]->n_poly_vert) 
+          for(j=0;j<poly[i]->n_poly_vert;++j)
             {
               if(poly[i]->poly_vert[j]->lonlat[0] > max_x) max_x = poly[i]->poly_vert[j]->lonlat[0];
               if(poly[i]->poly_vert[j]->lonlat[1] > max_y) max_y = poly[i]->poly_vert[j]->lonlat[1];
@@ -774,42 +1189,47 @@ phydbl PHYREX_Simulate_Forward_Core(int n_sites, t_tree *tree)
           trans_x = Uni()*(mmod->lim->lonlat[0] - max_x);
           trans_y = Uni()*(mmod->lim->lonlat[1] - max_y);
           
-          For(j,poly[i]->n_poly_vert) 
+          for(j=0;j<poly[i]->n_poly_vert;++j)
             {
               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=0;i<n_otu;++i) ldsk_a_samp[i] = NULL;
 
-      permut = Permutate(n_poly);
+      for(i=0;i<n_poly;++i) is_sampled[i] = NO;
 
+      permut = Permutate(n_poly);
+  
       sample_size = 0;
-      For(i,pop_size)
+      for(i=0;i<curr_pop_size;++i)
         {
-          For(j,n_poly)
+          for(j=0;j<n_poly;++j)
             {
               if(Is_In_Polygon(ldsk_a_pop[i]->coord,poly[permut[j]]) == YES)
                 {
                   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,23 +1237,43 @@ 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)
+      if(i == curr_pop_size)
         {
-          PhyML_Printf("\n== Not enough individuals in polygon(s) (only %d found).",sample_size);
+          for(j=0;j<n_poly;j++) 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__);       */
         }
-      else break;    
+      else break;
     }
   while(1);
-      
-  For(i,n_otu) ldsk_a_tips[i] = ldsk_a_samp[i];
-  
+
+  n_sampled_demes = 0;
+  for(i=0;i<n_poly;++i) if(is_sampled[i] == YES) n_sampled_demes++;
+
+  for(i=0;i<n_otu;++i) ldsk_a_tips[i] = ldsk_a_samp[i];
+
+  area = Make_Sarea(n_sampled_demes);
+  area->n_poly = n_sampled_demes;
+  n_sampled_demes = 0;
+  for(i=0;i<n_poly;++i) if(is_sampled[i] == YES) area->a_poly[n_sampled_demes++] = poly[i];
+
+
+  for(i=0;i<area->n_poly;++i) 
+    {
+      /* PhyML_Printf("\n@ Poly %3d area = %f",i,Area_Of_Poly_Monte_Carlo(area->a_poly[i],mmod->lim)); */
+
+      for(j=0;j<area->a_poly[i]->n_poly_vert;++j)
+        {
+          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;
@@ -842,20 +1282,16 @@ phydbl PHYREX_Simulate_Forward_Core(int n_sites, t_tree *tree)
   disk->n_ldsk_a         = n_otu;  
 
   int n_discs = 0;
-
+  
   n_lineages = n_otu;
   do
-    {      
-      /* printf("\n [%s %f]",disk->id,disk->time); */
-
+    {
       n_remain = 0;
-      For(i,n_lineages) 
+      for(i=0;i<n_lineages;++i) 
         {
-          /* printf(" %s",ldsk_a_samp[i]->coord->id); */
 
           if((disk->prev->ldsk != NULL) && (disk->prev->ldsk == ldsk_a_samp[i]->prev)) /* Coalescent event is sampled */
             {
-              /* printf("*"); */
               PHYREX_Make_Lindisk_Next(disk->prev->ldsk);
               disk->prev->ldsk->next[disk->prev->ldsk->n_next-1] = ldsk_a_samp[i];
             }
@@ -866,7 +1302,7 @@ phydbl PHYREX_Simulate_Forward_Core(int n_sites, t_tree *tree)
             }
         }
 
-      For(i,n_remain) ldsk_a_samp[i] = ldsk_a_tmp[i];
+      for(i=0;i<n_remain;i++) ldsk_a_samp[i] = ldsk_a_tmp[i];
       if((disk->prev->ldsk != NULL) && (disk->prev->ldsk->n_next > 0)) ldsk_a_samp[i] = disk->prev->ldsk;
 
       if((disk->prev->ldsk != NULL) && (disk->prev->ldsk->n_next > 0))
@@ -904,7 +1340,8 @@ phydbl PHYREX_Simulate_Forward_Core(int n_sites, t_tree *tree)
     }
   while(n_lineages > 1);
 
-  /* For(i,n_otu) printf("\n> %s",tree->disk->ldsk_a[i]->coord->id); */
+  
+  /* for(i=0;i<n_otu;i++) printf("\n> %s",tree->disk->ldsk_a[i]->coord->id); */
 
   disk->prev = NULL;
 
@@ -921,7 +1358,7 @@ phydbl PHYREX_Simulate_Forward_Core(int n_sites, t_tree *tree)
   Free(ldsk_a_tmp);
   Free(ldsk_a_samp);
   Free(ldsk_a_pop);
-  Free(parent_prob);
+  Free(is_sampled);
   
   /* PHYREX_Print_Struct('#',tree); */
   /* Exit("\n"); */
@@ -943,7 +1380,7 @@ int PHYREX_Is_In_Disk(t_geo_coord *coord, t_dsk *disk, t_phyrex_mod *mmod)
 
   if(mmod->name == PHYREX_UNIFORM)
     {
-      For(i,disk->centr->dim)
+      for(i=0;i<disk->centr->dim;i++)
         {
           if(FABS(coord->lonlat[i] - disk->centr->lonlat[i]) > disk->mmod->rad + 1.E-20)
             {
@@ -973,7 +1410,7 @@ phydbl PHYREX_Lk(t_tree *tree)
   assert(tree->disk->prev);
   
   tree->mmod->c_lnL = 0.0;
-  log_lbda          = LOG(tree->mmod->lbda);
+  log_lbda          = log(tree->mmod->lbda);
 
   /* TO DO: create a proper PHYREX_LogPost() function */
   tree->mmod->c_lnL += PHYREX_LnPrior_Radius(tree);
@@ -1016,19 +1453,19 @@ phydbl PHYREX_Lk_Core(t_dsk *disk, t_tree *tree)
 
   two_theta_two = 2.*POW(tree->mmod->rad,2);
   lnL           = 0.0;
-  log_mu        = LOG(tree->mmod->mu);
+  log_mu        = log(tree->mmod->mu);
   was_hit       = (disk->ldsk != NULL);
 
-  For(i,disk->n_ldsk_a)
+  for(i=0;i<disk->n_ldsk_a;i++)
     {
       if(PHYREX_Is_In_Ldscape(disk->ldsk_a[i],tree->mmod) == NO) return(UNLIKELY);     
 
       if(was_hit && disk->ldsk_a[i] == disk->ldsk)
         {
-          For(k,disk->ldsk->n_next)
+          for(k=0;k<disk->ldsk->n_next;k++)
             {              
               log_prob_hit = log_mu;
-              For(j,tree->mmod->n_dim)
+              for(j=0;j<tree->mmod->n_dim;j++)
                 log_prob_hit += -POW(disk->ldsk->next[k]->coord->lonlat[j] - disk->centr->lonlat[j],2)/two_theta_two;
 
               lnL += log_prob_hit;
@@ -1037,10 +1474,10 @@ phydbl PHYREX_Lk_Core(t_dsk *disk, t_tree *tree)
       else
         {
           log_prob_hit = log_mu;
-          For(j,tree->mmod->n_dim)
+          for(j=0;j<tree->mmod->n_dim;j++)
             log_prob_hit += -POW(disk->ldsk_a[i]->coord->lonlat[j] - disk->centr->lonlat[j],2)/two_theta_two;
           
-          lnL += LOG(1. - EXP(log_prob_hit));
+          lnL += log(1. - exp(log_prob_hit));
         }
     }
 
@@ -1049,7 +1486,7 @@ phydbl PHYREX_Lk_Core(t_dsk *disk, t_tree *tree)
     {
       err = NO;
       log_dens_coal = 0.0;
-      For(j,tree->mmod->n_dim) log_dens_coal += Log_Dnorm_Trunc(disk->ldsk->coord->lonlat[j],
+      for(j=0;j<tree->mmod->n_dim;j++) log_dens_coal += Log_Dnorm_Trunc(disk->ldsk->coord->lonlat[j],
                                                                 disk->centr->lonlat[j],
                                                                 tree->mmod->rad,
                                                                 0.0,
@@ -1058,7 +1495,7 @@ phydbl PHYREX_Lk_Core(t_dsk *disk, t_tree *tree)
     }
 
   /* Likelihood for the disk center */
-  For(i,disk->mmod->n_dim) lnL -= LOG(tree->mmod->lim->lonlat[i]);
+  for(i=0;i<disk->mmod->n_dim;i++) lnL -= log(tree->mmod->lim->lonlat[i]);
   
   return(lnL);
 }
@@ -1074,7 +1511,7 @@ phydbl PHYREX_Lk_Range(t_dsk *young, t_dsk *old, t_tree *tree)
   assert(young);
   assert(young->next);
   
-  log_lbda = LOG(tree->mmod->lbda);
+  log_lbda = log(tree->mmod->lbda);
 
   lnL  = 0.0;
   disk = young;
@@ -1096,12 +1533,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;
@@ -1117,7 +1554,6 @@ phydbl *PHYREX_MCMC(t_tree *tree)
 
   mcmc->io               = NULL;
   mcmc->is               = NO;
-  mcmc->use_data         = YES;
   mcmc->run              = 0;
   mcmc->chain_len_burnin = 1E+5;
   mcmc->randomize        = YES;
@@ -1134,6 +1570,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=0;i<tree->mmod->samp_area->n_poly;i++) 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 +1599,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 +1618,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=0;i<tree->mmod->samp_area->n_poly;i++) 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;
@@ -1258,17 +1706,16 @@ phydbl *PHYREX_MCMC(t_tree *tree)
                 "tuneRad",
                 "tuneMu");
 
-  For(i,mcmc->n_moves) tree->mcmc->start_ess[i] = YES;
+  for(i=0;i<mcmc->n_moves;i++) 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(mcmc->run > adjust_len) for(i=0;i<mcmc->n_moves;i++) tree->mcmc->adjust_tuning[i] = NO;
 
       if(tree->mmod->c_lnL < UNLIKELY + 0.1)
         {
@@ -1278,7 +1725,7 @@ phydbl *PHYREX_MCMC(t_tree *tree)
 
       u = Uni();
 
-      For(move,tree->mcmc->n_moves) if(tree->mcmc->move_weight[move] > u-1.E-10) break;
+      for(move=0;move<tree->mcmc->n_moves;move++) if(tree->mcmc->move_weight[move] > u-1.E-10) break;
 
       assert(!(move == tree->mcmc->n_moves));
 
@@ -1360,9 +1807,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,27 +1874,30 @@ 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);
           
-          For(i,tree->mcmc->n_moves) if(tree->mcmc->start_ess[i] == YES) MCMC_Update_Effective_Sample_Size(i,tree->mcmc,tree);
-          For(i,tree->mcmc->n_moves) MCMC_Update_Mode(i,tree->mcmc,tree);
+          for(i=0;i<tree->mcmc->n_moves;i++) if(tree->mcmc->start_ess[i] == YES) MCMC_Update_Effective_Sample_Size(i,tree->mcmc,tree);
+          for(i=0;i<tree->mcmc->n_moves;i++) MCMC_Update_Mode(i,tree->mcmc,tree);
 
 
           burnin = (int)(0.5*(tree->mcmc->run / tree->mcmc->sample_interval));
           
           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 +1907,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 +1981,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. && */
@@ -1570,7 +2022,7 @@ void PHYREX_New_Traj(t_dsk *start, t_dsk *end, t_tree *tree)
 
 
 
-  For(i,start->n_ldsk_a)
+  for(i=0;i<start->n_ldsk_a;i++)
     {      
       /* printf("\n<><><>"); */
 
@@ -1625,7 +2077,7 @@ void PHYREX_New_Traj(t_dsk *start, t_dsk *end, t_tree *tree)
             {              
               n_hit_up++;
 
-              For(j,disk->mmod->n_dim)
+              for(j=0;j<disk->mmod->n_dim;j++)
                 {
                   /* min_up = end->ldsk_a[i]->coord->lonlat[j] - n_hit_up * 2. * disk->mmod->rad; */
                   /* min_do = start->ldsk_a[i]->coord->lonlat[j] - (n_hit_tot - n_hit_up) * 2. * disk->mmod->rad; */
@@ -1654,7 +2106,7 @@ void PHYREX_New_Traj(t_dsk *start, t_dsk *end, t_tree *tree)
         {
           if(disk->ldsk_a[i]->is_hit == YES)
             {
-              /* For(j,disk->mmod->n_dim) */
+              /* for(j=0;j<disk->mmod->n_dim;j++) */
                 /* disk->ldsk_a[i]->prev->coord->lonlat[j] =  */
                 /* Uni()* */
                 /* (disk->ldsk_a[i]->prev->max_coord->lonlat[j]  - */
@@ -1663,7 +2115,7 @@ void PHYREX_New_Traj(t_dsk *start, t_dsk *end, t_tree *tree)
             }
           else
             {
-              For(j,disk->mmod->n_dim)
+              for(j=0;j<disk->mmod->n_dim;j++)
                 disk->ldsk_a[i]->prev->coord->lonlat[j] = 
                 disk->ldsk_a[i]->coord->lonlat[j];
             }
@@ -1682,7 +2134,7 @@ void PHYREX_New_Traj(t_dsk *start, t_dsk *end, t_tree *tree)
 
   /* gtk_widget_queue_draw(tree->draw_area); */
   
-  /* For(i,start->n_ldsk_a) */
+  /* for(i=0;i<start->n_ldsk_a;i++) */
   /*   { */
   /*     printf("\n<><><>"); */
   /*     disk = end; */
@@ -1806,7 +2258,7 @@ int PHYREX_One_New_Traj(t_ldsk *y_ldsk, t_ldsk *o_ldsk, int dir_o_y, t_dsk *xtra
 
   /* Minimum number of disks between y_ldsk and o_ldsk */
   min_n_disk = 0;
-  For(i,mmod->n_dim)
+  for(i=0;i<mmod->n_dim;i++)
     {
       /* PhyML_Printf("\n# y_ldsk %s : %f o_ldsk->disk->centr: %f rad: %f", */
       /*              y_ldsk->coord->id, */
@@ -1843,21 +2295,21 @@ int PHYREX_One_New_Traj(t_ldsk *y_ldsk, t_ldsk *o_ldsk, int dir_o_y, t_dsk *xtra
     {
       /* Make new disks to create a new path between ldsk_left and ldsk_up */
       disk_new = (t_dsk **)mCalloc(n_new_disk,sizeof(t_dsk *));
-      For(i,n_new_disk-1)  disk_new[i] = PHYREX_Make_Disk_Event(mmod->n_dim,tree->n_otu);
+      for(i=0;i<n_new_disk-1;i++)  disk_new[i] = PHYREX_Make_Disk_Event(mmod->n_dim,tree->n_otu);
       if(xtra_dsk != NULL) disk_new[n_new_disk-1] = xtra_dsk;
       else                 disk_new[n_new_disk-1] = PHYREX_Make_Disk_Event(mmod->n_dim,tree->n_otu);
 
-      For(i,n_new_disk)  PHYREX_Init_Disk_Event(disk_new[i],mmod->n_dim,mmod);
+      for(i=0;i<n_new_disk;i++)  PHYREX_Init_Disk_Event(disk_new[i],mmod->n_dim,mmod);
 
       /* Times of these new disks. If xtra_dsk != NULL, then make sure you do not */
       /* reset the time of that disk  */
       n = (xtra_dsk != NULL) ? (n_new_disk-1) : (n_new_disk);
-      For(i,n)
+      for(i=0;i<n;i++)
         disk_new[i]->time =
         Uni()*(y_ldsk->disk->time - o_ldsk->disk->time) + o_ldsk->disk->time;       
      
       /* Insert these events */
-      For(i,n_new_disk)
+      for(i=0;i<n_new_disk;i++)
         {
           assert(!tree->disk->next);
           disk = tree->disk;
@@ -1865,13 +2317,13 @@ int PHYREX_One_New_Traj(t_ldsk *y_ldsk, t_ldsk *o_ldsk, int dir_o_y, t_dsk *xtra
           PHYREX_Insert_Disk(disk_new[i],tree);
         }
             
-      /* For(i,n_new_disk) */
+      /* for(i=0;i<n_new_disk;i++) */
       /*   { */
       /*     printf("\n> disk_new: %f [%s]",disk_new[i]->time,disk_new[i]->id); fflush(NULL); */
       /*   } */
       
       /* Add new lindisks to the new disk events */
-      For(i,n_new_disk)
+      for(i=0;i<n_new_disk;i++)
         {
           disk_new[i]->ldsk = PHYREX_Make_Lindisk_Node(tree->mmod->n_dim);
           PHYREX_Init_Lindisk_Node(disk_new[i]->ldsk,disk_new[i],tree->mmod->n_dim);
@@ -1939,7 +2391,7 @@ void PHYREX_One_New_Traj_Given_Disk(t_ldsk *y_ldsk, t_ldsk *o_ldsk, t_tree *tree
       PHYREX_Store_Geo_Coord(ldsk->coord);
       PHYREX_Store_Geo_Coord(ldsk->disk->centr);
 
-      For(i,tree->mmod->n_dim)
+      for(i=0;i<tree->mmod->n_dim;i++)
         {
           min = 
             MAX(0.0,
@@ -1959,7 +2411,7 @@ void PHYREX_One_New_Traj_Given_Disk(t_ldsk *y_ldsk, t_ldsk *o_ldsk, t_tree *tree
 
       /* New coordinate for the centre of the corresponding disk event */
       PHYREX_Get_Min_Max_Disk_Given_Ldsk(ldsk->disk,&min_disk_coord,&max_disk_coord,tree);
-      For(i,tree->mmod->n_dim) ldsk->disk->centr->lonlat[i] = Uni()*(max_disk_coord[i] - min_disk_coord[i]) + min_disk_coord[i];
+      for(i=0;i<tree->mmod->n_dim;i++) ldsk->disk->centr->lonlat[i] = Uni()*(max_disk_coord[i] - min_disk_coord[i]) + min_disk_coord[i];
       Free(min_disk_coord);
       Free(max_disk_coord);
 
@@ -2006,7 +2458,7 @@ phydbl PHYREX_Uniform_Path_Density(t_ldsk *y_ldsk, t_ldsk *o_ldsk, t_tree *tree)
           continue;
         }
       
-      For(i,ldsk->disk->mmod->n_dim)
+      for(i=0;i<ldsk->disk->mmod->n_dim;i++)
         {
           min = 
             MAX(0.0,
@@ -2020,11 +2472,11 @@ phydbl PHYREX_Uniform_Path_Density(t_ldsk *y_ldsk, t_ldsk *o_ldsk, t_tree *tree)
 
           assert(!(max < min));
 
-          log_dens -= LOG(max - min);          
+          log_dens -= log(max - min);          
         }
 
       PHYREX_Get_Min_Max_Disk_Given_Ldsk(ldsk->disk,&min_disk_coord,&max_disk_coord,tree);
-      For(i,tree->mmod->n_dim) log_dens -= LOG(max_disk_coord[i] - min_disk_coord[i]);
+      for(i=0;i<tree->mmod->n_dim;i++) log_dens -= log(max_disk_coord[i] - min_disk_coord[i]);
       Free(min_disk_coord);
       Free(max_disk_coord);
 
@@ -2057,7 +2509,7 @@ int PHYREX_Get_Next_Direction(t_ldsk *young, t_ldsk *old)
   if(young->prev == old)
     {
       int i;
-      For(i,old->n_next) if(old->next[i] == young) return i;
+      for(i=0;i<old->n_next;i++) if(old->next[i] == young) return i;
     }
   else
     {
@@ -2109,7 +2561,7 @@ int PHYREX_Get_Next_Direction(t_ldsk *young, t_ldsk *old)
 /*   else if(ldsk->disk->time < time) */
 /*     { */
 /*       int i; */
-/*       For(i,ldsk->n_next) */
+/*       for(i=0;i<ldsk->n_next;i++) */
 /*         PHYREX_Update_Lindisk_List_Pre(ldsk->next[i],time,list,pos);     */
 /*     } */
 /*   else Generic_Exit(__FILE__,__LINE__,__FUNCTION__); */
@@ -2146,10 +2598,10 @@ void PHYREX_Update_Lindisk_List_Core(t_dsk *disk, t_tree *tree)
 
   if(!disk->next) return;
 
-  For(i,tree->n_otu) disk->ldsk_a[i] = NULL;
+  for(i=0;i<tree->n_otu;++i) disk->ldsk_a[i] = NULL;
 
   disk->n_ldsk_a = 0;
-  For(i,disk->next->n_ldsk_a)
+  for(i=0;i<disk->next->n_ldsk_a;++i)
     {
       if(disk->next->ldsk_a[i]->prev != disk->ldsk)
         {
@@ -2158,16 +2610,15 @@ void PHYREX_Update_Lindisk_List_Core(t_dsk *disk, t_tree *tree)
         }
     }
   
-  if(disk->ldsk) 
-    {
-      disk->ldsk_a[disk->n_ldsk_a] = disk->ldsk;
-      disk->n_ldsk_a++;          
-    }
+  /* if(disk->ldsk)  */
+  /*   { */
+  /*     disk->ldsk_a[disk->n_ldsk_a] = disk->ldsk; */
+  /*     disk->n_ldsk_a++;           */
+  /*   } */
   
-  /* if(disk->n_ldsk_a == 0 || disk->n_ldsk_a > tree->n_otu || (!disk->prev && disk->n_ldsk_a != 1))  */
-  if(disk->n_ldsk_a == 0 || disk->n_ldsk_a > tree->n_otu) 
+  if(disk->n_ldsk_a > tree->n_otu) 
     {
-      PhyML_Printf("\n== disk %s %d %s",disk->id, disk->n_ldsk_a, disk->ldsk?disk->ldsk->coord->id:"xx");
+      PhyML_Printf("\n== disk: %s next: %s disk->n_ldsk_a: %d coord: %s",disk->id, disk->next->id, disk->n_ldsk_a, disk->ldsk?disk->ldsk->coord->id:"xx");
       Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
     }
 }
@@ -2187,7 +2638,7 @@ void PHYREX_Connect_Ldsk_Given_Disk(t_dsk **disk, int n_disk, t_ldsk *y_ldsk, t_
   t_dsk *disk_tmp;
 
   /* Sort these events by ascending order of their times */
-  For(i,n_disk-1)
+  for(i=0;i<n_disk-1;i++)
     {
       for(j=i+1;j<n_disk;j++)
         {
@@ -2201,7 +2652,7 @@ void PHYREX_Connect_Ldsk_Given_Disk(t_dsk **disk, int n_disk, t_ldsk *y_ldsk, t_
     }
 
 
-  For(i,n_disk)
+  for(i=0;i<n_disk;i++)
     {
       if(!i)
         {
@@ -2244,11 +2695,11 @@ void PHYREX_Print_Struct(char sign, t_tree *tree)
              disk->time,disk->ldsk?disk->ldsk->coord->id:NULL,
              disk->ldsk?disk->ldsk->n_next:-1,
              tree->mmod->rad); fflush(NULL);
-      For(j,tree->mmod->n_dim) PhyML_Printf(" %f",disk->centr->lonlat[j]);
+      for(j=0;j<tree->mmod->n_dim;j++) PhyML_Printf(" %f",disk->centr->lonlat[j]);
       fflush(NULL);
 
 
-      For(i,disk->n_ldsk_a)
+      for(i=0;i<disk->n_ldsk_a;i++)
         {
           ldisk = disk->ldsk_a[i];
 
@@ -2258,7 +2709,7 @@ void PHYREX_Print_Struct(char sign, t_tree *tree)
                        ldisk->prev ? ldisk->prev->coord->id : NULL);
           fflush(NULL);
           
-          For(j,tree->mmod->n_dim) 
+          for(j=0;j<tree->mmod->n_dim;j++) 
             {
               PhyML_Printf(" %f",ldisk->coord->lonlat[j]);
               fflush(NULL);
@@ -2302,12 +2753,12 @@ void PHYREX_Check_Struct(t_tree *tree)
       /* PHYREX_Update_Lindisk_List(disk->time,disk->ldsk_a,&(disk->n_ldsk_a),disk); */
       PHYREX_Update_Lindisk_List(tree);
 
-      For(i,disk->n_ldsk_a)
+      for(i=0;i<disk->n_ldsk_a;i++)
         {
           ldisk = disk->ldsk_a[i];
           if(ldisk->prev != NULL)
             {
-              For(j,tree->mmod->n_dim)
+              for(j=0;j<tree->mmod->n_dim;j++)
                 {
                   if(FABS(ldisk->coord->lonlat[j] - 
                           ldisk->prev->coord->lonlat[j]) > 2.*tree->mmod->rad)
@@ -2338,7 +2789,7 @@ void PHYREX_Store_Geo_Coord(t_geo_coord *t)
 {
   int i;
 
-  For(i,t->dim) t->cpy->lonlat[i] = t->lonlat[i];  
+  for(i=0;i<t->dim;i++) t->cpy->lonlat[i] = t->lonlat[i];  
   t->cpy->dim = t->dim;
   strcpy(t->cpy->id,t->id);
 }
@@ -2351,7 +2802,7 @@ void PHYREX_Restore_Geo_Coord(t_geo_coord *t)
 {
   int i;
 
-  For(i,t->dim) t->lonlat[i] = t->cpy->lonlat[i];  
+  for(i=0;i<t->dim;i++) t->lonlat[i] = t->cpy->lonlat[i];  
   t->dim = t->cpy->dim;
   strcpy(t->id,t->cpy->id);
 }
@@ -2438,14 +2889,14 @@ phydbl PHYREX_Log_Dunif_Rectangle_Overlap(t_ldsk *ldsk, t_dsk *disk, t_phyrex_mo
 
 
   /* l = main_mass / (.5*(1.-main_mass)*(up - down)); */
-  /* if(ldsk->coord->lonlat[0] < down)    log_dens += LOG(.5*(1.-main_mass)) + LOG(l) - l*(down - ldsk->coord->lonlat[0]); */
-  /* else if(ldsk->coord->lonlat[0] > up) log_dens += LOG(.5*(1.-main_mass)) + LOG(l) - l*(ldsk->coord->lonlat[0] - up); */
-  /* else log_dens += LOG(main_mass) - LOG(up - down); */
+  /* if(ldsk->coord->lonlat[0] < down)    log_dens += log(.5*(1.-main_mass)) + log(l) - l*(down - ldsk->coord->lonlat[0]); */
+  /* else if(ldsk->coord->lonlat[0] > up) log_dens += log(.5*(1.-main_mass)) + log(l) - l*(ldsk->coord->lonlat[0] - up); */
+  /* else log_dens += log(main_mass) - log(up - down); */
 
   /* l = main_mass / (.5*(1.-main_mass)*(rght - left)); */
-  /* if(ldsk->coord->lonlat[1] < left)      log_dens += LOG(.5*(1.-main_mass)) + LOG(l) - l*(left - ldsk->coord->lonlat[1]); */
-  /* else if(ldsk->coord->lonlat[1] > rght) log_dens += LOG(.5*(1.-main_mass)) + LOG(l) - l*(ldsk->coord->lonlat[1] - rght); */
-  /* else log_dens += LOG(main_mass) - LOG(rght - left); */
+  /* if(ldsk->coord->lonlat[1] < left)      log_dens += log(.5*(1.-main_mass)) + log(l) - l*(left - ldsk->coord->lonlat[1]); */
+  /* else if(ldsk->coord->lonlat[1] > rght) log_dens += log(.5*(1.-main_mass)) + log(l) - l*(ldsk->coord->lonlat[1] - rght); */
+  /* else log_dens += log(main_mass) - log(rght - left); */
 
 
   if(ldsk->coord->lonlat[0] < down)  return UNLIKELY;
@@ -2453,7 +2904,7 @@ phydbl PHYREX_Log_Dunif_Rectangle_Overlap(t_ldsk *ldsk, t_dsk *disk, t_phyrex_mo
   if(ldsk->coord->lonlat[1] < left)  return UNLIKELY;
   if(ldsk->coord->lonlat[1] > rght)  return UNLIKELY;
 
-  log_dens = -LOG(up-down)-LOG(rght-left);
+  log_dens = -log(up-down)-log(rght-left);
 
   return(log_dens);
 }
@@ -2480,7 +2931,7 @@ phydbl PHYREX_Runif_Rectangle_Overlap(t_ldsk *ldsk, t_dsk *disk, t_phyrex_mod *m
   /*        disk->centr->lonlat[1], */
   /*        mmod->rad, */
   /*        up,down,rght,left); */
-  return(LOG(up-down)+LOG(rght-left));
+  return(log(up-down)+log(rght-left));
 }
  
 /*////////////////////////////////////////////////////////////
@@ -2521,13 +2972,13 @@ phydbl PHYREX_LnPrior_Lbda(t_tree *tree)
   if(tree->mmod->lbda > tree->mmod->max_lbda) return UNLIKELY;
 
   /* tree->mmod->c_ln_prior_lbda = */
-  /*   LOG(tree->mmod->prior_param_lbda) - */
+  /*   log(tree->mmod->prior_param_lbda) - */
   /*   tree->mmod->prior_param_lbda*tree->mmod->lbda; */
 
-  /* tree->mmod->c_ln_prior_lbda -= LOG(EXP(-tree->mmod->prior_param_lbda*tree->mmod->min_lbda)- */
-  /*                                    EXP(-tree->mmod->prior_param_lbda*tree->mmod->max_lbda)); */
+  /* tree->mmod->c_ln_prior_lbda -= log(exp(-tree->mmod->prior_param_lbda*tree->mmod->min_lbda)- */
+  /*                                    exp(-tree->mmod->prior_param_lbda*tree->mmod->max_lbda)); */
 
-  tree->mmod->c_ln_prior_lbda = -LOG(tree->mmod->max_lbda - tree->mmod->min_lbda);;
+  tree->mmod->c_ln_prior_lbda = -log(tree->mmod->max_lbda - tree->mmod->min_lbda);;
 
   return(tree->mmod->c_ln_prior_lbda);
 }
@@ -2540,9 +2991,9 @@ phydbl PHYREX_LnPrior_Mu(t_tree *tree)
   if(tree->mmod->mu < tree->mmod->min_mu) return UNLIKELY;
   if(tree->mmod->mu > tree->mmod->max_mu) return UNLIKELY;
 
-  tree->mmod->c_ln_prior_mu = -LOG(tree->mmod->max_mu - tree->mmod->min_mu);
+  tree->mmod->c_ln_prior_mu = -log(tree->mmod->max_mu - tree->mmod->min_mu);
 
-  /* tree->mmod->c_ln_prior_mu = -2.*LOG(tree->mmod->mu); */
+  /* tree->mmod->c_ln_prior_mu = -2.*log(tree->mmod->mu); */
 
   return(tree->mmod->c_ln_prior_mu);
 }
@@ -2556,13 +3007,13 @@ phydbl PHYREX_LnPrior_Radius(t_tree *tree)
   if(tree->mmod->rad > tree->mmod->max_rad) return UNLIKELY;
 
   /* tree->mmod->c_ln_prior_rad = */
-  /*   LOG(tree->mmod->prior_param_rad) - */
+  /*   log(tree->mmod->prior_param_rad) - */
   /*   tree->mmod->prior_param_rad*tree->mmod->rad; */
 
-  /* tree->mmod->c_ln_prior_rad -= LOG(EXP(-tree->mmod->prior_param_lbda*tree->mmod->min_rad)- */
-  /*                                   EXP(-tree->mmod->prior_param_lbda*tree->mmod->max_rad)); */
+  /* tree->mmod->c_ln_prior_rad -= log(exp(-tree->mmod->prior_param_lbda*tree->mmod->min_rad)- */
+  /*                                   exp(-tree->mmod->prior_param_lbda*tree->mmod->max_rad)); */
 
-  tree->mmod->c_ln_prior_rad = -LOG(tree->mmod->max_rad - tree->mmod->min_rad);
+  tree->mmod->c_ln_prior_rad = -log(tree->mmod->max_rad - tree->mmod->min_rad);
 
   return(tree->mmod->c_ln_prior_rad);
 }
@@ -2573,7 +3024,7 @@ phydbl PHYREX_LnPrior_Radius(t_tree *tree)
 phydbl PHYREX_LnPrior_Sigsq(t_tree *tree)
 {
   tree->mmod->c_ln_prior_sigsq = 
-    LOG(tree->mmod->prior_param_sigsq) - 
+    log(tree->mmod->prior_param_sigsq) - 
     tree->mmod->prior_param_sigsq*tree->mmod->sigsq; 
   return(tree->mmod->c_ln_prior_sigsq);
 }
@@ -2593,10 +3044,10 @@ void PHYREX_Initial_Ldsk_Pos(t_tree *tree)
     {
       if(disk->ldsk)
         {
-          For(i,tree->mmod->n_dim)
+          for(i=0;i<tree->mmod->n_dim;i++)
             {
               mean = 0.0;
-              For(j,disk->ldsk->n_next) mean += disk->ldsk->next[j]->coord->lonlat[i];
+              for(j=0;j<disk->ldsk->n_next;j++) mean += disk->ldsk->next[j]->coord->lonlat[i];
               disk->ldsk->coord->lonlat[i] = mean / (phydbl)disk->ldsk->n_next;
             }
         }
@@ -2642,7 +3093,7 @@ void PHYREX_Get_Min_Max_Ldsk_Given_Disk(t_ldsk *ldsk, phydbl **min, phydbl **max
   loc_min = (phydbl *)mCalloc(tree->mmod->n_dim, sizeof(phydbl));
   loc_max = (phydbl *)mCalloc(tree->mmod->n_dim, sizeof(phydbl));
 
-  For(i,tree->mmod->n_dim)
+  for(i=0;i<tree->mmod->n_dim;i++)
     {
       loc_min[i] = ldsk->disk->centr->lonlat[i] - tree->mmod->rad;
       loc_max[i] = ldsk->disk->centr->lonlat[i] + tree->mmod->rad;     
@@ -2677,7 +3128,7 @@ void PHYREX_Get_Min_Max_Disk_Given_Ldsk(t_dsk *disk, phydbl **min, phydbl **max,
 
   if(!disk->ldsk || tree->mmod->name == PHYREX_NORMAL)
     {
-      For(i,tree->mmod->n_dim)
+      for(i=0;i<tree->mmod->n_dim;i++)
         {
           loc_min[i] = 0.0;
           loc_max[i] = tree->mmod->lim->lonlat[i];
@@ -2685,11 +3136,11 @@ void PHYREX_Get_Min_Max_Disk_Given_Ldsk(t_dsk *disk, phydbl **min, phydbl **max,
     }
   else
     {
-      For(i,tree->mmod->n_dim)
+      for(i=0;i<tree->mmod->n_dim;i++)
         {
           tmp_min = +INFINITY;
           tmp_max = -INFINITY;
-          For(j,disk->ldsk->n_next)
+          for(j=0;j<disk->ldsk->n_next;j++)
             {
               if(disk->ldsk->next[j]->coord->lonlat[i] < tmp_min) tmp_min = disk->ldsk->next[j]->coord->lonlat[i];
               if(disk->ldsk->next[j]->coord->lonlat[i] > tmp_max) tmp_max = disk->ldsk->next[j]->coord->lonlat[i];
@@ -2718,7 +3169,7 @@ void PHYREX_Get_Min_Max_Disk_Given_Ldsk(t_dsk *disk, phydbl **min, phydbl **max,
 void PHYREX_Update_Disk_Ldsk_Subtree(t_ldsk *root_ldsk, t_tree *tree)
 {
   int i;  
-  For(i,root_ldsk->n_next) PHYREX_Update_Disk_Ldsk_Subtree_Pre(root_ldsk,root_ldsk->next[i],root_ldsk,tree);
+  for(i=0;i<root_ldsk->n_next;i++) PHYREX_Update_Disk_Ldsk_Subtree_Pre(root_ldsk,root_ldsk->next[i],root_ldsk,tree);
 }
 
 /*////////////////////////////////////////////////////////////
@@ -2748,7 +3199,7 @@ void PHYREX_Update_Disk_Ldsk_Subtree_Pre(t_ldsk *old_ldsk, t_ldsk *young_ldsk, t
 void PHYREX_Restore_Disk_Ldsk_Subtree(t_ldsk *root_ldsk, t_tree *tree)
 {
   int i;  
-  For(i,root_ldsk->n_next) PHYREX_Restore_Disk_Ldsk_Subtree_Pre(root_ldsk,root_ldsk->next[i],tree);
+  for(i=0;i<root_ldsk->n_next;i++) PHYREX_Restore_Disk_Ldsk_Subtree_Pre(root_ldsk,root_ldsk->next[i],tree);
 }
 
 /*////////////////////////////////////////////////////////////
@@ -2765,7 +3216,7 @@ void PHYREX_Restore_Disk_Ldsk_Subtree_Pre(t_ldsk *old_ldsk, t_ldsk *young_ldsk,
       PHYREX_Restore_Geo_Coord(young_ldsk->coord);
       PHYREX_Restore_Geo_Coord(young_ldsk->disk->centr);
 
-      For(i,young_ldsk->n_next)
+      for(i=0;i<young_ldsk->n_next;i++)
         {
           PHYREX_Restore_Disk_Ldsk_Subtree_Pre(young_ldsk,young_ldsk->next[i],tree);
         }
@@ -2779,7 +3230,7 @@ void PHYREX_Proposal_Disk_Ldsk_Subtree(t_ldsk *root_ldsk, phydbl *logdens, t_tre
 {
   int i;  
   (*logdens) = 0.0;
-  For(i,root_ldsk->n_next) PHYREX_Proposal_Disk_Ldsk_Subtree_Pre(root_ldsk,root_ldsk->next[i],root_ldsk,logdens,tree);
+  for(i=0;i<root_ldsk->n_next;i++) PHYREX_Proposal_Disk_Ldsk_Subtree_Pre(root_ldsk,root_ldsk->next[i],root_ldsk,logdens,tree);
 }
 
 /*////////////////////////////////////////////////////////////
@@ -2796,7 +3247,7 @@ void PHYREX_Proposal_Disk_Ldsk_Subtree_Pre(t_ldsk *old_ldsk, t_ldsk *young_ldsk,
   else
     {
       int i;
-      For(i,young_ldsk->n_next)
+      for(i=0;i<young_ldsk->n_next;i++)
         {
           PHYREX_Proposal_Disk_Ldsk_Subtree_Pre(young_ldsk,young_ldsk->next[i],root_ldsk,logdens,tree);
         }
@@ -2814,9 +3265,9 @@ void PHYREX_Ldsk_To_Tree(t_tree *tree)
   t_dsk *disk;
 
   /* Reset */
-  For(i,2*tree->n_otu-1) 
+  for(i=0;i<2*tree->n_otu-1;++i) 
     {
-      For(j,3) 
+      for(j=0;j<3;++j) 
         {
           tree->a_nodes[i]->v[j] = NULL;
           tree->a_nodes[i]->b[j] = NULL;
@@ -2831,7 +3282,7 @@ void PHYREX_Ldsk_To_Tree(t_tree *tree)
     }
 
   /* Connect tips */
-  For(i,tree->n_otu) 
+  for(i=0;i<tree->n_otu;++i) 
     {
       tree->disk->ldsk_a[i]->nd = tree->a_nodes[i];
       tree->a_nodes[i]->coord = tree->disk->ldsk_a[i]->coord;
@@ -2845,16 +3296,16 @@ void PHYREX_Ldsk_To_Tree(t_tree *tree)
   tree->num_curr_branch_available = 0;
   PHYREX_Ldsk_To_Tree_Post(tree->n_root,disk->ldsk,&i,tree);
 
-  For(i,tree->n_otu) assert(!(tree->a_nodes[i]->v[0] == NULL));
+  for(i=0;i<tree->n_otu;++i) assert(tree->a_nodes[i]->v[0]);
 
-  For(i,3) 
+  for(i=0;i<3;++i) 
     if(tree->n_root->v[2]->v[i] == tree->n_root) 
       { 
         tree->n_root->v[2]->v[i] = tree->n_root->v[1]; 
         break; 
       }
 
-  For(i,3) 
+  for(i=0;i<3;++i) 
     if(tree->n_root->v[1]->v[i] == tree->n_root) 
       { 
         tree->n_root->v[1]->v[i] = tree->n_root->v[2]; 
@@ -2866,7 +3317,7 @@ void PHYREX_Ldsk_To_Tree(t_tree *tree)
   /* Connect_Edges_To_Nodes_Recur(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree); */
 
   tree->e_root = NULL;
-  For(i,2*tree->n_otu-3)
+  for(i=0;i<2*tree->n_otu-3;++i)
     {
       /* printf("\n %d %d",tree->a_edges[i]->left->num,tree->a_edges[i]->rght->num); */
       if((tree->a_edges[i]->left == tree->n_root->v[1] && tree->a_edges[i]->rght == tree->n_root->v[2]) ||
@@ -2897,8 +3348,8 @@ void PHYREX_Ldsk_To_Tree(t_tree *tree)
 
 void PHYREX_Ldsk_To_Tree_Post(t_node *a, t_ldsk *ldsk, int *available, t_tree *tree)
 {
-  assert(!(ldsk == NULL));
-  assert(!(a == NULL));
+  assert(ldsk);
+  assert(a);
 
   ldsk->nd = a;  
   tree->rates->nd_t[a->num] = ldsk->disk->time;
@@ -2926,6 +3377,7 @@ void PHYREX_Ldsk_To_Tree_Post(t_node *a, t_ldsk *ldsk, int *available, t_tree *t
           /*     Generic_Exit(__FILE__,__LINE__,__FUNCTION__); */
           /*   } */
 
+
           while(t->next && t->n_next == 1) t = t->next[0];
          
           if(t->nd == NULL) 
@@ -2938,6 +3390,8 @@ void PHYREX_Ldsk_To_Tree_Post(t_node *a, t_ldsk *ldsk, int *available, t_tree *t
               son = t->nd;
             }
                     
+          /* printf("\n. a: %d son: %d n_next: %d",a->num,son->num,ldsk->n_next); */
+
           PHYREX_Ldsk_To_Tree_Post(son,t,available,tree);          
 
           if(parent->v[2] != NULL && n_next >= 2) 
@@ -2958,7 +3412,7 @@ void PHYREX_Ldsk_To_Tree_Post(t_node *a, t_ldsk *ldsk, int *available, t_tree *t
               
               /* printf("\n# connect %d to %d",parent->num,new_parent->num); */
               /* printf("\n# connect %d to %d",new_parent->num,new_parent->v[1]->num); */
-              /* printf("\n# connect %d to %d",new_parent->num,new_parent->v[2]->num); */              
+              /* printf("\n# connect %d to %d",new_parent->num,new_parent->v[2]->num);               */
               /* fflush(NULL); */
               
               tree->rates->nd_t[new_parent->num] = ldsk->disk->time;
@@ -2991,7 +3445,7 @@ void PHYREX_Remove_Lindisk_Next(t_ldsk *ldsk, t_ldsk *rm)
   new_next = (t_ldsk **)mCalloc(ldsk->n_next-1+NEXT_BLOCK_SIZE,sizeof(t_ldsk *));
 
   pos = 0;
-  For(i,ldsk->n_next)
+  for(i=0;i<ldsk->n_next;i++)
     {
       if(ldsk->next[i] != rm)
         {
@@ -3028,11 +3482,11 @@ phydbl *PHYREX_Mean_Pairwise_Distance_Between_Lineage_Locations(t_tree *tree)
       else if(!(n_disks%block)) dist = (phydbl *)mRealloc(dist,n_disks+block,sizeof(phydbl));
       
       dist[n_disks] = 0.0;
-      For(i,disk->n_ldsk_a-1)
+      for(i=0;i<disk->n_ldsk_a-1;i++)
         {
           for(j=i+1;j<disk->n_ldsk_a;j++)
             {
-              For(k,tree->mmod->n_dim)
+              for(k=0;k<tree->mmod->n_dim;k++)
                 {
                   dist[n_disks] += FABS(disk->ldsk_a[i]->coord->lonlat[k] - disk->ldsk_a[j]->coord->lonlat[k]);
                   printf("\n * %d %f %f %f",
@@ -3103,7 +3557,7 @@ phydbl PHYREX_Random_Select_Time_Between_Jumps(t_tree *tree)
 int PHYREX_Is_In_Ldscape(t_ldsk *ldsk, t_phyrex_mod *mmod)
 {
   int j;
-  For(j,mmod->n_dim) if(ldsk->coord->lonlat[j] > mmod->lim->lonlat[j] ||
+  for(j=0;j<mmod->n_dim;j++) if(ldsk->coord->lonlat[j] > mmod->lim->lonlat[j] ||
                         ldsk->coord->lonlat[j] < 0.0) return NO;
   return YES;
 }
@@ -3146,7 +3600,7 @@ phydbl PHYREX_Neighborhood_Size_Regression(t_tree *tree)
 
   pair = 0;
   fst0 = 0.0;
-  For(i,tree->n_otu-1)
+  for(i=0;i<tree->n_otu-1;i++)
     {
       fst_min_dist = 0.0;
       min_dist = MDBL_MAX;
@@ -3161,7 +3615,7 @@ phydbl PHYREX_Neighborhood_Size_Regression(t_tree *tree)
             }
           
           dist[pair] = Euclidean_Dist(tree->a_nodes[i]->coord,tree->a_nodes[j]->coord);
-          dist[pair] = LOG(dist[pair]);
+          dist[pair] = log(dist[pair]);
 
           Qr = Pairwise_Identity(i,j,tree->data);
           fst[pair] = (Qr-QA)/(1.-QA);
@@ -3315,7 +3769,7 @@ void PHYREX_Read_Tip_Coordinates(t_ldsk **ldsk_a, t_tree *tree)
   found_sw = NO;
   found_ne = NO;
 
-  For(i,tree->n_otu) done[i] = NO;
+  for(i=0;i<tree->n_otu;i++) done[i] = NO;
 
   do
     {
@@ -3323,8 +3777,8 @@ void PHYREX_Read_Tip_Coordinates(t_ldsk **ldsk_a, t_tree *tree)
       For(i,strlen(s)) if(s[i] == '#') break; /* skip comment */
       if(i != strlen(s)) continue;
       
-      For(i,tree->n_otu) if(strstr(tree->a_nodes[i]->name,s)) break;
-      
+      for(i=0;i<tree->n_otu;i++) 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;
@@ -3361,14 +3815,14 @@ void PHYREX_Read_Tip_Coordinates(t_ldsk **ldsk_a, t_tree *tree)
       Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
     }
 
-  For(i,tree->n_otu) 
+  for(i=0;i<tree->n_otu;i++) 
     if(done[i] == NO) 
       {
         PhyML_Printf("\n== Could not find coordinates for '%s'.",tree->a_nodes[i]->name);
         Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
       }
 
-  For(i,tree->n_otu) 
+  for(i=0;i<tree->n_otu;i++) 
     {
       ldsk_a[i]->coord->lonlat[0] -= sw_lon;
       ldsk_a[i]->coord->lonlat[1] -= sw_lat;
@@ -3431,11 +3885,11 @@ int PHYREX_Random_Insert_Ldsk_In_Next_List(t_ldsk *ins, t_ldsk *where)
   rk = (int *)mCalloc(size,sizeof(int));
   next_cpy = (t_ldsk **)mCalloc(size,sizeof(t_ldsk *));
 
-  For(i,size) next_cpy[i] = where->next[i];
+  for(i=0;i<size;i++) next_cpy[i] = where->next[i];
 
   pos  = Rand_Int(0,size);
 
-  For(i,size)
+  for(i=0;i<size;i++)
     {
       if(i < pos) rk[i] = i;
       else        rk[i] = i+1;
@@ -3443,7 +3897,7 @@ int PHYREX_Random_Insert_Ldsk_In_Next_List(t_ldsk *ins, t_ldsk *where)
 
   PHYREX_Make_Lindisk_Next(where);
   
-  For(i,size) where->next[rk[i]] = next_cpy[i];
+  for(i=0;i<size;i++) where->next[rk[i]] = next_cpy[i];
   
   where->next[pos]= ins;
 
@@ -3467,9 +3921,9 @@ void PHYREX_Insert_Ldsk_In_Next_List(t_ldsk *ins, int pos, t_ldsk *where)
   rk = (int *)mCalloc(size,sizeof(int));
   next_cpy = (t_ldsk **)mCalloc(size,sizeof(t_ldsk *));
 
-  For(i,size) next_cpy[i] = where->next[i];
+  for(i=0;i<size;i++) next_cpy[i] = where->next[i];
 
-  For(i,size)
+  for(i=0;i<size;i++)
     {
       if(i < pos) rk[i] = i;
       else        rk[i] = i+1;
@@ -3477,7 +3931,7 @@ void PHYREX_Insert_Ldsk_In_Next_List(t_ldsk *ins, int pos, t_ldsk *where)
 
   PHYREX_Make_Lindisk_Next(where);
   
-  For(i,size) where->next[rk[i]] = next_cpy[i];
+  for(i=0;i<size;i++) where->next[rk[i]] = next_cpy[i];
   
   where->next[pos]= ins;
 
@@ -3615,16 +4069,16 @@ t_ldsk *PHYREX_Generate_Path(t_ldsk *beg, t_ldsk *end, phydbl cur_n_evt, phydbl
   time   = (phydbl *)mCalloc(n_evt,sizeof(phydbl));
   ldsk_a = (t_ldsk **)mCalloc(n_evt,sizeof(t_ldsk *));
 
-  For(i,n_evt) time[i] =  beg->disk->time - FABS(Uni()*(end->disk->time - beg->disk->time));
+  for(i=0;i<n_evt;i++) time[i] =  beg->disk->time - FABS(Uni()*(end->disk->time - beg->disk->time));
 
   /* Invert time direction */
-  For(i,n_evt) time[i] = -time[i];
+  for(i=0;i<n_evt;i++) time[i] = -time[i];
   
   /* Bubble sort time in ascending order */
   do
     {
       swap = NO;
-      For(i,n_evt-1) 
+      for(i=0;i<n_evt-1;i++) 
         {
           if(time[i+1] < time[i])
             {
@@ -3637,7 +4091,7 @@ t_ldsk *PHYREX_Generate_Path(t_ldsk *beg, t_ldsk *end, phydbl cur_n_evt, phydbl
     }while(swap == YES);
 
   
-  For(i,n_evt)
+  for(i=0;i<n_evt;i++)
     {
       ldsk_a[i] = PHYREX_Make_Lindisk_Node(tree->mmod->n_dim);
       disk = PHYREX_Make_Disk_Event(tree->mmod->n_dim,tree->n_otu);
@@ -3649,7 +4103,7 @@ t_ldsk *PHYREX_Generate_Path(t_ldsk *beg, t_ldsk *end, phydbl cur_n_evt, phydbl
       /* printf("\n. Generate ldsk %s",ldsk_a[i]->coord->id); */
     }
 
-  For(i,n_evt-1) ldsk_a[i]->prev = ldsk_a[i+1];
+  for(i=0;i<n_evt-1;i++) ldsk_a[i]->prev = ldsk_a[i+1];
   ldsk_a[i]->prev = NULL;
 
   for(i=1;i<n_evt;i++) ldsk_a[i]->next[0] = ldsk_a[i-1];
@@ -3658,9 +4112,9 @@ t_ldsk *PHYREX_Generate_Path(t_ldsk *beg, t_ldsk *end, phydbl cur_n_evt, phydbl
   path = ldsk_a[0];
 
   /* Generate path */
-  For(i,tree->mmod->n_dim)
+  for(i=0;i<tree->mmod->n_dim;i++)
     {
-      For(j,n_evt)
+      for(j=0;j<n_evt;j++)
         {
           if(j == 0)
             mode = (end->coord->lonlat[i] - beg->coord->lonlat[i])/(n_evt+1.) + beg->coord->lonlat[i];          
@@ -3687,7 +4141,7 @@ t_ldsk *PHYREX_Generate_Path(t_ldsk *beg, t_ldsk *end, phydbl cur_n_evt, phydbl
     }
 
 
-  /* For(j,n_evt) PhyML_Printf("\n. in %12f %12f",ldsk_a[j]->coord->lonlat[0],ldsk_a[j]->coord->lonlat[1]); */
+  /* for(j=0;j<n_evt;j++) PhyML_Printf("\n. in %12f %12f",ldsk_a[j]->coord->lonlat[0],ldsk_a[j]->coord->lonlat[1]); */
 
 
   Free(ldsk_a);
@@ -3717,7 +4171,7 @@ phydbl PHYREX_Path_Logdensity(t_ldsk *beg, t_ldsk *end, phydbl cur_n_evt, phydbl
       assert(ldsk != NULL);
     }
 
-  For(i,tree->mmod->n_dim)
+  for(i=0;i<tree->mmod->n_dim;i++)
     {     
       j    = 0;
       ldsk = beg;
@@ -3733,7 +4187,7 @@ phydbl PHYREX_Path_Logdensity(t_ldsk *beg, t_ldsk *end, phydbl cur_n_evt, phydbl
                                     0.0,
                                     tree->mmod->lim->lonlat[i],&err);
 
-          /* lnDens += LOG(1./tree->mmod->lim->lonlat[i]); */
+          /* lnDens += log(1./tree->mmod->lim->lonlat[i]); */
 
           lnDens += Log_Dnorm_Trunc(ldsk->prev->disk->centr->lonlat[i],
                                     ldsk->prev->coord->lonlat[i],
@@ -3741,7 +4195,7 @@ phydbl PHYREX_Path_Logdensity(t_ldsk *beg, t_ldsk *end, phydbl cur_n_evt, phydbl
                                     0.0,
                                     tree->mmod->lim->lonlat[i],&err);
 
-          /* lnDens += LOG(1./tree->mmod->lim->lonlat[i]); */
+          /* lnDens += log(1./tree->mmod->lim->lonlat[i]); */
 
           ldsk = ldsk->prev;
           j++;
@@ -3754,7 +4208,7 @@ phydbl PHYREX_Path_Logdensity(t_ldsk *beg, t_ldsk *end, phydbl cur_n_evt, phydbl
     rate = cur_n_evt;
 
   lnDens += Dpois(n_evt,rate,YES);
-  lnDens += (n_evt) * LOG(1./FABS(end->disk->time - beg->disk->time));
+  lnDens += (n_evt) * log(1./FABS(end->disk->time - beg->disk->time));
   lnDens += LnFact(n_evt);
 
   return(lnDens);
@@ -3773,7 +4227,7 @@ phydbl PHYREX_Time_Tree_Length(t_tree *tree)
   while(disk->prev) disk = disk->prev;
 
   len = 0.0;
-  For(i,disk->ldsk->n_next) PHYREX_Time_Tree_Length_Pre(disk->ldsk,disk->ldsk->next[i],&len,tree);
+  for(i=0;i<disk->ldsk->n_next;i++) PHYREX_Time_Tree_Length_Pre(disk->ldsk,disk->ldsk->next[i],&len,tree);
   
   assert(!(isnan(len) || isinf(len)));
 
@@ -3791,7 +4245,7 @@ void PHYREX_Time_Tree_Length_Pre(t_ldsk *a, t_ldsk *d, phydbl *len, t_tree *tree
   
   if(d->disk->next == NULL) return;
   else
-    For(i,d->n_next) PHYREX_Time_Tree_Length_Pre(d,d->next[i],len,tree);
+    for(i=0;i<d->n_next;i++) PHYREX_Time_Tree_Length_Pre(d,d->next[i],len,tree);
 }
 
 /*////////////////////////////////////////////////////////////
@@ -3973,10 +4427,10 @@ void PHYREX_Print_MultiTypeTree_Config_File(int n_sites, char *filename, t_tree
   deme_names = (char **)mCalloc(n_sites,sizeof(char *));
 
   n_demes = 0;
-  For(i,tree->n_otu)
+  for(i=0;i<tree->n_otu;i++)
     {
       s = strrchr(tree->a_nodes[i]->coord->id,'_');
-      For(j,n_demes) if(!strcmp(s+1,deme_names[j])) break;
+      for(j=0;j<n_demes;j++) if(!strcmp(s+1,deme_names[j])) break;
       if(j == n_demes)
         {
           deme_names[n_demes] = (char *)mCalloc(strlen(s+1)+1,sizeof(char));
@@ -3991,14 +4445,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)
+  for(i=0;i<tree->n_otu;i++)
     {
       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 +4473,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));
@@ -4028,17 +4483,17 @@ void PHYREX_Print_MultiTypeTree_Config_File(int n_sites, char *filename, t_tree
   Free(s);
 
   s = (char *)mCalloc(T_MAX_LINE,sizeof(char));
-  For(i,n_demes) strcat(s,"1.0 ");
+  for(i=0;i<n_demes;i++) strcat(s,"1.0 ");
   PhyML_Fprintf(fp,"\n<parameter id=\"RealParameter.01\" dimension=\"%d\" estimate=\"false\" name=\"popSizes\">%s</parameter>",n_demes,s);
   Free(s);
 
   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)
+  for(i=0;i<tree->n_otu;i++)
     {
-      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 +4503,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);
+  for(i=0;i<n_demes;i++) strcat(s,"1.0 ");
+  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\">");
@@ -4152,17 +4607,66 @@ void PHYREX_Print_MultiTypeTree_Config_File(int n_sites, char *filename, t_tree
   PhyML_Fprintf(fp,"\n</run>");
   PhyML_Fprintf(fp,"\n</beast>");
   
-  For(i,n_demes) Free(deme_names[i]);
+  for(i=0;i<n_demes;i++) Free(deme_names[i]);
   Free(deme_names);
 
   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=0;i<tree->n_otu;i++)
+    {
+      for(j=0;j<n_demes;j++)
+        {
+          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..bb5a0d4 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,9 @@ 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);
+t_tree *PHYREX_Simulate_Independent_Loci(int n_otu, int n_loci, phydbl w, phydbl h, int r_seed);
 
 
 
diff --git a/src/rates.c b/src/rates.c
index 6a2926b..9f79435 100644
--- a/src/rates.c
+++ b/src/rates.c
@@ -1,7 +1,7 @@
 /*
 
-PhyML:  a program that  computes maximum likelihood phyLOGenies from
-DNA or AA homoLOGous sequences.
+PhyML:  a program that  computes maximum likelihood phylogenies from
+DNA or AA homologous sequences.
 
 Copyright (C) Stephane Guindon. Oct 2003 onward.
 
@@ -19,21 +19,20 @@ the GNU public licence. See http://www.opensource.org for details.
 #include <R.h>
 #endif
 
-
-
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 phydbl RATES_Lk_Rates(t_tree *tree)
 {
+  
+  if(tree->eval_rlnL == NO) return UNLIKELY;
 
   tree->rates->c_lnL_rates  = .0;
 
   RATES_Lk_Rates_Pre(tree->n_root,tree->n_root->v[2],NULL,tree);
   RATES_Lk_Rates_Pre(tree->n_root,tree->n_root->v[1],NULL,tree);
 
-  if(isnan(tree->rates->c_lnL_rates) || isinf(tree->rates->c_lnL_rates))
+  if(isnan(tree->rates->c_lnL_rates))
     {
       PhyML_Printf("\n== Err. in file %s at line %d (function '%s')\n",__FILE__,__LINE__,__FUNCTION__);
       Exit("\n");
@@ -45,7 +44,6 @@ phydbl RATES_Lk_Rates(t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void RATES_Lk_Rates_Pre(t_node *a, t_node *d, t_edge *b, t_tree *tree)
 {
   int i;
@@ -56,8 +54,8 @@ void RATES_Lk_Rates_Pre(t_node *a, t_node *d, t_edge *b, t_tree *tree)
 
   if(d->anc != a)
     {
-      PhyML_Printf("\n. d=%d d->anc=%d a=%d root=%d",d->num,d->anc->num,a->num,tree->n_root->num);
-      PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__);
+      PhyML_Printf("\n== d=%d d->anc=%d a=%d root=%d",d->num,d->anc->num,a->num,tree->n_root->num);
+      PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__);
       Warn_And_Exit("");
     }
 
@@ -76,11 +74,9 @@ void RATES_Lk_Rates_Pre(t_node *a, t_node *d, t_edge *b, t_tree *tree)
   log_dens = RATES_Lk_Rates_Core(mu_a,mu_d,r_a,r_d,n_a,n_d,dt_a,dt_d,tree);
   tree->rates->c_lnL_rates += log_dens;
 
-  /* printf("\n. a=%3d d=%3d r(a)=%10f r(d)=%10f %f",a->num,d->num,mu_a,mu_d,log_dens); */
-
   if(isnan(tree->rates->c_lnL_rates))
     {
-      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__);
       MCMC_Print_Param(tree->mcmc,tree);
       Exit("\n");
     }
@@ -91,7 +87,7 @@ void RATES_Lk_Rates_Pre(t_node *a, t_node *d, t_edge *b, t_tree *tree)
   if(d->tax) return;
   else
     {
-      For(i,3)
+      for(i=0;i<3;i++)
 	{
 	  if((d->v[i] != a) && (d->b[i] != tree->e_root))
 	    {
@@ -104,7 +100,6 @@ void RATES_Lk_Rates_Pre(t_node *a, t_node *d, t_edge *b, t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 phydbl RATES_Lk_Change_One_Rate(t_node *d, phydbl new_rate, t_tree *tree)
 {
   tree->rates->br_r[d->num] = new_rate;
@@ -133,7 +128,7 @@ phydbl RATES_Lk_Change_One_Time(t_node *n, phydbl new_t, t_tree *tree)
 
       RATES_Update_Triplet(n,tree);
       
-      For(i,3)
+      for(i=0;i<3;i++)
 	{
 	  if(n->b[i] != tree->e_root) RATES_Update_Triplet(n->v[i],tree);
 	  else RATES_Update_Triplet(tree->n_root,tree);
@@ -145,7 +140,6 @@ phydbl RATES_Lk_Change_One_Time(t_node *n, phydbl new_t, t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void RATES_Update_Triplet(t_node *n, t_tree *tree)
 {
   phydbl curr_triplet,new_triplet;
@@ -188,19 +182,19 @@ void RATES_Update_Triplet(t_node *n, t_tree *tree)
 	  {
 	    log_dens  = RATES_Dmu(mu0,n0,dt0,tree->rates->nu,1./tree->rates->nu,tree->rates->lexp,0,1);
 	    log_dens *= RATES_Dmu(mu1,n1,dt1,tree->rates->nu,1./tree->rates->nu,tree->rates->lexp,0,1);
-	    log_dens  = LOG(log_dens);
+	    log_dens  = log(log_dens);
 	    break;
 	  }
 	case EXPONENTIAL : 
 	  {
 	    log_dens = Dexp(mu0,tree->rates->lexp) * Dexp(mu1,tree->rates->lexp);
-	    log_dens = LOG(log_dens);
+	    log_dens = log(log_dens);
 	    break;
 	  }
 	case GAMMA :
 	  {
 	    log_dens = Dgamma(mu0,tree->rates->nu,1./tree->rates->nu) * Dgamma(mu1,tree->rates->nu,1./tree->rates->nu);
-	    log_dens = LOG(log_dens);
+	    log_dens = log(log_dens);
 	    break;
 	  }
 	case THORNE :
@@ -254,7 +248,7 @@ void RATES_Update_Triplet(t_node *n, t_tree *tree)
       r0 = tree->rates->nd_r[n->num];
 
       v1 = v2 = NULL;
-      For(i,3)
+      for(i=0;i<3;i++)
 	{
 	  if((n->v[i] != n->anc) && (n->b[i] != tree->e_root))
 	    {
@@ -290,7 +284,6 @@ void RATES_Update_Triplet(t_node *n, t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-/* Returns LOG(f(br_r_rght;br_r_left)) */
 phydbl RATES_Lk_Rates_Core(phydbl br_r_a, phydbl br_r_d, phydbl nd_r_a, phydbl nd_r_d, int n_a, int n_d, phydbl dt_a, phydbl dt_d, t_tree *tree)
 {
   phydbl log_dens;
@@ -299,7 +292,7 @@ phydbl RATES_Lk_Rates_Core(phydbl br_r_a, phydbl br_r_d, phydbl nd_r_a, phydbl n
   phydbl cr,logcr;
   
   cr        = tree->rates->clock_r;
-  logcr     = LOG(cr);
+  logcr     = log(cr);
   log_dens  = UNLIKELY;
   mean = sd = -1.;
   min_r     = tree->rates->min_rate;
@@ -359,8 +352,8 @@ phydbl RATES_Lk_Rates_Core(phydbl br_r_a, phydbl br_r_d, phydbl nd_r_a, phydbl n
 
 	/* sd = SQRT(dt_d*tree->rates->nu); */
 
- 	/* /\* sd   = SQRT(dt_d*EXP(tree->rates->nu)); *\/ */
-	/* /\* mean = LOG(br_r_a) - .5*sd*sd; *\/ */
+ 	/* /\* sd   = SQRT(dt_d*exp(tree->rates->nu)); *\/ */
+	/* /\* mean = log(br_r_a) - .5*sd*sd; *\/ */
 
 	/* if(tree->rates->model_log_rates == YES) */
 	/*   { */
@@ -413,11 +406,26 @@ phydbl RATES_Lk_Rates_Core(phydbl br_r_a, phydbl br_r_d, phydbl nd_r_a, phydbl n
     case GAMMA :
       {
 	if(tree->rates->model_log_rates == YES)
-	  log_dens = Dgamma(EXP(br_r_d),1./tree->rates->nu,tree->rates->nu);
-	else
-	  log_dens = Dgamma(br_r_d,1./tree->rates->nu,tree->rates->nu);
-
-	log_dens = LOG(log_dens);
+	  {
+            /* log_dens = Dgamma(exp(br_r_d),1./(tree->rates->nu*dt_d*POW(tree->rates->clock_r,2)),tree->rates->nu*dt_d*POW(tree->rates->clock_r,2)); */
+            /* log_dens /= */
+            /*   (Pgamma(exp(tree->rates->max_rate),1./(tree->rates->nu*dt_d*POW(tree->rates->clock_r,2)),tree->rates->nu*dt_d*POW(tree->rates->clock_r,2)) - */
+            /*    Pgamma(exp(tree->rates->min_rate),1./(tree->rates->nu*dt_d*POW(tree->rates->clock_r,2)),tree->rates->nu*dt_d*POW(tree->rates->clock_r,2))); */
+          }
+        else
+	  {
+            /* log_dens = Dgamma(br_r_d,1./(tree->rates->nu*dt_d*POW(tree->rates->clock_r,2)),tree->rates->nu*dt_d*POW(tree->rates->clock_r,2)); */
+            /* log_dens /= */
+            /*   (Pgamma(tree->rates->max_rate,1./(tree->rates->nu*dt_d*POW(tree->rates->clock_r,2)),tree->rates->nu*dt_d*POW(tree->rates->clock_r,2)) - */
+            /*    Pgamma(tree->rates->min_rate,1./(tree->rates->nu*dt_d*POW(tree->rates->clock_r,2)),tree->rates->nu*dt_d*POW(tree->rates->clock_r,2))); */
+
+            int err;
+            /* log_dens = Log_Dnorm_Trunc(br_r_d,1.0,tree->rates->nu/tree->rates->clock_r,tree->rates->min_rate,tree->rates->max_rate,&err); */
+            log_dens = Log_Dnorm_Trunc(br_r_d,1.0,tree->rates->nu,tree->rates->min_rate,tree->rates->max_rate,&err);
+            /* log_dens = Log_Dnorm_Trunc(br_r_d,1.0,2.0,tree->rates->min_rate,tree->rates->max_rate,&err); */
+          }
+        
+	/* log_dens = log(log_dens); */
 	break;
       }
     case STRICTCLOCK :
@@ -428,18 +436,18 @@ 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("");
       }
     }
 
-  if(isnan(log_dens) || isinf(FABS(log_dens)))
+  if(isnan(log_dens))
     {
-      PhyML_Printf("\n. Run=%4d br_r_d=%f br_r_a=%f dt_d=%f dt_a=%f nu=%f log_dens=%G sd=%f mean=%f\n",
+      PhyML_Printf("\n== Run=%4d br_r_d=%f br_r_a=%f dt_d=%f dt_a=%f nu=%f log_dens=%G sd=%f mean=%f\n",
 		   tree->mcmc->run,
 		   br_r_d,br_r_a,dt_d,dt_a,tree->rates->nu,log_dens,
 		   sd,mean);
-      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");
     }
 
@@ -620,6 +628,160 @@ void RATES_Print_Rates(t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
+void RATES_Copy_Rate_Struct(t_rate *from, t_rate *to, int n_otu)
+{
+  int i;
+
+  to->lexp = from->lexp;
+  to->alpha = from->alpha;
+  to->less_likely = from->less_likely;
+
+  to->birth_rate = from->birth_rate;
+  to->birth_rate_min = from->birth_rate_min;
+  to->birth_rate_max = from->birth_rate_max;
+  to->birth_rate_pivot = from->birth_rate_pivot;
+
+  to->death_rate = from->death_rate;
+  to->death_rate_min = from->death_rate_min;
+  to->death_rate_max = from->death_rate_max;
+  to->death_rate_pivot = from->death_rate_pivot;
+  
+  to->nu = from->nu;
+  to->min_nu = from->min_nu;
+  to->max_nu = from->max_nu;
+
+  to->min_rate = from->min_rate;
+  to->max_rate = from->max_rate;
+
+  to->c_lnL1 = from->c_lnL1;
+  to->c_lnL2 = from->c_lnL2;
+
+  to->c_lnL_rates = from->c_lnL_rates;
+  to->c_lnL_times = from->c_lnL_times;
+  to->c_lnL_jps = from->c_lnL_jps;
+  
+  to->clock_r = from->clock_r;
+  to->min_clock = from->min_clock;
+  to->max_clock = from->max_clock;
+
+  to->lbda_nu = from->lbda_nu;
+  to->min_dt = from->min_dt;
+  to->step_rate = from->step_rate;
+  to->true_tree_size = from->true_tree_size;
+  to->p_max = from->p_max;
+  to->norm_fact = from->norm_fact;
+
+  to->adjust_rates = from->adjust_rates;
+  to->use_rates = from->use_rates;
+  to->bl_from_rt = from->bl_from_rt;
+  to->approx = from->approx;
+  to->model = from->model;
+  to->is_allocated = from->is_allocated;
+  to->met_within_gibbs = from->met_within_gibbs;
+  
+  to->update_mean_l = from->update_mean_l;
+  to->update_cov_l = from->update_cov_l;
+
+  to->model_log_rates = from->model_log_rates;
+  
+  to->nd_t_recorded = from->nd_t_recorded;
+  to->br_r_recorded = from->br_r_recorded;
+  
+  to->log_K_cur = from->log_K_cur;
+  to->cur_comb_numb = from->cur_comb_numb;
+  to->update_time_norm_const = from->update_time_norm_const;
+
+  For(i,2*n_otu-1) to->nd_r[i] = from->nd_r[i];
+  For(i,2*n_otu-1) to->br_r[i] = from->br_r[i];
+  For(i,2*n_otu-1) to->buff_r[i] = from->buff_r[i];
+  For(i,2*n_otu-1) to->true_r[i] = from->true_r[i];
+  For(i,2*n_otu-1) to->nd_t[i] = from->nd_t[i];
+  For(i,2*n_otu-1) to->buff_t[i] = from->buff_t[i];
+  For(i,2*n_otu-1) to->true_t[i] = from->true_t[i];
+  For(i,2*n_otu-1) to->t_mean[i] = from->t_mean[i];
+  For(i,2*n_otu-1) to->t_prior[i] = from->t_prior[i];
+  For(i,2*n_otu-1) to->t_prior_min[i] = from->t_prior_min[i];
+  For(i,2*n_otu-1) to->t_prior_max[i] = from->t_prior_max[i];
+  For(i,2*n_otu-1) to->t_floor[i] = from->t_floor[i];
+  For(i,2*n_otu-1) to->t_rank[i] = from->t_rank[i];
+  For(i,2*n_otu-1) to->t_has_prior[i] = from->t_has_prior[i];
+  For(i,2*n_otu-2) to->dens[i] = from->dens[i];
+  For(i,2*n_otu-1) to->triplet[i] = from->triplet[i];
+  For(i,2*n_otu-1) to->n_jps[i] = from->n_jps[i];
+  For(i,2*n_otu-2) to->t_jps[i] = from->t_jps[i];
+  For(i,(2*n_otu-2)*(2*n_otu-2)) to->cov_l[i] = from->cov_l[i];
+  For(i,(2*n_otu-2)*(2*n_otu-2)) to->invcov[i] = from->invcov[i];
+  For(i,2*n_otu-2) to->mean_l[i] = from->mean_l[i];
+  For(i,2*n_otu-2) to->ml_l[i] = from->ml_l[i];
+  For(i,2*n_otu-2) to->cur_l[i] = from->cur_l[i];
+  For(i,2*n_otu-3) to->u_ml_l[i] = from->u_ml_l[i];
+  For(i,2*n_otu-3) to->u_cur_l[i] = from->u_cur_l[i];
+  For(i,(2*n_otu-2)*(2*n_otu-2)) to->cov_r[i] = from->cov_r[i];
+  For(i,2*n_otu-2) to->cond_var[i] = from->cond_var[i];
+  For(i,2*n_otu-2) to->mean_r[i] = from->mean_r[i];
+  For(i,2*n_otu-1) to->mean_t[i] = from->mean_t[i];
+  For(i,(2*n_otu-1)*(2*n_otu-1)) to->lca[i] = from->lca[i];
+  For(i,(2*n_otu-2)*(2*n_otu-2)) to->reg_coeff[i] = from->reg_coeff[i];
+  For(i,(2*n_otu-2)*(6*n_otu-9)) to->trip_reg_coeff[i] = from->trip_reg_coeff[i];
+  For(i,(2*n_otu-2)*9) to->trip_cond_cov[i] = from->trip_cond_cov[i];
+  For(i,2*n_otu) to->_2n_vect1[i] = from->_2n_vect1[i];
+  For(i,2*n_otu) to->_2n_vect2[i] = from->_2n_vect2[i];
+  For(i,2*n_otu) to->_2n_vect3[i] = from->_2n_vect3[i];
+  For(i,2*n_otu) to->_2n_vect4[i] = from->_2n_vect4[i];
+  For(i,2*n_otu) to->_2n_vect5[i] = from->_2n_vect5[i];
+  For(i,4*n_otu*n_otu) to->_2n2n_vect1[i] = from->_2n2n_vect1[i];
+  For(i,4*n_otu*n_otu) to->_2n2n_vect2[i] = from->_2n2n_vect2[i];
+  For(i,2*n_otu-1) to->br_do_updt[i] = from->br_do_updt[i];
+  For(i,2*n_otu-1) to->cur_gamma_prior_mean[i] = from->cur_gamma_prior_mean[i];
+  For(i,2*n_otu-1) to->cur_gamma_prior_var[i] = from->cur_gamma_prior_var[i];
+  For(i,2*n_otu-1) to->n_tips_below[i] = from->n_tips_below[i];
+  For(i,2*n_otu-1) to->time_slice_lims[i] = from->time_slice_lims[i];
+  For(i,2*n_otu-1) to->n_time_slice_spans[i] = from->n_time_slice_spans[i];
+  For(i,2*n_otu-1) to->curr_slice[i] = from->curr_slice[i];
+  For(i,2*n_otu-1) to->has_survived[i] = from->has_survived[i];
+  For(i,2*n_otu-1) to->survival_rank[i] = from->survival_rank[i];
+  For(i,2*n_otu-1) to->survival_dur[i] = from->survival_dur[i];
+  For(i,2*n_otu-1) to->calib_prob[i] = from->calib_prob[i];
+  For(i,2*n_otu-1) to->t_prior_min_ori[i] = from->t_prior_max_ori[i];
+  For(i,n_otu*n_otu) to->times_partial_proba[i] = from->times_partial_proba[i];
+  For(i,n_otu*n_otu) to->numb_calib_chosen[i] = from->numb_calib_chosen[i];
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void RATES_Duplicate_Calib_Struct(t_tree *from, t_tree *to)
+{
+  int i,j;
+
+  to->rates->n_cal = from->rates->n_cal;
+
+  for(i=0;i<from->rates->n_cal;i++)
+    {      
+
+      to->rates->a_cal[i] = Make_Calibration();
+      Init_Calibration(to->rates->a_cal[i]);
+
+      to->rates->a_cal[i]->is_primary = from->rates->a_cal[i]->is_primary;
+      to->rates->a_cal[i]->n_target_tax = from->rates->a_cal[i]->n_target_tax;
+      to->rates->a_cal[i]->lower = from->rates->a_cal[i]->lower;
+      to->rates->a_cal[i]->upper = from->rates->a_cal[i]->upper;
+
+      to->rates->a_cal[i]->target_tax = (char **)mCalloc(to->rates->a_cal[i]->n_target_tax,sizeof(char *));
+      For(j,to->rates->a_cal[i]->n_target_tax) 
+        {
+          to->rates->a_cal[i]->target_tax[j] = (char *)mCalloc(strlen(from->rates->a_cal[i]->target_tax[j])+1,sizeof(char ));
+          strcpy(to->rates->a_cal[i]->target_tax[j],from->rates->a_cal[i]->target_tax[j]);
+        }
+
+      to->rates->a_cal[i]->target_tip = Make_Target_Tip(to->rates->a_cal[i]->n_target_tax);
+      Init_Target_Tip(to->rates->a_cal[i],to);
+
+    }
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
 
 void RATES_Print_Rates_Pre(t_node *a, t_node *d, t_edge *b, t_tree *tree)
 {  
@@ -654,7 +816,7 @@ void RATES_Print_Rates_Pre(t_node *a, t_node *d, t_edge *b, t_tree *tree)
     {
       int i;
 
-      For(i,3) 
+      for(i=0;i<3;i++) 
 	{
 	  if((d->v[i] != a) && (d->b[i] != tree->e_root))
 	    {
@@ -681,48 +843,26 @@ phydbl RATES_Average_Rate(t_tree *tree)
 
 phydbl RATES_Average_Substitution_Rate(t_tree *tree)
 {
-  phydbl sum_r,sum_dt;
-  phydbl u,t,t_anc;
+  phydbl l,dt;
   int i;
 
-  u = 0.0;
-  sum_r  = 0.0;
-  sum_dt = 0.0;
-
-  /* For(i,2*tree->n_otu-3)  */
-  /*   { */
-  /*     t     = tree->rates->nd_t[i]; */
-  /*     t_anc = tree->rates->nd_t[tree->a_nodes[i]->anc->num];       */
-  /*     u = tree->a_edges[i]->l->v; */
-  /*     if(tree->rates->model == GUINDON) u = tree->a_edges[i]->gamma_prior_mean; */
-  /*     sum_r += u;	   */
-  /*     sum_dt += FABS(t-t_anc); */
-  /*   } */
-
-  For(i,2*tree->n_otu-3)  
+  l = 0.0;
+  dt = 0.0;
+  For(i,2*tree->n_otu-1)
     {
-      if(tree->a_edges[i] != tree->e_root)
-	{
-	  t     = tree->rates->nd_t[tree->a_edges[i]->left->num];
-	  t_anc = tree->rates->nd_t[tree->a_edges[i]->rght->num];
-	  u = tree->a_edges[i]->l->v;
-	  sum_r += u;
-	  sum_dt += FABS(t-t_anc);
-	}
-      
-      sum_dt += FABS(tree->rates->nd_t[tree->n_root->v[2]->num] - tree->rates->nd_t[tree->n_root->num]);
-      sum_dt += FABS(tree->rates->nd_t[tree->n_root->v[1]->num] - tree->rates->nd_t[tree->n_root->num]);
-
-      u = tree->e_root->l->v;
-      sum_r += u;	 
+      if(tree->a_nodes[i] != tree->n_root)
+        {
+          dt += FABS(tree->rates->nd_t[tree->a_nodes[i]->num] - tree->rates->nd_t[tree->a_nodes[i]->anc->num]); 
+          l  += tree->rates->cur_l[tree->a_nodes[i]->num];
+        }
     }
-  return(sum_r / sum_dt);
+      
+  return(l/dt);
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 phydbl RATES_Check_Mean_Rates_True(t_tree *tree)
 {
   phydbl sum;
@@ -749,7 +889,6 @@ int RATES_Check_Node_Times(t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void RATES_Check_Node_Times_Pre(t_node *a, t_node *d, int *err, t_tree *tree)
 {
   if((tree->rates->nd_t[d->num] < tree->rates->nd_t[a->num]) || (FABS(tree->rates->nd_t[d->num] - tree->rates->nd_t[a->num]) < 1.E-20))
@@ -764,7 +903,7 @@ void RATES_Check_Node_Times_Pre(t_node *a, t_node *d, int *err, t_tree *tree)
     {
       int i;
 
-      For(i,3)
+      for(i=0;i<3;i++)
 	if((d->v[i] != a) && (d->b[i] != tree->e_root))	  
 	  RATES_Check_Node_Times_Pre(d,d->v[i],err,tree);
     }
@@ -772,12 +911,6 @@ void RATES_Check_Node_Times_Pre(t_node *a, t_node *d, int *err, t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
-
-
-
-
-
 void RATES_Bracket_N_Jumps(int *up, int *down, phydbl param)
 {
   phydbl cdf,eps,a,b,c;
@@ -1053,7 +1186,10 @@ void RATES_Get_Mean_Rates_Pre(t_node *a, t_node *d, t_edge *b, phydbl r_a, t_tre
 
   a_t = tree->rates->nd_t[a->num];
   d_t = tree->rates->nd_t[d->num];
-      
+
+  mean_r = -1.;
+  n_jumps = -1;
+  r_d = -1.;
   RATES_Expect_Number_Subst(a_t,d_t,r_a,&n_jumps,&mean_r,&r_d,tree->rates,tree);
   
   tree->rates->br_r[d->num]   = mean_r;
@@ -1067,7 +1203,7 @@ void RATES_Get_Mean_Rates_Pre(t_node *a, t_node *d, t_edge *b, phydbl r_a, t_tre
     {
       int i;
       
-      For(i,3)
+      for(i=0;i<3;i++)
 	{
 	  if((d->v[i] != a) && (d->b[i] != tree->e_root))
 	    {
@@ -1081,7 +1217,6 @@ void RATES_Get_Mean_Rates_Pre(t_node *a, t_node *d, t_edge *b, phydbl r_a, t_tre
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void RATES_Random_Branch_Lengths(t_tree *tree)
 {
   phydbl r0;
@@ -1136,7 +1271,7 @@ void RATES_Set_Node_Times_Pre(t_node *a, t_node *d, t_tree *tree)
       int i;
 
       v1 = v2 = NULL;
-      For(i,3) if((d->v[i] != a) && (d->b[i] != tree->e_root)) 
+      for(i=0;i<3;i++) if((d->v[i] != a) && (d->b[i] != tree->e_root)) 
 	{
 	  if(!v1) v1 = d->v[i]; 
 	  else    v2 = d->v[i];
@@ -1164,7 +1299,7 @@ void RATES_Set_Node_Times_Pre(t_node *a, t_node *d, t_tree *tree)
 	  PhyML_Printf("\n. Time for t_node %d is lower than should be. Set it to %f",d->num,tree->rates->nd_t[d->num]);
 	}
 
-      For(i,3)
+      for(i=0;i<3;i++)
 	{
 	  if((d->v[i] != a) && (d->b[i] != tree->e_root))
 	    {
@@ -1232,7 +1367,7 @@ phydbl RATES_Dmu1_Given_V_And_N(phydbl mu1, phydbl v, int n, phydbl dt1, phydbl
       h = (end - beg) / (phydbl)n_points;
       
       lbda = beg;
-      For(i,n_points-1) 
+      for(i=0;i<n_points-1;i++) 
 	{
 	  lbda += h;
 	  u = (mu1 - lbda*v)/(1.-lbda);
@@ -1333,7 +1468,7 @@ phydbl RATES_Dmu2_And_Mu1_Given_Min_N(phydbl mu1, phydbl mu2, phydbl dt1, phydbl
 
 phydbl RATES_Dmu2_And_Mu1_Given_N(phydbl mu1, phydbl mu2, phydbl dt1, phydbl dt2, int n, phydbl a, phydbl b, phydbl lexp)
   {
-    phydbl density,cumpoiss,poiss,abb,ab,LOGnf,LOGdt1,LOGdt2,nLOGdt;
+    phydbl density,cumpoiss,poiss,abb,ab,lognf,logdt1,logdt2,nlogdt;
     int i;
 
     density  = 0.0;
@@ -1341,15 +1476,15 @@ phydbl RATES_Dmu2_And_Mu1_Given_N(phydbl mu1, phydbl mu2, phydbl dt1, phydbl dt2
     ab       = a*b;
     cumpoiss = 0.0;
     poiss    = 0.0;
-    LOGnf    = LnFact(n);
-    LOGdt1   = LOG(dt1);
-    LOGdt2   = LOG(dt2);
-    nLOGdt   = n*LOG(dt1+dt2);
+    lognf    = LnFact(n);
+    logdt1   = log(dt1);
+    logdt2   = log(dt2);
+    nlogdt   = n*log(dt1+dt2);
 
     For(i,n+1)
       {
-        poiss = LOGnf - LnFact(i) - LnFact(n-i) + i*LOGdt1 + (n-i)*LOGdt2 - nLOGdt;
-	poiss = EXP(poiss);
+        poiss = lognf - LnFact(i) - LnFact(n-i) + i*logdt1 + (n-i)*logdt2 - nlogdt;
+	poiss = exp(poiss);
 	cumpoiss = cumpoiss + poiss;
 
 	if(mu2 < 1.E-10)
@@ -1506,12 +1641,12 @@ void RATES_Posterior_One_Rate(t_node *a, t_node *d, int traversal, t_tree *tree)
 
   b = NULL;
   if(a == tree->n_root) b = tree->e_root;
-  else For(i,3) if(d->v[i] == a) { b = d->b[i]; break; }
+  else for(i=0;i<3;i++) if(d->v[i] == a) { b = d->b[i]; break; }
   
   v2 = v3 = NULL;
   if(!d->tax)
     {
-      For(i,3)
+      for(i=0;i<3;i++)
 	if((d->v[i] != a) && (d->b[i] != tree->e_root))
 	  {
 	    if(!v2) { v2 = d->v[i]; }
@@ -1552,7 +1687,7 @@ void RATES_Posterior_One_Rate(t_node *a, t_node *d, int traversal, t_tree *tree)
 
   /* Likelihood */
   cel=0.0;
-  For(i,dim) 
+  for(i=0;i<dim;i++) 
     if(i != b->num) 
 	cel += tree->rates->reg_coeff[b->num*dim+i] * (tree->rates->u_cur_l[i] - tree->rates->mean_l[i]);
   cel += tree->rates->mean_l[b->num];
@@ -1569,7 +1704,7 @@ void RATES_Posterior_One_Rate(t_node *a, t_node *d, int traversal, t_tree *tree)
 
   if(isnan(cvl) || isnan(cel) || cvl < .0) 
     {
-      For(i,dim) if(i != b->num) printf("\n. reg: %f %f %f nu=%f clock=%f",
+      for(i=0;i<dim;i++) if(i != b->num) printf("\n. reg: %f %f %f nu=%f clock=%f",
 					tree->rates->reg_coeff[b->num*dim+i],
 					tree->rates->u_cur_l[i],
 					tree->rates->mean_l[i],
@@ -1580,15 +1715,15 @@ void RATES_Posterior_One_Rate(t_node *a, t_node *d, int traversal, t_tree *tree)
     }
 
   /* Model rates */
-  /* if(tree->mod->log_l == YES) cel = EXP(cel); */
+  /* if(tree->mod->log_l == YES) cel = exp(cel); */
   /* like_mean = cel / (dt*cr*nf); */
   /* like_var  = cvl / POW(dt*cr*nf,2);  */
 
   /* Model log of rates. Branch lengths are given in log units */
   if(tree->rates->model_log_rates == YES) 
     {      
-      like_mean = cel -    LOG(dt*cr*nf);
-      like_var  = cvl - 2.*LOG(dt*cr*nf);
+      like_mean = cel -    log(dt*cr*nf);
+      like_var  = cvl - 2.*log(dt*cr*nf);
     }
   else
     {
@@ -1624,7 +1759,7 @@ void RATES_Posterior_One_Rate(t_node *a, t_node *d, int traversal, t_tree *tree)
 
 
   /* Sample according to priors */
-  if(tree->mcmc->use_data == NO)
+  if(tree->eval_alnL == NO)
     {
       post_mean = prior_mean;
       post_var  = prior_var;
@@ -1651,7 +1786,7 @@ void RATES_Posterior_One_Rate(t_node *a, t_node *d, int traversal, t_tree *tree)
 
   /* !!!!!!!!!!!!!! */
 /*   u = Uni(); */
-/*   rd = U1 * EXP(1.*(u-0.5)); */
+/*   rd = U1 * exp(1.*(u-0.5)); */
 
   if(rd > r_min && rd < r_max)
     {
@@ -1665,7 +1800,7 @@ void RATES_Posterior_One_Rate(t_node *a, t_node *d, int traversal, t_tree *tree)
       RATES_Update_Norm_Fact(tree);
       RATES_Update_Cur_Bl(tree);
       
-      if(tree->mcmc->use_data) new_lnL_data = Lk(b,tree);
+      if(tree->eval_alnL) new_lnL_data = Lk(b,tree);
         /* new_lnL_rate = RATES_Lk_Rates(tree); */
       new_lnL_rate = 
 	cur_lnL_rate - 
@@ -1688,14 +1823,14 @@ void RATES_Posterior_One_Rate(t_node *a, t_node *d, int traversal, t_tree *tree)
       ratio = 0.0;
       /* Proposal ratio */
       ratio += (Log_Dnorm_Trunc(U1,post_mean,inflate_var*post_sd,r_min,r_max,&err) - Log_Dnorm_Trunc(rd,post_mean,inflate_var*post_sd,r_min,r_max,&err));
-      /*   ratio += LOG(rd/U1); */
+      /*   ratio += log(rd/U1); */
       /* Prior ratio */
       ratio += (new_lnL_rate - cur_lnL_rate);
       /* Likelihood ratio */
       ratio += (new_lnL_data - cur_lnL_data);
       
       
-      ratio = EXP(ratio);
+      ratio = exp(ratio);
       
       /*   printf("\n. R a=%3d T0=%6.1f T1=%6.1f T2=%6.1f T3=%6.1f ratio=%8f pm=%7f U1=%7.2f rd=%7.2f %f %f lr=%f %f ld=%f %f [%f]",a->num,T0,T1,T2,T3,ratio,post_mean,U1,rd, */
       /* 	 Log_Dnorm_Trunc(U1,post_mean,post_sd,r_min,r_max,&err), */
@@ -1737,17 +1872,17 @@ void RATES_Posterior_One_Rate(t_node *a, t_node *d, int traversal, t_tree *tree)
       if(d->tax == YES) return;
       else
 	{
-	  For(i,3)
+	  for(i=0;i<3;i++)
 	    if(d->v[i] != a && d->b[i] != tree->e_root)
 	      {
-		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); } */
+		if(tree->io->lk_approx == EXACT) Update_Partial_Lk(tree,d->b[i],d);
+		/* if(tree->io->lk_approx == EXACT) { tree->both_sides = YES; Lk(tree); } */
 		RATES_Posterior_One_Rate(d,d->v[i],YES,tree);
 	      }
 	}
       
-      if(tree->io->lk_approx == EXACT && tree->mcmc->use_data) Update_P_Lk(tree,b,d);
-      /* if(tree->io->lk_approx == EXACT && tree->mcmc->use_data) { tree->both_sides = YES; Lk(tree); } */
+      if(tree->io->lk_approx == EXACT) Update_Partial_Lk(tree,b,d);
+      /* if(tree->io->lk_approx == EXACT) { tree->both_sides = YES; Lk(tree); } */
     }
 }
 
@@ -1805,7 +1940,7 @@ void RATES_Posterior_One_Time(t_node *a, t_node *d, int traversal, t_tree *tree)
   phydbl inflate_var;
 
   dim = 2*tree->n_otu-3;
-  num_move = tree->mcmc->num_move_nd_t+d->num-tree->n_otu;
+  num_move = tree->mcmc->num_move_times;
   inflate_var = tree->rates->inflate_var;
 
   if(d->tax) return;
@@ -1822,11 +1957,11 @@ void RATES_Posterior_One_Time(t_node *a, t_node *d, int traversal, t_tree *tree)
 
   b1 = NULL;
   if(a == tree->n_root) b1 = tree->e_root;
-  else For(i,3) if(d->v[i] == a) { b1 = d->b[i]; break; }
+  else for(i=0;i<3;i++) if(d->v[i] == a) { b1 = d->b[i]; break; }
 
   b2 = b3 = NULL;
   v2 = v3 = NULL;
-  For(i,3)
+  for(i=0;i<3;i++)
     if((d->v[i] != a) && (d->b[i] != tree->e_root))
       {
 	if(!v2) { v2 = d->v[i]; b2 = d->b[i]; }
@@ -1863,12 +1998,12 @@ void RATES_Posterior_One_Time(t_node *a, t_node *d, int traversal, t_tree *tree)
   cr = tree->rates->clock_r;
   nf = tree->rates->norm_fact;
 
-  For(i,dim) is_1[i] = 0;
+  for(i=0;i<dim;i++) is_1[i] = 0;
   is_1[b1->num] = 1;
   is_1[b2->num] = 1;
   is_1[b3->num] = 1;
 
-/*   For(i,dim)     cond_mu[i]  = 0.0; */
+/*   for(i=0;i<dim;i++)     cond_mu[i]  = 0.0; */
 /*   For(i,dim*dim) cond_cov[i] = 0.0; */
 /*   Normal_Conditional(tree->rates->mean_l,tree->rates->cov_l,tree->rates->u_cur_l,dim,is_1,3,cond_mu,cond_cov); */
   
@@ -1914,19 +2049,19 @@ void RATES_Posterior_One_Time(t_node *a, t_node *d, int traversal, t_tree *tree)
   cov33 = tree->rates->trip_cond_cov[d->num * 9 + num_3 * 3 + num_3];
 
   El1=0.0;
-  For(i,dim)
+  for(i=0;i<dim;i++)
     if(i != b1->num && i != b2->num && i != b3->num)
       El1 += tree->rates->trip_reg_coeff[d->num * (6*tree->n_otu-9) + num_1 * dim +i] * (tree->rates->u_cur_l[i] - tree->rates->mean_l[i]);
   El1 += tree->rates->mean_l[b1->num];
 
   El2=0.0;
-  For(i,dim)
+  for(i=0;i<dim;i++)
     if(i != b1->num && i != b2->num && i != b3->num)
       El2 += tree->rates->trip_reg_coeff[d->num * (6*tree->n_otu-9) + num_2 * dim +i] * (tree->rates->u_cur_l[i] - tree->rates->mean_l[i]);
   El2 += tree->rates->mean_l[b2->num];
 
   El3=0.0;
-  For(i,dim)
+  for(i=0;i<dim;i++)
     if(i != b1->num && i != b2->num && i != b3->num)
       El3 += tree->rates->trip_reg_coeff[d->num * (6*tree->n_otu-9) + num_3 * dim +i] * (tree->rates->u_cur_l[i] - tree->rates->mean_l[i]);
   El3 += tree->rates->mean_l[b3->num];
@@ -1999,10 +2134,10 @@ void RATES_Posterior_One_Time(t_node *a, t_node *d, int traversal, t_tree *tree)
       PhyML_Printf("\n. COV11=%f COV12=%f COV13=%f COV22=%f COV23=%f COV33=%f",cov11,cov12,cov13,cov22,cov23,cov33);
       PhyML_Printf("\n. constraint1: %f constraints2: %f",l2XY[1],l2XY[2]);
       PhyML_Printf("\n");
-      For(i,3)
+      for(i=0;i<3;i++)
       	{
       	  PhyML_Printf(". mu%d=%12lf\t",i,mu[i]);
-      	  For(j,3)
+      	  for(j=0;j<3;j++)
       	    {
       	      PhyML_Printf("%12lf ",cov[i*3+j]);
       	    }
@@ -2112,7 +2247,7 @@ void RATES_Posterior_One_Time(t_node *a, t_node *d, int traversal, t_tree *tree)
       /*       Exit("\n"); */
     }
   
-  if(tree->mcmc->use_data == YES)
+  if(tree->eval_alnL == YES)
     tree->rates->nd_t[d->num] = t1_new;
   else
     {
@@ -2128,28 +2263,25 @@ void RATES_Posterior_One_Time(t_node *a, t_node *d, int traversal, t_tree *tree)
   new_lnL_data = tree->c_lnL;
   new_lnL_rate = tree->rates->c_lnL_rates;
   
-  if(tree->mcmc->use_data) 
+  /* !!!!!!!!!!!!!!!!! */
+  /* tree->both_sides = NO; */
+  /* new_lnL_data = Lk(tree); */
+  
+  if(tree->io->lk_approx == EXACT)
     {
-      /* !!!!!!!!!!!!!!!!! */
-      /* tree->both_sides = NO; */
-      /* new_lnL_data = Lk(tree); */
-
-      if(tree->io->lk_approx == EXACT)
-      	{
-      	  Update_PMat_At_Given_Edge(b1,tree);
-      	  Update_PMat_At_Given_Edge(b2,tree);
-      	  Update_PMat_At_Given_Edge(b3,tree);
-      	  Update_P_Lk(tree,b1,d);
-      	}
-      new_lnL_data = Lk(b1,tree);
+      Update_PMat_At_Given_Edge(b1,tree);
+      Update_PMat_At_Given_Edge(b2,tree);
+      Update_PMat_At_Given_Edge(b3,tree);
+      Update_Partial_Lk(tree,b1,d);
     }
-  
+  new_lnL_data = Lk(b1,tree);
+
   new_lnL_rate = RATES_Lk_Rates(tree);
 
   ratio = 0.0;
 
   /* Proposal ratio */
-  if(tree->mcmc->use_data)
+  if(tree->eval_alnL)
     ratio += (Log_Dnorm_Trunc(l1,    cond_mu[0],inflate_var*SQRT(cond_cov[0*3+0]),bl_min,bl_max,&err) - 
 	      Log_Dnorm_Trunc(new_l1,cond_mu[0],inflate_var*SQRT(cond_cov[0*3+0]),bl_min,bl_max,&err));
     
@@ -2161,14 +2293,14 @@ void RATES_Posterior_One_Time(t_node *a, t_node *d, int traversal, t_tree *tree)
 
   /*   printf("\n* d:%d Ratio=%f l1=%f new_l1=%f mean=%f ml=%f sd=%f [%f %f]", */
   /* 	 d->num, */
-  /* 	 EXP(ratio), */
+  /* 	 exp(ratio), */
   /* 	 l1,new_l1, */
   /* 	 cond_mu[0], */
   /* 	 tree->rates->mean_l[b1->num], */
   /* 	 SQRT(cond_cov[0*3+0]), */
   /* 	 Log_Dnorm(l1,cond_mu[0],SQRT(cond_cov[0*3+0]),&err),Log_Dnorm(new_l1,cond_mu[0],SQRT(cond_cov[0*3+0]),&err)); */
   
-  ratio = EXP(ratio);
+  ratio = exp(ratio);
 
 
   u = Uni();
@@ -2178,12 +2310,12 @@ void RATES_Posterior_One_Time(t_node *a, t_node *d, int traversal, t_tree *tree)
       tree->rates->c_lnL_rates        = cur_lnL_rate;
       tree->c_lnL               = cur_lnL_data;
       RATES_Update_Cur_Bl(tree);
-      if(tree->io->lk_approx == EXACT && tree->mcmc->use_data) 
+      if(tree->io->lk_approx == EXACT) 
 	{
 	  Update_PMat_At_Given_Edge(b1,tree);
 	  Update_PMat_At_Given_Edge(b2,tree);
 	  Update_PMat_At_Given_Edge(b3,tree);
-	  Update_P_Lk(tree,b1,d);
+	  Update_Partial_Lk(tree,b1,d);
 	}
     }
   else
@@ -2200,14 +2332,14 @@ void RATES_Posterior_One_Time(t_node *a, t_node *d, int traversal, t_tree *tree)
       if(d->tax == YES) return;
       else
 	{
-	  For(i,3)
+	  for(i=0;i<3;i++)
 	    if(d->v[i] != a && d->b[i] != tree->e_root)
 	      {
-		if(tree->io->lk_approx == EXACT && tree->mcmc->use_data) Update_P_Lk(tree,d->b[i],d);
+		if(tree->io->lk_approx == EXACT) Update_Partial_Lk(tree,d->b[i],d);
 		RATES_Posterior_One_Time(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) Update_Partial_Lk(tree,b1,d);
     }
   
 }
@@ -2288,7 +2420,7 @@ void RATES_Posterior_Time_Root(t_tree *tree)
   if(FABS(tree->rates->t_prior_min[root->num] - tree->rates->t_prior_max[root->num]) < 1.E-10) return;
 
   cel=0.0;
-  For(i,dim) if(i != b->num) cel += tree->rates->reg_coeff[b->num*dim+i] * (tree->rates->u_cur_l[i] - tree->rates->mean_l[i]);
+  for(i=0;i<dim;i++) if(i != b->num) cel += tree->rates->reg_coeff[b->num*dim+i] * (tree->rates->u_cur_l[i] - tree->rates->mean_l[i]);
   cel += tree->rates->mean_l[b->num];
 
   cvl = tree->rates->cond_var[b->num];
@@ -2340,7 +2472,7 @@ void RATES_Posterior_Time_Root(t_tree *tree)
   cur_lnL_rate = tree->rates->c_lnL_rates;
   new_lnL_data = tree->c_lnL;
   
-  if(tree->mcmc->use_data) new_lnL_data = Lk(NULL,tree);
+  new_lnL_data = Lk(NULL,tree);
     
   ratio = 0.0;
   /* Prior ratio */
@@ -2348,7 +2480,7 @@ void RATES_Posterior_Time_Root(t_tree *tree)
   /* Likelihood ratio */
   ratio += new_lnL_data - cur_lnL_data;
 
-  ratio = EXP(ratio);
+  ratio = exp(ratio);
   u = Uni();
   if(u > MIN(1.,ratio))
     {
@@ -2358,35 +2490,35 @@ void RATES_Posterior_Time_Root(t_tree *tree)
     }
   else
     {
-      tree->mcmc->acc_move[tree->mcmc->num_move_nd_t]++;
+      tree->mcmc->acc_move[tree->mcmc->num_move_times]++;
     }
 
   RATES_Update_Norm_Fact(tree);
   RATES_Update_Cur_Bl(tree);
 
-  tree->mcmc->run_move[tree->mcmc->num_move_nd_t]++;
-  tree->mcmc->acc_rate[tree->mcmc->num_move_nd_t] = 
-    (tree->mcmc->acc_move[tree->mcmc->num_move_nd_t]+1.E-6)/ 
-    (tree->mcmc->run_move[tree->mcmc->num_move_nd_t]+1.E+6);
+  tree->mcmc->run_move[tree->mcmc->num_move_times]++;
+  tree->mcmc->acc_rate[tree->mcmc->num_move_times] = 
+    (tree->mcmc->acc_move[tree->mcmc->num_move_times]+1.E-6)/ 
+    (tree->mcmc->run_move[tree->mcmc->num_move_times]+1.E-6);
 
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void RATES_Update_Cur_Bl(t_tree *tree)
 {
-  RATES_Update_Norm_Fact(tree);
+
+  /* RATES_Update_Norm_Fact(tree); */
   RATES_Update_Cur_Bl_Pre(tree->n_root,tree->n_root->v[2],NULL,tree);
   RATES_Update_Cur_Bl_Pre(tree->n_root,tree->n_root->v[1],NULL,tree);
   
   if(tree->mod && tree->mod->log_l == YES)
     {
       tree->e_root->l->v = 
-	EXP(tree->rates->cur_l[tree->n_root->v[2]->num]) +
-	EXP(tree->rates->cur_l[tree->n_root->v[1]->num]) ;
-      tree->e_root->l->v = LOG(tree->e_root->l->v);
+	exp(tree->rates->cur_l[tree->n_root->v[2]->num]) +
+	exp(tree->rates->cur_l[tree->n_root->v[1]->num]) ;
+      tree->e_root->l->v = log(tree->e_root->l->v);
     }
   else
     {
@@ -2397,7 +2529,7 @@ void RATES_Update_Cur_Bl(t_tree *tree)
 
   tree->rates->u_cur_l[tree->e_root->num] = tree->e_root->l->v;
   tree->n_root_pos = tree->rates->cur_l[tree->n_root->v[2]->num] / tree->e_root->l->v;
-
+  
   if(tree->rates->model == GUINDON)
     {
       phydbl t0,t1,t2;
@@ -2423,6 +2555,8 @@ void RATES_Update_Cur_Bl(t_tree *tree)
       /* 	     tree->rates->cur_gamma_prior_mean[n1->num], */
       /* 	     tree->rates->cur_gamma_prior_var[n1->num]); */
     }
+
+  if(tree->is_mixt_tree == YES) MIXT_RATES_Update_Cur_Bl(tree);
 }
 
 //////////////////////////////////////////////////////////////
@@ -2432,6 +2566,9 @@ void RATES_Update_Cur_Bl_Pre(t_node *a, t_node *d, t_edge *b, t_tree *tree)
 {
   phydbl dt,rr,cr,ra,rd,ta,td,nu;
 
+  assert(a);
+  assert(d);
+
   tree->rates->br_do_updt[d->num] = YES;
 
   if(tree->rates->br_do_updt[d->num] == YES)
@@ -2445,21 +2582,29 @@ void RATES_Update_Cur_Bl_Pre(t_node *a, t_node *d, t_edge *b, t_tree *tree)
       td = tree->rates->nd_t[d->num];
       ta = tree->rates->nd_t[a->num];
       nu = tree->rates->nu;
-
-
-      if(tree->rates->model_log_rates == YES)
-	{
-	  /* Artihmetic average */
-	  rr = (EXP(ra) + EXP(rd))/2.;
-	}
-      else
-	{
-	  rr = (ra+rd)/2.;
-	}
-
-      tree->rates->cur_l[d->num] = dt*rr*cr;
+      rr = -1.0;
+      
+      if(tree->rates->model == GAMMA)
+        {
+          rr = rd;
+          tree->rates->cur_l[d->num] = dt*rr*cr;          
+        }
+
+      if(tree->rates->model == THORNE)
+        {
+          if(tree->rates->model_log_rates == YES)
+            {
+              /* Artihmetic average */
+              rr = (exp(ra) + exp(rd))/2.;
+            }
+          else
+            {
+              rr = (ra+rd)/2.;
+            }
+          
+          tree->rates->cur_l[d->num] = dt*rr*cr;
+        }
       
-
       if(tree->rates->model == GUINDON)
 	{
 	  phydbl m,v;
@@ -2475,7 +2620,7 @@ void RATES_Update_Cur_Bl_Pre(t_node *a, t_node *d, t_edge *b, t_tree *tree)
 	  tree->rates->cur_l[d->num] = tree->rates->cur_gamma_prior_mean[d->num]; // Required for having proper branch lengths in Write_Tree function
 	}
       
-      if(tree->mod && tree->mod->log_l == YES) tree->rates->cur_l[d->num] = LOG(tree->rates->cur_l[d->num]);
+      if(tree->mod && tree->mod->log_l == YES) tree->rates->cur_l[d->num] = log(tree->rates->cur_l[d->num]);
       
       if(b)
 	{
@@ -2487,10 +2632,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");
 	}
     }
@@ -2499,7 +2642,7 @@ void RATES_Update_Cur_Bl_Pre(t_node *a, t_node *d, t_edge *b, t_tree *tree)
   else
     {
       int i;
-      For(i,3) 
+      for(i=0;i<3;i++) 
 	if((d->v[i] != a) && (d->b[i] != tree->e_root)) 
 	  RATES_Update_Cur_Bl_Pre(d,d->v[i],d->b[i],tree);
     }
@@ -2534,7 +2677,7 @@ void RATES_Bl_To_Bl_Pre(t_node *a, t_node *d, t_edge *b, t_tree *tree)
     {
       int i;
 
-      For(i,3) 
+      for(i=0;i<3;i++) 
 	if((d->v[i] != a) && (d->b[i] != tree->e_root)) 
 	  RATES_Bl_To_Bl_Pre(d,d->v[i],d->b[i],tree);
     }
@@ -2569,7 +2712,7 @@ void RATES_Bl_To_Ml_Pre(t_node *a, t_node *d, t_edge *b, t_tree *tree)
     {
       int i;
 
-      For(i,3) 
+      for(i=0;i<3;i++) 
 	if((d->v[i] != a) && (d->b[i] != tree->e_root)) 
 	  RATES_Bl_To_Ml_Pre(d,d->v[i],d->b[i],tree);
     }
@@ -2607,7 +2750,7 @@ void RATES_Get_Cov_Matrix_Rooted_Pre(t_node *a, t_node *d, t_edge *b, phydbl *co
   dim       = 2*tree->n_otu-3;
   n         = NULL;
 
-  For(i,dim) 
+  for(i=0;i<dim;i++) 
     { 
       if(tree->a_edges[i] != tree->e_root)
 	{
@@ -2645,7 +2788,7 @@ void RATES_Get_Cov_Matrix_Rooted_Pre(t_node *a, t_node *d, t_edge *b, phydbl *co
   if(d->tax) return;
   else
     {
-      For(i,3)
+      for(i=0;i<3;i++)
 	if((d->v[i] != a) && (d->b[i] != tree->e_root)) 
 	  RATES_Get_Cov_Matrix_Rooted_Pre(d,d->v[i],d->b[i],cov,tree);
     }
@@ -2678,7 +2821,7 @@ void RATES_Covariance_Mu(t_tree *tree)
   RATES_Variance_Mu_Pre(tree->n_root,tree->n_root->v[2],tree);
   RATES_Variance_Mu_Pre(tree->n_root,tree->n_root->v[1],tree);
 
-  For(i,dim)
+  for(i=0;i<dim;i++)
     {
       for(j=i+1;j<dim;j++)
 	{
@@ -2720,7 +2863,7 @@ void RATES_Variance_Mu_Pre(t_node *a, t_node *d, t_tree *tree)
   if(d->tax) return;
 
   dir1 = dir2 = -1;
-  For(i,3)
+  for(i=0;i<3;i++)
     {
       if((d->v[i] != a) && (d->b[i] != tree->e_root))
 	{
@@ -2742,7 +2885,7 @@ void RATES_Variance_Mu_Pre(t_node *a, t_node *d, t_tree *tree)
   tree->rates->cov_r[d->v[dir2]->num*dim+d->v[dir2]->num] = var0+var2;
 
 
-  For(i,3)
+  for(i=0;i<3;i++)
     {
       if((d->v[i] != a) && (d->b[i] != tree->e_root))
 	{
@@ -2761,7 +2904,7 @@ void RATES_Fill_Lca_Table(t_tree *tree)
   
   dim = 2*tree->n_otu-1;
 
-  For(i,dim)
+  for(i=0;i<dim;i++)
     {
       for(j=i;j<dim;j++)
 	{
@@ -2791,17 +2934,17 @@ void RATES_Get_Conditional_Variances(t_tree *tree)
   cond_mu  = tree->rates->_2n_vect2;
   cond_cov = tree->rates->_2n2n_vect1;
 
-  For(i,dim) a[i] = tree->rates->mean_l[i] * (Uni() * 0.2 + 0.9);
+  for(i=0;i<dim;i++) a[i] = tree->rates->mean_l[i] * (Uni() * 0.2 + 0.9);
 
-  For(i,dim)
+  for(i=0;i<dim;i++)
     {
       b = tree->a_edges[i];
 
-      For(j,dim) is_1[j] = 0;
+      for(j=0;j<dim;j++) is_1[j] = 0;
       is_1[b->num]       = 1;
 
       For(j,dim*dim) cond_cov[j] = 0.0;
-      For(j,dim)     cond_mu[j]  = 0.0;
+      for(j=0;j<dim;j++)     cond_mu[j]  = 0.0;
       Normal_Conditional(tree->rates->mean_l,tree->rates->cov_l,a,dim,is_1,1,cond_mu,cond_cov);
       
       tree->rates->cond_var[b->num] = cond_cov[b->num*dim+b->num];
@@ -2825,13 +2968,13 @@ void RATES_Get_All_Reg_Coeff(t_tree *tree)
   is_1 = tree->rates->_2n_vect5;
   b    = NULL;
 
-  For(i,dim) a[i] = tree->rates->mean_l[i] * (Uni() * 0.2 + 0.9);
+  for(i=0;i<dim;i++) a[i] = tree->rates->mean_l[i] * (Uni() * 0.2 + 0.9);
 
-  For(i,dim)
+  for(i=0;i<dim;i++)
     {
       b = tree->a_edges[i];
 
-      For(j,dim) is_1[j] = 0;
+      for(j=0;j<dim;j++) is_1[j] = 0;
       is_1[b->num]       = 1;
       
       Get_Reg_Coeff(tree->rates->mean_l,tree->rates->cov_l,a,dim,is_1,1,tree->rates->reg_coeff+b->num*dim);
@@ -2873,7 +3016,7 @@ void RATES_Get_Trip_Conditional_Variances(t_tree *tree)
 	  
 	  Normal_Conditional_Unsorted(tree->rates->mean_l,tree->rates->cov_l,a,2*n_otu-3,is_1,3,cond_mu,cond_cov);
 	  
-	  For(j,9) tree->rates->trip_cond_cov[n->num*9+j] = cond_cov[j];
+	  for(j=0;j<9;j++) tree->rates->trip_cond_cov[n->num*9+j] = cond_cov[j];
 	}
     }
 }
@@ -2915,7 +3058,6 @@ void RATES_Get_All_Trip_Reg_Coeff(t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void RATES_Check_Lk_Rates(t_tree *tree, int *err)
 {
   int i;
@@ -2996,7 +3138,7 @@ void RATES_Expected_Tree_Length_Pre(t_node *a, t_node *d, phydbl eranc, phydbl *
 
   if(d->tax) return;
   else
-    For(i,3)
+    for(i=0;i<3;i++)
       if(d->v[i] != a && d->b[i] != tree->e_root)
 	RATES_Expected_Tree_Length_Pre(d,d->v[i],erdes,mean,n,tree);
 }
@@ -3004,38 +3146,31 @@ void RATES_Expected_Tree_Length_Pre(t_node *a, t_node *d, phydbl eranc, phydbl *
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void RATES_Update_Norm_Fact(t_tree *tree)
 {
-  int i;
-  phydbl r,t,t_anc;
-  phydbl num,denom;
+  /* int i; */
+  /* phydbl r,t,t_anc; */
+  /* phydbl num,denom; */
   
-  num = denom = 0.0;
+  /* num = denom = 0.0; */
 
-  For(i,2*tree->n_otu-2)
-    {
-      r     = tree->rates->br_r[i];
-      t     = tree->rates->nd_t[i];
-      t_anc = tree->rates->nd_t[tree->a_nodes[i]->anc->num];
-
-      num   += (t-t_anc);
-      denom += (t-t_anc) * r;
+  /* For(i,2*tree->n_otu-2) */
+  /*   { */
+  /*     r     = tree->rates->br_r[i]; */
+  /*     t     = tree->rates->nd_t[i]; */
+  /*     t_anc = tree->rates->nd_t[tree->a_nodes[i]->anc->num]; */
 
-    }
-  tree->rates->norm_fact = num/denom;
+  /*     num   += (t-t_anc); */
+  /*     denom += (t-t_anc) * r; */
+  /*   } */
+  /* tree->rates->norm_fact = num/denom; */
 
-  /* !!!!!!!!!!!!!!!!!! */
   tree->rates->norm_fact = 1.0;
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
 void RATES_Normalise_Rates(t_tree *tree)
 {
   phydbl expr,curr;
@@ -3218,7 +3353,7 @@ void RATES_Min_Max_Interval(phydbl u0, phydbl u1, phydbl u2, phydbl u3, phydbl t
   cdf = (phydbl *)mCalloc(n_eval,sizeof(phydbl));
 
   sum_cdf = .0;
-  For(i,n_eval)
+  for(i=0;i<n_eval;i++)
     {
       t1 = t0 + (i + 1)*(mint2t3 - t0)/(n_eval + 1);
       cdf[i] = 
@@ -3230,19 +3365,19 @@ void RATES_Min_Max_Interval(phydbl u0, phydbl u1, phydbl u2, phydbl u3, phydbl t
     }
   sum_cdf = cdf[i-1];
 
-  For(i,n_eval) cdf[i] /= sum_cdf;
+  for(i=0;i<n_eval;i++) cdf[i] /= sum_cdf;
 
 /*   PhyML_Printf("\n"); */
-/*   For(i,n_eval) PhyML_Printf("\n* %f %f",cdf[i],sum_cdf); */
+/*   for(i=0;i<n_eval;i++) PhyML_Printf("\n* %f %f",cdf[i],sum_cdf); */
 
-  For(i,n_eval) 
+  for(i=0;i<n_eval;i++) 
     if(cdf[i] > p_thresh)
       {
 	*t_min = t0 + (i + 1)*(mint2t3 - t0)/(n_eval + 1);
 	break;
       }
 
-  For(i,n_eval) 
+  for(i=0;i<n_eval;i++) 
     if(cdf[i] > (1. - p_thresh))
       {
 	*t_max = t0 + (i + 1)*(mint2t3 - t0)/(n_eval + 1);
@@ -3344,7 +3479,6 @@ phydbl Sample_Average_Rate(t_node *a, t_node *d, t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void RATES_Update_Mean_Br_Len(int iter, t_tree *tree)
 {
   int i,dim;
@@ -3355,7 +3489,7 @@ void RATES_Update_Mean_Br_Len(int iter, t_tree *tree)
   dim = 2*tree->n_otu-3;
   mean = tree->rates->mean_l;
 
-  For(i,dim)
+  for(i=0;i<dim;i++)
     {      
      mean[i] *= (phydbl)iter;
      mean[i] += tree->a_edges[i]->l->v;
@@ -3378,9 +3512,9 @@ void RATES_Update_Cov_Br_Len(int iter, t_tree *tree)
   mean = tree->rates->mean_l;
   cov  = tree->rates->cov_l;
 
-  For(i,dim)
+  for(i=0;i<dim;i++)
     {     
-      For(j,dim)
+      for(j=0;j<dim;j++)
 	{
 	  cov[i*dim+j] += mean[i]*mean[j];
 	  cov[i*dim+j] *= (phydbl)tree->mcmc->run;
@@ -3396,7 +3530,6 @@ void RATES_Update_Cov_Br_Len(int iter, t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void RATES_Set_Mean_L(t_tree *tree)
 {
   int i;
@@ -3409,36 +3542,49 @@ void RATES_Set_Mean_L(t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
-void RATES_Record_Times(t_tree *tree)
+void RATES_Record_Times(t_tree *mixt_tree)
 {
   int i;
+  t_tree *tree;
 
-  if(tree->rates->nd_t_recorded == YES)
+  tree = mixt_tree;
+  do
     {
-      PhyML_Printf("\n. Overwriting recorded times is forbidden.\n");
-      PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__);
-      Exit("\n");
-    }
+      if(tree->rates->nd_t_recorded == YES)
+        {
+          PhyML_Printf("\n== Overwriting recorded times is forbidden.\n");
+          PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__);
+          Exit("\n");
+        }
 
-  For(i,2*tree->n_otu-1) tree->rates->buff_t[i] = tree->rates->nd_t[i];
+      For(i,2*tree->n_otu-1) tree->rates->buff_t[i] = tree->rates->nd_t[i];
+      tree = tree->next;
+    }
+  while(tree);
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
 
-void RATES_Reset_Times(t_tree *tree)
+void RATES_Reset_Times(t_tree *mixt_tree)
 {
   int i;
-  tree->rates->nd_t_recorded = NO;
-  For(i,2*tree->n_otu-1) tree->rates->nd_t[i] = tree->rates->buff_t[i];
+  t_tree *tree;
+
+  tree = mixt_tree;
+  do
+    {
+      tree->rates->nd_t_recorded = NO;
+      For(i,2*tree->n_otu-1) tree->rates->nd_t[i] = tree->rates->buff_t[i];
+      tree = tree->next;
+    }
+  while(tree);
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void RATES_Record_Rates(t_tree *tree)
 {
   int i;
@@ -3486,7 +3632,7 @@ void RATES_Set_Clock_And_Nu_Max(t_tree *tree)
       
       if(tree->rates->model_log_rates == NO)
 	{
-	  r_max = LOG(tree->rates->max_rate);
+	  r_max = log(tree->rates->max_rate);
 	}
       else
 	{
@@ -3539,8 +3685,8 @@ void RATES_Set_Birth_Rate_Boundaries(t_tree *tree)
 
   for(lbda = 0.0001; lbda < 10; lbda+=0.0001)
     {
-      p_above_min = 1. - POW(1.-EXP(-lbda*min),tree->n_otu);
-      p_below_max = POW(1.-EXP(-lbda*max),tree->n_otu);
+      p_above_min = 1. - POW(1.-exp(-lbda*min),tree->n_otu);
+      p_below_max = POW(1.-exp(-lbda*max),tree->n_otu);
  
       if(p_above_min < 1.E-10) 
 	{ 
@@ -3565,7 +3711,6 @@ void RATES_Set_Birth_Rate_Boundaries(t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void RATES_Write_Mean_R_On_Edge_Label(t_node *a, t_node *d, t_edge *b, t_tree *tree)
 {
 
@@ -3583,7 +3728,7 @@ void RATES_Write_Mean_R_On_Edge_Label(t_node *a, t_node *d, t_edge *b, t_tree *t
   else
     {
       int i;
-      For(i,3)
+      for(i=0;i<3;i++)
 	{
 	  if((d->v[i] != a) && (d->b[i] != tree->e_root))
 	    {
@@ -3596,12 +3741,6 @@ void RATES_Write_Mean_R_On_Edge_Label(t_node *a, t_node *d, t_edge *b, t_tree *t
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
 phydbl RATES_Get_Mean_Rate_In_Subtree(t_node *root, t_tree *tree)
 {
   phydbl sum;
@@ -3620,7 +3759,7 @@ phydbl RATES_Get_Mean_Rate_In_Subtree(t_node *root, t_tree *tree)
       else
 	{
 	  int i;
-	  For(i,3)
+	  for(i=0;i<3;i++)
 	    {
 	      if(root->v[i] != root->anc && root->b[i] != tree->e_root)
 		{
@@ -3633,9 +3772,7 @@ phydbl RATES_Get_Mean_Rate_In_Subtree(t_node *root, t_tree *tree)
   else
     {
       return 0.0;
-    }
-  
-  
+    }  
 }
 
 //////////////////////////////////////////////////////////////
@@ -3644,14 +3781,14 @@ phydbl RATES_Get_Mean_Rate_In_Subtree(t_node *root, t_tree *tree)
 
 void RATES_Get_Mean_Rate_In_Subtree_Pre(t_node *a, t_node *d, phydbl *sum, int *n, t_tree *tree)
 {
-  (*sum) += EXP(tree->rates->nd_r[d->num]);
+  (*sum) += exp(tree->rates->nd_r[d->num]);
   (*n)   += 1;
 
   if(d->tax == YES)  return;
   else
     {
       int i;
-      For(i,3)
+      for(i=0;i<3;i++)
 	{
 	  if(d->v[i] != a && d->b[i] != tree->e_root)
 	    {
diff --git a/src/rates.h b/src/rates.h
index bb28760..88b32ee 100644
--- a/src/rates.h
+++ b/src/rates.h
@@ -179,5 +179,7 @@ void RATES_Get_Survival_Ranks(t_tree *tree);
 void RATES_Bl_To_Bl(t_tree *tree);
 void RATES_Bl_To_Bl_Pre(t_node *a, t_node *d, t_edge *b, t_tree *tree);
 void RATES_Set_Birth_Rate_Boundaries(t_tree *tree);
+void RATES_Copy_Rate_Struct(t_rate *from, t_rate *to, int n_otu);
+void RATES_Duplicate_Calib_Struct(t_tree *from, t_tree *to);
 
 #endif
diff --git a/src/rwrapper.c b/src/rwrapper.c
index 7b41cc6..e53a9a8 100644
--- a/src/rwrapper.c
+++ b/src/rwrapper.c
@@ -32,13 +32,13 @@
 
 /*   tree->io->z_scores = (phydbl *)mCalloc(tree->n_otu,sizeof(phydbl)); */
 
-/*   /\\* For(i,tree->n_otu) tree->io->z_scores[i] = TIPO_Read_One_Taxon_Zscore(fp_coord_file,tree->noeud[i]->name,1,tree); *\\/ */
+/*   /\\* for(i=0;i<tree->n_otu;i++) tree->io->z_scores[i] = TIPO_Read_One_Taxon_Zscore(fp_coord_file,tree->noeud[i]->name,1,tree); *\\/ */
 /*   /\\* TIPO_Normalize_Zscores(tree); *\\/ */
 /*   /\\* TIPO_Get_Min_Number_Of_Tip_Permut(tree); *\\/ */
 /*   /\\* res[0] = (phydbl)tree->tip_order_score; *\\/ */
 
 
-/*   For(i,tree->n_otu) tree->io->z_scores[i] = TIPO_Read_One_Taxon_Zscore(fp_coord_file,tree->a_nodes[i]->name,1,tree); */
+/*   for(i=0;i<tree->n_otu;i++) tree->io->z_scores[i] = TIPO_Read_One_Taxon_Zscore(fp_coord_file,tree->a_nodes[i]->name,1,tree); */
 /*   Free_Bip(tree); */
 /*   Alloc_Bip(tree); */
 /*   Get_Bip(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree); */
@@ -53,7 +53,7 @@
 /* 		   NULL,tree,NULL); */
 
 /*   res[0] = (phydbl)tree->geo_mig_sd; */
-/*   /\\* For(i,tree->n_otu) Rprintf("\n.. %f",tree->io->z_scores[i]); *\\/ */
+/*   /\\* for(i=0;i<tree->n_otu;i++) Rprintf("\n.. %f",tree->io->z_scores[i]); *\\/ */
 /*   /\\* printf("\n>> sd: %f",tree->geo_mig_sd); *\\/ */
 
 /*   fclose(fp_tree_file); */
diff --git a/src/simu.c b/src/simu.c
index 57e9f87..9bbda10 100644
--- a/src/simu.c
+++ b/src/simu.c
@@ -19,36 +19,10 @@ 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;
-
-  SPR_Shuffle(mixt_tree);
-
-  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);
-
-  int n_tot_moves = 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;
-    }
-  while(mixt_tree->c_lnL > lk_old + mixt_tree->mod->s_opt->min_diff_lk_local);
-
-  do
-    {
-      Round_Optimize(mixt_tree,mixt_tree->data,ROUND_MAX);
-      if(!Check_NNI_Five_Branches(mixt_tree)) break;
-    }
-  while(1);
-
-  if((mixt_tree->mod->s_opt->print) &&
-     (!mixt_tree->io->quiet)) PhyML_Printf("\n");
+  Spr_List_Of_Trees(tree);
+  return;
 }
 
 //////////////////////////////////////////////////////////////
@@ -56,105 +30,155 @@ void Simu_Loop(t_tree *mixt_tree)
 
 int Simu(t_tree *tree, int n_step_max)
 {
-  phydbl old_loglk,n_iter,lambda;
-  int i,n_neg,n_tested,n_without_swap,n_tot_swap,step,it_lim_without_swap;
-  t_edge **sorted_b,**tested_b;
-
-  sorted_b = (t_edge **)mCalloc(tree->n_otu-3,sizeof(t_edge *));
-  tested_b = (t_edge **)mCalloc(tree->n_otu-3,sizeof(t_edge *));
-
-  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;
-  step                = 0;
-  lambda              = .75;
-  n_tot_swap          = 0;
-
-  Update_Dirs(tree);
-
-  if(tree->lock_topo)
-    {
-      PhyML_Printf("\n== The tree topology is locked.");
-      PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__);
-      Warn_And_Exit("");
-    }
-
+  phydbl old_loglk,delta;
+  unsigned int n_round;
+  
+  tree->c_lnL = UNLIKELY;
+  delta = UNLIKELY;
+  old_loglk = UNLIKELY;
+  n_round = 0;
+  tree->annealing_temp = 0.0;
   do
     {
-      ++step;
-
-      if(n_tested || step == 1) MIXT_Set_Alias_Subpatt(YES,tree);
       old_loglk = tree->c_lnL;
-      Set_Both_Sides(YES,tree);
+      Set_Both_Sides(NO,tree);
       Lk(NULL,tree);
-      MIXT_Set_Alias_Subpatt(NO,tree);
+      NNI_Traversal(tree->a_nodes[0],
+                    tree->a_nodes[0]->v[0],
+                    NULL,
+                    tree->a_nodes[0]->b[0],
+                    tree);
+      delta = tree->c_lnL - old_loglk;
+      tree->annealing_temp -= 1.0;
+      /* PhyML_Printf("\n. lnL: %15f",tree->c_lnL); */
+      if(tree->annealing_temp < 0.0) tree->annealing_temp = 0.0;
+      n_round++;
+      if(n_round == n_step_max) break;
+    }
+  while(delta > 1.0 || Are_Equal(tree->annealing_temp,0.0,1.E-3) == NO || n_round < 5);
+
+  return 1;
+                
+
+  /* phydbl old_loglk,n_iter,lambda; */
+  /* int i,n_neg,n_tested,n_without_swap,n_tot_swap,step,it_lim_without_swap; */
+  /* t_edge **sorted_b,**tested_b; */
+
+  /* sorted_b = (t_edge **)mCalloc(tree->n_otu-3,sizeof(t_edge *)); */
+  /* tested_b = (t_edge **)mCalloc(tree->n_otu-3,sizeof(t_edge *)); */
+
+  /* old_loglk           = UNLIKELY; */
+  /* tree->c_lnL         = UNLIKELY; */
+  /* n_iter              = 1.0; */
+  /* it_lim_without_swap = (tree->mod->ras->invar)?(1):(1); */
+  /* n_tested            = 0; */
+  /* n_without_swap      = 0; */
+  /* step                = 0; */
+  /* lambda              = 0.75; */
+  /* n_tot_swap          = 0; */
+
+  /* Update_Dirs(tree); */
+
+  /* if(tree->lock_topo) */
+  /*   { */
+  /*     PhyML_Printf("\n== The tree topology is locked."); */
+  /*     PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__); */
+  /*     Warn_And_Exit(""); */
+  /*   } */
+  
+  /* Set_Both_Sides(NO,tree); */
+  /* Lk(NULL,tree); */
+  /* Optimize_Br_Len_Serie(tree); */
+  
+  /* do */
+  /*   { */
+  /*     ++step; */
 
-      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(!tree->n_swap) n_neg = 0;
-          Record_Br_Len(tree);
-          Set_Both_Sides(YES,tree);
-          Lk(NULL,tree);
-        }
+  /*     if(n_tested || step == 1) MIXT_Set_Alias_Subpatt(YES,tree); */
 
-      if(step > n_step_max) break;
+  /*     old_loglk = tree->c_lnL; */
 
-      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) Print_Site_Lk(tree,tree->io->fp_out_lk); fflush(tree->io->fp_out_lk);
-          Free(s);
-        }
+  /*     Set_Both_Sides(YES,tree); */
+  /*     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 && step > 1) */
+  /*       { */
+  /*         if(tree->verbose > VL2 && tree->io->quiet == NO) PhyML_Printf("\n\n. Moving backward\n"); */
+
+  /*         if(!Mov_Backward_Topo_Bl(tree,old_loglk,tested_b,n_tested)) */
+  /*           { */
+  /*             PhyML_Printf("\n== tree->c_lnL: %f old_loglk: %f",tree->c_lnL,old_loglk); */
+  /*             Generic_Exit(__FILE__,__LINE__,__FUNCTION__); */
+  /*           } */
+  /*         if(!tree->n_swap) n_neg = 0; */
+  /*         Record_Br_Len(tree); */
+  /*         Set_Both_Sides(YES,tree); */
+  /*         Lk(NULL,tree); */
+  /*       } */
+
+  /*     if(step > n_step_max) break; */
+
+  /*     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) 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);  */
+
+  /*     if(tree->verbose > VL2 && tree->io->quiet == NO) Print_Lk(tree,"[Topology           ]"); */
+      
+  /*     if((FABS(old_loglk-tree->c_lnL) < tree->mod->s_opt->min_diff_lk_global) || (n_without_swap > it_lim_without_swap)) break; */
 
-      if((tree->mod->s_opt->print) && (!tree->io->quiet)) Print_Lk(tree,"[Topology           ]");
+  /*     Update_Dirs(tree); */
 
-/*       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;
+  /*     Fix_All(tree); */
 
-      Fill_Dir_Table(tree);
-      Fix_All(tree);
-      n_neg = 0;
-      For(i,2*tree->n_otu-3)
-        if((!tree->a_edges[i]->left->tax) &&
-           (!tree->a_edges[i]->rght->tax))
-          NNI(tree,tree->a_edges[i],0);
+  /*     For(i,2*tree->n_otu-3) */
+  /*       if((!tree->a_edges[i]->left->tax) && (!tree->a_edges[i]->rght->tax)) */
+  /*         NNI(tree,tree->a_edges[i],NO); */
 
-      Select_Edges_To_Swap(tree,sorted_b,&n_neg);
-      Sort_Edges_NNI_Score(tree,sorted_b,n_neg);
-      Optimiz_Ext_Br(tree);
-      Update_Bl(tree,lambda);
+  /*     n_neg = 0; */
+  /*     Select_Edges_To_Swap(tree,sorted_b,&n_neg); */
+  /*     Sort_Edges_NNI_Score(tree,sorted_b,n_neg); */
+  /*     Optimiz_Ext_Br(tree); */
+  /*     Update_Bl(tree,lambda); */
 
-      n_tested = 0;
-      For(i,(int)CEIL((phydbl)n_neg*(lambda)))
-        tested_b[n_tested++] = sorted_b[i];
+  /*     n_tested = 0; */
+  /*     For(i,(int)CEIL((phydbl)n_neg*(lambda))) */
+  /*       tested_b[n_tested++] = sorted_b[i]; */
 
-      Make_N_Swap(tree,tested_b,0,n_tested);
+  /*     Make_N_Swap(tree,tested_b,0,n_tested); */
 
-      if((tree->mod->s_opt->print) && (!tree->io->quiet)) PhyML_Printf("[# nnis=%3d]",n_tested);
 
-      n_tot_swap += n_tested;
+  /*     if((tree->verbose > VL2) && (tree->io->quiet == NO)) PhyML_Printf("[# nnis=%3d]",n_tested); */
 
-      if(n_tested > 0) n_without_swap = 0;
-      else             n_without_swap++;
+  /*     n_tot_swap += n_tested; */
 
-      n_iter+=1.0;
-    }
-  while(1);
+  /*     if(n_tested > 0) n_without_swap = 0; */
+  /*     else             n_without_swap++; */
 
-/*   Round_Optimize(tree,tree->data); */
+  /*     n_iter+=1.0; */
+  /*   } */
+  /* while(1); */
 
-  Free(sorted_b);
-  Free(tested_b);
+  /* Free(sorted_b); */
+  /* Free(tested_b); */
 
-  return n_tot_swap;
+  /* return n_tot_swap; */
 }
 
 //////////////////////////////////////////////////////////////
@@ -178,12 +202,12 @@ void Simu_Pars(t_tree *tree, int n_step_max)
   n_without_swap      = 0;
   step                = 0;
   each                = 4;
-  lambda              = .75;
+  lambda              = 0.5;
   n_tot_swap          = 0;
 
   Update_Dirs(tree);
 
-  if((tree->mod->s_opt->print) && (!tree->io->quiet)) PhyML_Printf("\n\n. Starting simultaneous NNI moves (parsimony criterion)...\n");
+  if((tree->verbose > VL0) && (tree->io->quiet == NO)) PhyML_Printf("\n\n. Starting simultaneous NNI moves (parsimony criterion)...\n");
 
   do
     {
@@ -196,7 +220,7 @@ void Simu_Pars(t_tree *tree, int n_step_max)
       Set_Both_Sides(YES,tree);
       Pars(NULL,tree);
       
-      if((tree->mod->s_opt->print) && (!tree->io->quiet))
+      if((tree->verbose > VL0) && (tree->io->quiet == NO))
         {
           Print_Pars(tree);
           if(step > 1) (n_tested > 1)?(printf("[%4d NNIs]",n_tested)):(printf("[%4d NNI ]",n_tested));
@@ -207,21 +231,18 @@ void Simu_Pars(t_tree *tree, int n_step_max)
       
       if((tree->c_pars > old_pars) && (step > 1))
         {
-          if((tree->mod->s_opt->print) && (!tree->io->quiet))
-            PhyML_Printf("\n\n. Moving backward (topoLlogy) \n");
+          if(tree->verbose > VL0 && tree->io->quiet == NO)
+            PhyML_Printf("\n\n. Moving backward (topology) \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)
@@ -258,23 +279,42 @@ void Select_Edges_To_Swap(t_tree *tree, t_edge **sorted_b, int *n_neg)
 {
   int i;
   t_edge *b;
-  phydbl best_score;
+  /* phydbl best_score; */
 
   *n_neg = 0;
 
   For(i,2*tree->n_otu-3)
     {
       b = tree->a_edges[i];
-      best_score = b->nni->score;
+      /* best_score = b->nni->score; */
       
       if((!b->left->tax) && (!b->rght->tax) && (b->nni->score < -tree->mod->s_opt->min_diff_lk_move))
         {
-          Check_NNI_Scores_Around(b->left,b->rght,b,&best_score,tree);
-          Check_NNI_Scores_Around(b->rght,b->left,b,&best_score,tree);
-          if(best_score < b->nni->score) continue;
+          /* // Evaluate NNIs on edges at distance 1 */
+          /* Check_NNI_Scores_Around(b->left,b->rght,b,&best_score,tree); */
+          /* Check_NNI_Scores_Around(b->rght,b->left,b,&best_score,tree);           */
+          
+          /* // Evaluate NNIs on edges at distance 2 */
+          /* Check_NNI_Scores_Around(b->left,b->left->v[b->l_v1],b,&best_score,tree); */
+          /* Check_NNI_Scores_Around(b->left,b->left->v[b->l_v2],b,&best_score,tree); */
+
+          /* // Evaluate NNIs on edges at distance 2 */
+          /* Check_NNI_Scores_Around(b->rght,b->rght->v[b->r_v1],b,&best_score,tree); */
+          /* Check_NNI_Scores_Around(b->rght,b->rght->v[b->r_v2],b,&best_score,tree); */
+
+          /* if(best_score < b->nni->score) continue; */
+
           sorted_b[*n_neg] = b;
           (*n_neg)++;
         }
+
+
+      /* if((!b->left->tax) && (!b->rght->tax) && (b->nni->score < -tree->mod->s_opt->min_diff_lk_move)) */
+      /*   { */
+      /*     sorted_b[*n_neg] = b; */
+      /*     (*n_neg)++; */
+      /*   } */
+
     }
 }
 
@@ -285,65 +325,84 @@ 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;
+
+      n1 = b[i]->nni->swap_node_v1;
+      n2 = b[i]->nni->swap_node_v2;
+      n3 = b[i]->nni->swap_node_v3;
+      n4 = b[i]->nni->swap_node_v4;
+
+      /* 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]; */
+      /*   } */
+
+      if(b[i]->nni->best_conf == 1)
+        {
+          if(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]) continue;
+        }
+      else if(b[i]->nni->best_conf == 2)
+        {
+          if(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]) continue;
+        }
+            
+      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(n4,n2,n3,n1,tree);
         }
       
       if(tree->n_root)
@@ -352,16 +411,18 @@ 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 +434,77 @@ 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);
+      /* n1 = b->nni->swap_node_v1; */
+      /* n2 = b->nni->swap_node_v2; */
+      /* n3 = b->nni->swap_node_v3; */
+      /* n4 = b->nni->swap_node_v4; */
 
-      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);
-    }
+      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(n4,n2,n3,n1,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 +513,81 @@ 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);
+    }
 
   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];
+
+          orig = b;
+          do
+            {
+              b->l->v = b->l_old->v + (1./step) * (l_init[i]->v - b->l_old->v);
+              if(b->next == NULL) break;
+              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");
-
-      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;
-    }
-
-
+      
+      Restore_Br_Len(tree);
+      
       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) 
+    {
+      while(l_init[i]->prev) l_init[i] = l_init[i]->prev; 
+      Free_Scalar_Dbl(l_init[i]);
+    }
   Free(l_init);
 
+  For(i,2*tree->n_otu-3) 
+    {
+      while(v_init[i]->prev) v_init[i] = v_init[i]->prev;
+      Free_Scalar_Dbl(v_init[i]);
+    }
+  Free(v_init);
+
   tree->n_swap = 0;
   For(i,2*tree->n_otu-3)
     {
@@ -536,14 +598,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;
@@ -565,7 +626,8 @@ int Mov_Backward_Topo_Pars(t_tree *tree, int pars_old, t_edge **tested_b, int n_
 
       step++;
 
-    }while((tree->c_pars > pars_old) && (step < 1000));
+    }
+  while((tree->c_pars > pars_old) && (step < 1000));
 
 
   if(step == 1000)
@@ -596,245 +658,411 @@ 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; */
-
+          n1 = n2 = n3 = n4 = NULL;
+          
+          n1 = b[i]->nni->swap_node_v4;
+          n2 = b[i]->nni->swap_node_v2;
+          n3 = b[i]->nni->swap_node_v3;
+          n4 = b[i]->nni->swap_node_v1;
+
+          /* 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; */
 
-      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;
         }
-      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; */
+          n1 = n2 = n3 = n4 = NULL;
+          
+          n1 = b[i]->nni->swap_node_v4;
+          n2 = b[i]->nni->swap_node_v2;
+          n3 = b[i]->nni->swap_node_v3;
+          n4 = b[i]->nni->swap_node_v1;
+
+          /* 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;
-          if(b[i]->next) b[i] = b[i]->next;
-          else            b[i] = b[i]->next;
+          /* 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;
+          
+          n1 = b[i]->nni->swap_node_v1;
+          n2 = b[i]->nni->swap_node_v2;
+          n3 = b[i]->nni->swap_node_v3;
+          n4 = b[i]->nni->swap_node_v4;
+
+
+          /* 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;
+
+          n1 = b[i]->nni->swap_node_v1;
+          n2 = b[i]->nni->swap_node_v2;
+          n3 = b[i]->nni->swap_node_v3;
+          n4 = b[i]->nni->swap_node_v4;
+
+
+          /* 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)
 {
-
   int i;
-  For(i,3)
+
+  if(d->tax) return;
+  
+  for(i=0;i<3;i++)
     {
       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;
+            }
         }
     }
-    }
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
+/*
+        v
+        |
+        |
+        a
+       / \
+      d   u
+     / \
+    v1 v2   
+*/
+void NNI_Traversal(t_node *a, t_node *d, t_node *v, t_edge *b, t_tree *tree)
+{
+  unsigned int i;
+  
+  if(d->tax == YES)
+    {
+      Br_Len_Brent(b,tree);
+      return;
+    }
+  else if(a->tax == YES)
+    {
+      Br_Len_Brent(b,tree);
+      for(i=0;i<3;++i) if(d->v[i] != a)
+        {
+          Update_Partial_Lk(tree,d->b[i],d);
+          NNI_Traversal(d,d->v[i],a,d->b[i],tree);
+        }
+      Update_Partial_Lk(tree,b,d);
+    }
+  else
+    {
+      phydbl lk0,lk1,lk2;
+      phydbl l0,rnd;
+      t_node *v1,*v2,*u,*dum;
 
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
+      /* unsigned int keep_topo; */
+      /* phydbl p,accept_prob; */
+      
+      lk0 = UNLIKELY;
+      lk1 = UNLIKELY;
+      lk2 = UNLIKELY;
+      
+      v1 = v2 = NULL;
+      for(i=0;i<3;++i)
+        if(d->v[i] != a)
+          {
+            if(v1 == NULL) v1 = d->v[i];
+            else           v2 = d->v[i];
+          }
+      assert(v1 != NULL);
+      assert(v2 != NULL);
+
+      dum = NULL;
+      rnd = Uni();
+      if(rnd < .5)
+        {
+          dum = v1;
+          v1  = v2;
+          v2  = dum;
+        }
+      
+      u = NULL;
+      for(i=0;i<3;++i) if(a->v[i] != d && a->v[i] != v) { u = a->v[i]; break; }
+      
+      /* Br_Len_Brent(b,tree); */
+      lk0 = Lk(b,tree);
+      Record_Br_Len(tree);
+      l0 = MIXT_Get_Mean_Edge_Len(b,tree);
 
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
+      if(l0 < 0.1)
+        {
+          // First NNI
+          Swap(v1,d,a,u,tree);
+          // Update partial likelihood looking up
+          Update_Partial_Lk(tree,b,a);
+          // Update partial likelihood looking down
+          Update_Partial_Lk(tree,b,d);
+          // Evaluate likelihood
+          /* Br_Len_Brent(b,tree); */
+          lk1 = Lk(b,tree);
 
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
+          
+          /* keep_topo = (lk1 > lk0); */
+          /* if(Are_Equal(tree->annealing_temp,0.0,1.E-3) == NO) */
+          /*   { */
+          /*     accept_prob = exp((lk1-lk0)/tree->annealing_temp); */
+          /*     p = Uni(); */
+          /*     if(!(p > accept_prob)) keep_topo = YES; */
+          /*   } */
+
+          /* if(keep_topo == NO) */
+          if(lk1 < lk0)
+            {
+              // Unswap
+              Swap(u,d,a,v1,tree);
+              
+              // Second NNI
+              Swap(v2,d,a,u,tree);
+              // Update partial likelihood looking up
+              Update_Partial_Lk(tree,b,a);
+              // Update partial likelihood looking down
+              Update_Partial_Lk(tree,b,d);
+              // Evaluate likelihood
+              /* Br_Len_Brent(b,tree); */
+              lk2 = Lk(b,tree);
+              
+              
+              /* keep_topo = (lk2 > lk0); */
+              /* if(Are_Equal(tree->annealing_temp,0.0,1.E-3) == NO) */
+              /*   { */
+              /*     accept_prob = exp((lk2-lk0)/tree->annealing_temp); */
+              /*     p = Uni(); */
+              /*     if(!(p > accept_prob)) keep_topo = YES; */
+              /*   } */
+
+              // Unswap
+              if(lk2 < lk0)
+              /* if(keep_topo == NO) */
+                {
+                  Swap(u,d,a,v2,tree);
+                  // Update partial likelihood looking up
+                  Update_Partial_Lk(tree,b,a);
+                  // Update partial likelihood looking down
+                  Update_Partial_Lk(tree,b,d);
+                  Restore_Br_Len(tree);
+                  Lk(b,tree);
+                }
+            }
+        }
+      
+      Br_Len_Brent(b,tree);
+
+      for(i=0;i<3;++i)
+        if(d->v[i] != a)
+          {
+            Update_Partial_Lk(tree,d->b[i],d);
+            NNI_Traversal(d,d->v[i],a,d->b[i],tree);
+          }
+      Update_Partial_Lk(tree,b,d);
+    }
+}
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
-
diff --git a/src/simu.h b/src/simu.h
index 54203c9..25d0433 100644
--- a/src/simu.h
+++ b/src/simu.h
@@ -29,5 +29,6 @@ void Swap_N_Branch(t_tree *tree,t_edge **b,int beg,int end);
 void Check_NNI_Scores_Around(t_node *a, t_node *d, t_edge *b, phydbl *best_score, t_tree *tree);
 int Mov_Backward_Topo_Pars(t_tree *tree, int pars_old, t_edge **tested_b, int n_tested);
 void Simu_Pars(t_tree *tree, int n_step_max);
+void NNI_Traversal(t_node *a, t_node *d, t_node *v, t_edge *b, t_tree *tree);
 
 #endif
diff --git a/src/spr.c b/src/spr.c
index f3771ca..1c23d61 100644
--- a/src/spr.c
+++ b/src/spr.c
@@ -1,7 +1,7 @@
 /*
 
-PhyML:  a program that  computes maximum likelihood phyLOGenies from
-DNA or AA homoLOGous sequences.
+PhyML:  a program that  computes maximum likelihood phylogenies from
+DNA or AA homologous sequences.
 
 Copyright (C) Stephane Guindon. Oct 2003 onward.
 
@@ -23,3079 +23,40 @@ the GNU public licence. See http://www.opensource.org for details.
 #include "beagle_utils.h"
 #endif
 
-/*
-** BIG: Some big number.
-*/
-
-/* #define BIG  1e05 */
-
-/*
-** Global vars.
-**
-**   - cur_lk:        The current likelihood of the tree.
-**   - subtree_dist:  The average subtree distances matrix.
-**   - seq_dist:      The sequence distance matrix.
-**   - optim_cand:    Array for holding candidate moves for local and global branch
-**                    length optimization.
-**   - rgrft_cand:    Array for holding candidate regraft positions.
-**   - v_tmp:         The central t_node of the temporary regraft structure for
-**                    estimating changes in likelihood.
-**   - path:          The path through the tree during the recursive tree length
-**                    calculation.
-**   - sum_scale_tmp  Array for temporarily storing scaling factors.
-**   - p_lk_tmp:      Temporary partial likelihood storage.
-**   - e_brent:       A temporary t_edge to use for estimating distances using Brent.
-
-**   - tree->mod->s_opt->wim_n_rgrft:       Number of promising regraft positions to consider when
-                      performing all improving SPR moves.
-**   - tree->mod->s_opt->wim_n_optim:       Number of candidate moves on which to perform local branch
-                      length optimization.
-**   - tree->mod->s_opt->wim_max_dist:      Maximum regraft distance to consider.
-**   - tree->mod->s_opt->wim_n_globl:       Number of candidates moves on which to perform global branch
-                      length optimization.
-**   - tree->mod->s_opt->wim_n_best:        Number of promising regraft positions to consider when
-                      performing only the best SPR move.
-
-**   - nr_d_l:        Total number of change in tree length calculations done.
-**   - nr_d_lk:       Total number of change in likelihood calculations done.
-**   - nr_loc:        Total number of local branch length optimizations done.
-**   - nr_glb:        Total number of global branch length optimizations done.
-*/
-
-phydbl   cur_lk, **subtree_dist, *sum_scale_tmp, *p_lk_tmp;
-matrix  *seq_dist;
-_move_ **optim_cand, **rgrft_cand;
-t_node    *v_tmp=NULL, **path;
-t_edge    *e_brent=NULL;
-int      nr_d_L, nr_d_lk, nr_loc, nr_glb;
-
-/*
-** Init_SPR: Initialize the SPR algorithm: allocate memory and set variables.
-**
-** Parameters:
-**   - tree: The current tree to use for initialization.
-*/
-
-void Init_SPR (t_tree *tree)
-{
-  int   i, nr_nodes, nr_edges;
-  t_node *u_0, *u_1, *u_2;
-
-  /*
-  ** Get the SPR parameter values.
-  */
-  nr_edges = 2*tree->n_otu-3;
-
-  if(tree->mod->s_opt->wim_n_rgrft  < 0) tree->mod->s_opt->wim_n_rgrft = 1 + nr_edges / 5;
-  if(tree->mod->s_opt->wim_n_globl  < 0) tree->mod->s_opt->wim_n_globl = 1 + nr_edges / 10;
-  if(tree->mod->s_opt->wim_max_dist < 0) tree->mod->s_opt->wim_max_dist = 1 + nr_edges / 10;
-  if(tree->mod->s_opt->wim_n_optim  < 0) tree->mod->s_opt->wim_n_optim = 100;
-  if(tree->mod->s_opt->wim_n_best   < 0) tree->mod->s_opt->wim_n_best = tree->mod->s_opt->wim_n_rgrft; /* can't
-                                                    *  be
-                                                    *  anything else
-                                                        */
-
-
-  /*
-  ** If it doesn't exist yet, create the temporary regraft structure:
-  ** a central t_node with three edges and tip nodes adjacent to it.
-  */
-  if (v_tmp == NULL)
-  {
-
-    v_tmp=Make_Node_Light(0);
-    v_tmp->tax = 0;
-    u_0=Make_Node_Light(1);
-    u_0->tax = 1;
-    u_1=Make_Node_Light(2);
-    u_1->tax = 1;
-    u_2=Make_Node_Light(3);
-    u_2->tax = 1;
-
-    v_tmp->v[0] = u_0;
-    v_tmp->v[1] = u_1;
-    v_tmp->v[2] = u_2;
-    u_0->v[0]   = v_tmp;
-    u_1->v[0]   = v_tmp;
-    u_2->v[0]   = v_tmp;
-
-    t_edge *edge_0 = Make_Edge_Light (v_tmp, u_0, 0);
-    Make_Edge_Lk (edge_0, tree);
-    t_edge *edge_1 = Make_Edge_Light (v_tmp, u_1,1);
-    Make_Edge_Lk (edge_1, tree);
-    t_edge *edge_2 = Make_Edge_Light (v_tmp, u_2,2);
-    Make_Edge_Lk (edge_2, tree);
-
-
-/*     For(i,tree->data->crunch_len) */
-/*       { */
-/* 	For(j,tree->mod->ras->n_catg) */
-/* 	  { */
-/* 	    Free(edge_0->p_lk_rght[i][j]); */
-/* 	  } */
-/* 	Free(edge_0->p_lk_rght[i]); */
-/*       } */
-    Free(edge_0->p_lk_rght);
-
-    if(!edge_0->rght->tax) Free(edge_0->sum_scale_rght);
-
-
-/*     For(i,tree->data->crunch_len) */
-/*       { */
-/* 	For(j,tree->mod->ras->n_catg) */
-/* 	  { */
-/* 	    Free(edge_1->p_lk_rght[i][j]); */
-/* 	  } */
-/* 	Free(edge_1->p_lk_rght[i]); */
-/*       } */
-    Free(edge_1->p_lk_rght);
-
-    if(!edge_1->rght->tax) Free(edge_1->sum_scale_rght);
-
-
-/*     For(i,tree->data->crunch_len) */
-/*       { */
-/* 	For(j,tree->mod->ras->n_catg) */
-/* 	  { */
-/* 	    Free(edge_2->p_lk_rght[i][j]); */
-/* 	  } */
-/* 	Free(edge_2->p_lk_rght[i]); */
-/*       } */
-    Free(edge_2->p_lk_rght);
-
-    if(!edge_2->rght->tax) Free(edge_2->sum_scale_rght);
-  }
-
-  /*
-  ** If it doesn't exist yet, create the temporary edge.
-  */
-  if (e_brent == NULL)
-  {
-
-    u_1=Make_Node_Light(4);
-    u_1->tax = 1;
-    u_2=Make_Node_Light(5);
-    u_2->tax = 1;
-    u_1->v[0] = u_2;
-    u_2->v[0] = u_1;
-    t_edge *edge_4 = Make_Edge_Light (u_1, u_2, 3);
-    Make_Edge_Lk (edge_4, tree);
-    e_brent = u_1->b[0];
-
-
-/*     For(i,tree->data->crunch_len) */
-/*       { */
-/* 	For(j,tree->mod->ras->n_catg) */
-/* 	  { */
-/* 	    Free(edge_4->p_lk_rght[i][j]); */
-/* 	  } */
-/* 	Free(edge_4->p_lk_rght[i]); */
-/*       } */
-    Free(edge_4->p_lk_rght);
-
-    if(!edge_4->rght->tax) Free(edge_4->sum_scale_rght);
-
-
-/*     For(i,tree->data->crunch_len) */
-/*       { */
-/* 	For(j,tree->mod->ras->n_catg) */
-/* 	  { */
-/* 	    Free(edge_4->p_lk_left[i][j]); */
-/* 	  } */
-/* 	Free(edge_4->p_lk_left[i]); */
-/*       } */
-    Free(edge_4->p_lk_left);
-
-    if(!edge_4->left->tax) Free(edge_4->sum_scale_left);
-  }
-
-  /*
-  ** Allocate memory for temporarily storing partial likelihoods and
-  ** scaling factors.
-  */
-  p_lk_tmp = (phydbl *)mCalloc (tree->n_pattern*tree->mod->ras->n_catg*tree->mod->ns, sizeof (phydbl));
-/*   p_lk_tmp = (phydbl ***)mCalloc (tree->n_pattern, sizeof (phydbl **)); */
-/*   for (i = 0; i < tree->n_pattern; i++) */
-/*   { */
-/*     p_lk_tmp[i] = (phydbl **)mCalloc (tree->mod->ras->n_catg, sizeof (phydbl *)); */
-/*     for (j = 0; j < tree->mod->ras->n_catg; j++) */
-/*     { */
-/*       p_lk_tmp[i][j] = (phydbl *)mCalloc (tree->mod->ns, sizeof (phydbl)); */
-/*     } */
-/*   } */
-  sum_scale_tmp = (phydbl *)mCalloc (tree->n_pattern, sizeof (phydbl));
-
-  /*
-  ** Allocate memory for storing the average subtree distances.
-  */
-  nr_nodes = 2*tree->n_otu-2;
-  subtree_dist = (phydbl **)malloc (nr_nodes * sizeof (phydbl *));
-  for (i = 0; i < nr_nodes; i++)
-    {
-      subtree_dist[i] = (phydbl *)malloc (nr_nodes * sizeof (phydbl));
-    }
-
-  /*
-  ** Allocate memory for storing the candidate regraft positions and
-  ** t_edge length optimization moves.
-  */
-  rgrft_cand = (_move_ **)malloc (MAX(tree->mod->s_opt->wim_n_rgrft,tree->mod->s_opt->wim_n_best) * sizeof (_move_ *));
-  for (i = 0; i < MAX(tree->mod->s_opt->wim_n_rgrft,tree->mod->s_opt->wim_n_best); i++)
-    {
-      rgrft_cand[i] = (_move_ *)malloc (sizeof (_move_));
-      rgrft_cand[i]->path = (t_node **)malloc ((tree->mod->s_opt->wim_max_dist+2) * sizeof (t_node *));
-    }
-  optim_cand = (_move_ **)malloc (tree->mod->s_opt->wim_n_optim * sizeof (_move_ *));
-  for (i = 0; i < tree->mod->s_opt->wim_n_optim; i++)
-    {
-      optim_cand[i] = (_move_ *)malloc (sizeof (_move_));
-      optim_cand[i]->path = (t_node **)malloc ((tree->mod->s_opt->wim_max_dist+2) * sizeof (t_node *));
-    }
-  path = (t_node **)malloc ((tree->mod->s_opt->wim_max_dist+2) * sizeof (t_node *));
-
-  if(!tree->mat)
-    {
-      seq_dist = ML_Dist (tree->data, tree->mod);
-      tree->mat = seq_dist;
-    }
-  else
-    seq_dist = tree->mat;
-
-  /*
-  ** Set variables.
-  */
-  nr_d_L = 0;
-  nr_d_lk = 0;
-  nr_loc = 0;
-  nr_glb = 0;
-}
-
-
-/*
-** Clean_SPR: Free up the used memory.
-**
-** Parameters:
-**   - tree: The current tree.
-*/
-
-void Clean_SPR (t_tree *tree)
-{
-  int i;
-
-  /*
-  ** Clean up the temporary regraft structure.
-  */
-  Free_Node (v_tmp->v[0]);
-  Free_Node (v_tmp->v[1]);
-  Free_Node (v_tmp->v[2]);
-  v_tmp->b[0]->p_lk_rght = NULL;
-  Free_Edge_Lk (v_tmp->b[0]);
-  Free_Edge (v_tmp->b[0]);
-  v_tmp->b[1]->p_lk_rght = NULL;
-  Free_Edge_Lk(v_tmp->b[1]);
-  Free_Edge(v_tmp->b[1]);
-  v_tmp->b[2]->p_lk_rght = NULL;
-  Free_Edge_Lk (v_tmp->b[2]);
-  Free_Edge (v_tmp->b[2]);
-  Free_Node (v_tmp);
-  v_tmp = NULL;
-
-  /*
-  ** Clean up the temporary edge.
-  */
-  Free_Node (e_brent->left);
-  Free_Node (e_brent->rght);
-  e_brent->p_lk_left = NULL;
-  e_brent->p_lk_rght = NULL;
-  Free_Edge_Lk (e_brent);
-  Free_Edge (e_brent);
-  e_brent = NULL;
-
-  /*
-  ** Free the temporary partial likelihood and scaling memory.
-  */
-/*   for (i = 0; i < tree->n_pattern; i++) */
-/*   { */
-/*     for (j = 0; j < tree->mod->ras->n_catg; j++) */
-/*     { */
-/*       free (p_lk_tmp[i][j]); */
-/*     } */
-/*     free (p_lk_tmp[i]); */
-/*   } */
-  free (p_lk_tmp);
-  free (sum_scale_tmp);
-
-  /*
-  ** Free the subtree distance matrix.
-  */
-  for (i = 0; i < 2*tree->n_otu - 2; i++)
-  {
-    free (subtree_dist[i]);
-  }
-  free (subtree_dist);
-
-  /*
-  ** Free the arrays for storing the candidate regrafting positions and
-  ** t_edge length optimization moves.
-  */
-  for (i = 0; i < MAX(tree->mod->s_opt->wim_n_rgrft,tree->mod->s_opt->wim_n_best); i++)
-  {
-    free (rgrft_cand[i]->path);
-    free (rgrft_cand[i]);
-  }
-  free (rgrft_cand);
-  for (i = 0; i < tree->mod->s_opt->wim_n_optim; i++)
-  {
-    free (optim_cand[i]->path);
-    free (optim_cand[i]);
-  }
-  free (optim_cand);
-  free (path);
-
-
-  /*
-  ** Print some statistics (for "research" purposes only).
-  */
-/*   PhyML_Printf ("nr_d_L:  %d\n", nr_d_L); */
-/*   PhyML_Printf ("nr_d_lk: %d\n", nr_d_lk); */
-/*   PhyML_Printf ("nr_loc:  %d\n", nr_loc); */
-/*   PhyML_Printf ("nr_glb:  %d\n", nr_glb); */
-}
-
-
-/*
-** Optim_SPR: Optimize the tree using SPR moves.
-**
-** Parameters:
-**   - tree:     The tree to optimize.
-**   - max_size: The maximum size (= number of taxa) of the subtrees to be
-**               pruned. If m=0 or m>ntax, all possible prunings will be
-**               considered.
-**   - method:   The optimization method to use ("ALL" or "BEST").
-*/
-
-void Optim_SPR (t_tree *tree, int max_size, int method)
-{
-  int   nr_moves, improvement;
-
-  if(tree->mod->s_opt->print) PhyML_Printf("\n\n. Starting SPR moves...\n");
-
-  /*
-  ** Calculate the current likelihood value.
-  */
-  Set_Both_Sides(YES,tree);
-  cur_lk = Lk(NULL,tree);
-  time(&(tree->t_current));
-  if(tree->mod->s_opt->print) Print_Lk(tree,"topology");
-
-  /*
-  ** Optimize all t_edge lengths and calculate the new likelihood value.
-  */
-/*   PhyML_Printf("\n. Optimizing t_edge lengths."); */
-  Optimize_Br_Len_Serie (tree);
-  Set_Both_Sides(YES,tree);
-  cur_lk = Lk(NULL,tree);
-  time(&(tree->t_current));
-  if(tree->mod->s_opt->print) Print_Lk(tree,"topology");
-
-  /*
-  ** While improvements were found, perform another round of SPR moves.
-  */
-  nr_moves = 0;
-  improvement = 1;
-  while (improvement)
-    {
-      /*
-      ** Perform one round of SPR moves.
-      */
-      if (method == ALL)
-    {
-      improvement = Perform_SPR_Moves (tree, max_size);
-    }
-      else if (method == BEST)
-    {
-      improvement = Perform_Best_SPR (tree, max_size);
-    }
-      else if (method == ONE)
-    {
-      improvement = Perform_One_SPR (tree, max_size);
-    }
-      else
-    {
-      PhyML_Printf ("\n. Unknown SPR optimization method, bailing out...\n");
-      exit (1);
-    }
-
-      /*     If an improvement was found, update statistics. */
-      if(improvement)
-    {
-    nr_moves++;
-    if((nr_moves == 1) || (nr_moves % 4 == 1))
-      {
-        /*
-        ** Optimize model parameters.
-        */
-        Optimiz_All_Free_Param (tree,(tree->io->quiet)?(0):(tree->mod->s_opt->print));
-        Set_Both_Sides(YES,tree);
-        Lk(NULL,tree);
-      }
-      }
-
-      /* Beg SG 28 May 2007 */
-      if(method == BEST || method == ONE) break;
-      /* Beg SG 28 May 2007 */
-  }
-
-  if(tree->mod->s_opt->print) PhyML_Printf ("\n\n. Number of SPR moves: %d\n", nr_moves);
-
-  /*
-  ** Perform a last round of optimization steps (for t_edge lengths).
-  */
-  Round_Optimize(tree,tree->data,ROUND_MAX);
-  Check_NNI_Five_Branches(tree);
-}
-
-
-/*
-** Perform_SPR_Moves: Perform a round of SPR moves on the tree. Prune each subtree in
-**                    turn and calculate the change in tree length for each candidate
-**                    regraft position. Estimate change in likelihood for the most
-**                    promising moves, and perform all moves that result in an
-**                    improvement. If no improvements were found at all, try local edge
-**                    length optimization. If still no improvement, try global edge
-**                    length optimization.
-**
-** Parameters:
-**   - tree:     The tree to perform the SPR moves on.
-**   - max_size: The maximum size (= number of taxa) of the subtrees to be
-**               pruned. If m=0 or m>ntax, all possible prunings will be
-**               considered.
-**
-** Returns:
-**   If the current tree could be improved: 1.
-**   Otherwise:                             0.
-*/
-
-int Perform_SPR_Moves (t_tree *tree, int max_size)
-{
-  int   nr_edges, i, j, candidate, improvement;
-  t_node *root, *v_prune;
-  t_edge *e_prune;
-
-  /*
-  ** Calculate the average subtree distances.
-  */
-  root = tree->a_nodes[0];
-  PostOrder_v (tree, root->v[2], root->b[2]);
-
-  /*
-  ** Initialize the array of optimization candidates.
-  */
-  for (i = 0; i < tree->mod->s_opt->wim_n_optim; i++)
-  {
-    optim_cand[i]->delta_lk = -1.0*BIG;
-    optim_cand[i]->d_L = -1.0*BIG;
-  }
-
-  /*
-  ** Try all possible SPR moves and perform the ones that give an improvement.
-  */
-  nr_edges = 2*tree->n_otu - 3;
-  cur_lk = tree->c_lnL;
-  improvement = 0;
-
-
-/*   PhyML_Printf("\n >>>>>>>>>>>>>>>>>>"); */
-/*   PhyML_Printf("\n. cur_lk = %f %f",cur_lk,Lk(NULL,tree)); */
-
-/*   PhyML_Printf ("\n. Trying SPR moves"); */
-/*   PhyML_Printf ("\n.  - calculating tree distances and estimating likelihoods"); */
-
-  for(i = 0; i < nr_edges; i++)
-    {
-      /*
-      ** Get the next prune edge.
-      */
-      e_prune = tree->a_edges[i];
-      /*
-      ** Try right subtree if appropriate.
-      */
-      if (!e_prune->left->tax)
-    {
-      /*
-      ** Clear the regraft candidate list.
-      */
-      for (j = 0; j < tree->mod->s_opt->wim_n_rgrft; j++)
-        {
-          rgrft_cand[j]->d_L = -1.0*BIG;
-        }
-      v_prune = e_prune->left;
-/* 	  if ((max_size == 0) || (e_prune->num_tax_rght <= max_size)) */
-        {
-          /*
-          ** Calculate changes in tree length, and estimate changes in likelihood for
-          ** the most promising candidates. Perform moves that give an improvement.
-          */
-          Calc_Tree_Length (e_prune, v_prune, tree);
-          if ((candidate = Est_Lk_Change (e_prune, v_prune, tree)) >= 0)
-        {
-          improvement = 1;
-          Make_Move (rgrft_cand[candidate],0,tree);
-/* 		  PhyML_Printf("\n. Make simple move"); */
-/* 		  PhyML_Printf("\n. lk after simple move = %f",Lk(tree)); */
-        }
-        }
-    }
-      /*
-      ** Try left subtree if appropriate.
-      */
-      if (!e_prune->rght->tax)
-    {
-      /*
-      ** Clear the regraft candidate list.
-      */
-      for (j = 0; j < tree->mod->s_opt->wim_n_rgrft; j++)
-        {
-          rgrft_cand[j]->d_L = -1.0*BIG;
-        }
-      v_prune = e_prune->rght;
-/* 	  if ((max_size == 0) || (e_prune->num_tax_left <= max_size)) */
-        {
-          /*
-          ** Calculate changes in tree length, and estimate changes in likelihood for
-          ** the most promising candidates. Perform moves that give an improvement.
-          */
-          Calc_Tree_Length (e_prune, v_prune, tree);
-          if ((candidate = Est_Lk_Change (e_prune, v_prune, tree)) >= 0)
-        {
-          improvement = 1;
-          Make_Move (rgrft_cand[candidate],0,tree);
-/* 		  PhyML_Printf("\n. Make simple move"); */
-/* 		  PhyML_Printf("\n. lk after simple move = %f",Lk(tree)); */
-        }
-        }
-    }
-    }
-
-  /*
-  ** If there was no improvement at all, try local t_edge length optimization at the
-  ** regraft position.
-  */
-
-/*   PhyML_Printf("\n. before local = %f %f",tree->c_lnL,Lk(tree)); */
-
-  if (!improvement)
-    {
-      /*       PhyML_Printf ("\n.  - performing local t_edge length optimizations"); */
-      if ((candidate = Find_Optim_Local (tree)) >= 0)
-    {
-/*  	  PhyML_Printf("\n. make local move"); */
-      improvement = 1;
-      Make_Move (optim_cand[candidate],1,tree);
-/* 	  PhyML_Printf("\n. lk after local move = %f",Lk(tree)); */
-    }
-    }
-
-
-  /*
-  ** If there was still no improvement, try global t_edge length optimization.
-  */
-/*   PhyML_Printf("\n. before global = %f %f",tree->c_lnL,Lk(tree)); */
-
-  if (!improvement)
-    {
-/*       PhyML_Printf ("\n.  - performing global t_edge length optimization"); */
-      if ((candidate = Find_Optim_Globl (tree)) >= 0)
-    {
-/*  	  PhyML_Printf("\n. make global move"); */
-      improvement = 1;
-      Make_Move (optim_cand[candidate],2,tree);
-/* 	  PhyML_Printf("\n. lk after global move = %f",Lk(tree)); */
-    }
-    }
-
-/*   PhyML_Printf("\n. after all = %f %f",tree->c_lnL,Lk(tree)); */
-
-  /*
-  ** Optimize all t_edge lengths again to make sure we got an updated
-  ** likelihood value.
-  */
-  Set_Both_Sides(YES,tree);
-  cur_lk = Lk(NULL,tree);
-  root = tree->a_nodes[0];
-  Optimize_Br_Len_Serie (tree);
-  Set_Both_Sides(YES,tree);
-  cur_lk = Lk(NULL,tree);
-  time(&(tree->t_current));
-  if(tree->mod->s_opt->print) Print_Lk(tree,"topoLOGy");
-
-  /*
-  ** Return the result.
-  */
-  return (improvement);
-}
-
-
-/*
-** Perform_Best_SPR: Perform the best SPR move on the tree. Prune each subtree in
-**                   turn and calculate the change in tree length for each candidate
-**                   regraft position. Estimate change in likelihood for the most
-**                   promising regraft positions, and store the best one. Then choose
-**                   the best candidate over all moves. If no improving move can be
-**                   found, try local t_edge length optimization, and if necessary
-**                   global t_edge length optimization.
-**
-** Parameters:
-**   - tree:     The tree to perform the SPR moves on.
-**   - max_size: The maximum size (= number of taxa) of the subtrees to be
-**               pruned. If m=0 or m>ntax, all possible prunings will be
-**               considered.
-**
-** Returns:
-**   If an improving move could be performed: 1.
-**   Otherwise:                               0.
-*/
-
-int Perform_Best_SPR (t_tree *tree, int max_size)
-{
-  int   nr_edges, i, j, candidate, improvement;
-  t_node *root, *v_prune;
-  t_edge *e_prune;
-
-  /*
-  ** Calculate the average subtree distances.
-  */
-  root = tree->a_nodes[0];
-  PostOrder_v (tree, root->v[2], root->b[2]);
-
-  /*
-  ** Initialize the array of optimization candidates.
-  */
-  for (i = 0; i < tree->mod->s_opt->wim_n_optim; i++)
-  {
-    optim_cand[i]->delta_lk = -1.0*BIG;
-    optim_cand[i]->d_L = -1.0*BIG;
-  }
-
-  /*
-  ** Try all possible SPR moves and perform the best one.
-  */
-  nr_edges = 2*tree->n_otu - 3;
-  cur_lk = tree->c_lnL;
-  improvement = 0;
-/*   PhyML_Printf ("\n. Trying SPR moves"); */
-/*   PhyML_Printf ("\n.  -calculating tree distances and estimating likelihoods"); */
-  for (i = 0; i < nr_edges; i++)
-  {
-    /*
-    ** Get the next prune edge.
-    */
-    e_prune = tree->a_edges[i];
-    /*
-    ** Try right subtree if appropriate.
-    */
-    if (!e_prune->left->tax)
-    {
-      /*
-      ** Clear the regraft candidate list.
-      */
-      for (j = 0; j < tree->mod->s_opt->wim_n_best; j++)
-      {
-    rgrft_cand[j]->d_L = -1.0*BIG;
-      }
-      v_prune = e_prune->left;
-/*       if ((max_size == 0) || (e_prune->num_tax_rght <= max_size)) */
-      {
-    /*
-    ** Calculate changes in tree length, and estimate changes in likelihood for
-    ** the most promising candidates. Store the best one in the optimization list.
-    */
-    Calc_Tree_Length (e_prune, v_prune, tree);
-    candidate = Best_Lk_Change (e_prune, v_prune, tree);
-      }
-    }
-    /*
-    ** Try left subtree if appropriate.
-    */
-    if (!e_prune->rght->tax)
-    {
-      /*
-      ** Clear the regraft candidate list.
-      */
-      for (j = 0; j < tree->mod->s_opt->wim_n_rgrft; j++)
-      {
-    rgrft_cand[j]->d_L = -1.0*BIG;
-      }
-      v_prune = e_prune->rght;
-/*       if ((max_size == 0) || (e_prune->num_tax_left <= max_size)) */
-      {
-    /*
-    ** Calculate changes in tree length, and estimate changes in likelihood for
-    ** the most promising candidates. Perform moves that give an improvement.
-    */
-    Calc_Tree_Length (e_prune, v_prune, tree);
-    candidate = Best_Lk_Change (e_prune, v_prune, tree);
-      }
-    }
-  }
-
-  /* If the best candidate has a positive estimated change in
-  ** likelihood, perform that move.
-  */
-  if (optim_cand[0]->delta_lk > 1.0/BIG)
-  {
-    improvement = 1;
-    Make_Move (optim_cand[0],0,tree);
-  }
-
-  /*
-  ** If there was no improvement at all, try local t_edge length optimization at the
-  ** regraft position.
-  */
-  if (!improvement)
-  {
-/*     PhyML_Printf ("\n.  - performing local t_edge length optimizations"); */
-    if ((candidate = Find_Optim_Local (tree)) >= 0)
-    {
-      improvement = 1;
-      Make_Move (optim_cand[candidate],1,tree);
-    }
-  }
-
-  /*
-  ** If there was still no improvement, try global t_edge length optimization.
-  */
-  if (!improvement)
-  {
-/*     PhyML_Printf ("\n.  - performing global t_edge length optimization"); */
-    if ((candidate = Find_Optim_Globl (tree)) >= 0)
-    {
-      improvement = 1;
-      Make_Move (optim_cand[candidate],2,tree);
-    }
-  }
-
-  /*
-  ** Optimize all t_edge lengths again to make sure we got an updated
-  ** likelihood value.
-  */
-  Set_Both_Sides(YES,tree);
-  cur_lk = Lk(NULL,tree);
-  root = tree->a_nodes[0];
-  Optimize_Br_Len_Serie (tree);
-  Set_Both_Sides(YES,tree);
-  cur_lk = Lk(NULL,tree);
-  time(&(tree->t_current));
-  if(tree->mod->s_opt->print) Print_Lk(tree,"topology");
-
-  /*
-  ** Return the result.
-  */
-  return (improvement);
-}
-
-
-/*
-** Perform_One_Moves: Perform a round of SPR moves on the tree. Prune each subtree in
-**                    turn and calculate the change in tree length for each candidate
-**                    regraft position. Estimate change in likelihood for the most
-**                    promising moves, and perform the first move that results in an
-**                    improvement. If no improvements were found at all, try local edge
-**                    length optimization. If still no improvement, try global edge
-**                    length optimization.
-**
-** Parameters:
-**   - tree:     The tree to perform the SPR moves on.
-**   - max_size: The maximum size (= number of taxa) of the subtrees to be
-**               pruned. If m=0 or m>ntax, all possible prunings will be
-**               considered.
-**
-** Returns:
-**   If the current tree could be improved: 1.
-**   Otherwise:                             0.
-*/
-
-int Perform_One_SPR(t_tree *tree, int max_size)
-{
-  int   nr_edges, i, j, candidate, improvement;
-  t_node *root, *v_prune;
-  t_edge *e_prune;
-
-  /*
-  ** Calculate the average subtree distances.
-  */
-
-  root = tree->a_nodes[0];
-  PostOrder_v (tree, root->v[2], root->b[2]);
-
-  /*
-  ** Initialize the array of optimization candidates.
-  */
-  for (i = 0; i < tree->mod->s_opt->wim_n_optim; i++)
-  {
-    optim_cand[i]->delta_lk = -1.0*BIG;
-    optim_cand[i]->d_L = -1.0*BIG;
-  }
-
-  /*
-  ** Try all possible SPR moves and perform the ones that give an improvement.
-  */
-  nr_edges = 2*tree->n_otu - 3;
-  cur_lk = tree->c_lnL;
-  improvement = 0;
-
-/*   PhyML_Printf("\n >>>>>>>>>>>>>>>>>>"); */
-/*   PhyML_Printf("\n. cur_lk = %f %f",cur_lk,Lk(tree)); */
-
-/*   PhyML_Printf ("\n. Trying SPR moves"); */
-/*   PhyML_Printf ("\n.  - calculating tree distances and estimating likelihoods"); */
-
-  for(i = 0; i < nr_edges; i++)
-    {
-      /*
-      ** Get the next prune edge.
-      */
-      e_prune = tree->a_edges[i];
-      /*
-      ** Try right subtree if appropriate.
-      */
-      if (!e_prune->left->tax)
-    {
-      /*
-      ** Clear the regraft candidate list.
-      */
-      for (j = 0; j < tree->mod->s_opt->wim_n_rgrft; j++)
-        {
-          rgrft_cand[j]->d_L = -1.0*BIG;
-        }
-      v_prune = e_prune->left;
-/* 	  if ((max_size == 0) || (e_prune->num_tax_rght <= max_size)) */
-        {
-          /*
-          ** Calculate changes in tree length, and estimate changes in likelihood for
-          ** the most promising candidates. Perform moves that give an improvement.
-          */
-          Calc_Tree_Length (e_prune, v_prune, tree);
-          if ((candidate = Est_Lk_Change (e_prune, v_prune, tree)) >= 0)
-        {
-          improvement = 1;
-          Make_Move (rgrft_cand[candidate],0,tree);
-        }
-        }
-    }
-      /*
-      ** Try left subtree if appropriate.
-      */
-      if (!e_prune->rght->tax && !improvement)
-    {
-      /*
-      ** Clear the regraft candidate list.
-      */
-      for (j = 0; j < tree->mod->s_opt->wim_n_rgrft; j++)
-        {
-          rgrft_cand[j]->d_L = -1.0*BIG;
-        }
-      v_prune = e_prune->rght;
-/* 	  if ((max_size == 0) || (e_prune->num_tax_left <= max_size)) */
-        {
-          /*
-          ** Calculate changes in tree length, and estimate changes in likelihood for
-          ** the most promising candidates. Perform moves that give an improvement.
-          */
-          Calc_Tree_Length (e_prune, v_prune, tree);
-          if ((candidate = Est_Lk_Change (e_prune, v_prune, tree)) >= 0)
-        {
-          improvement = 1;
-          Make_Move (rgrft_cand[candidate],0,tree);
-/* 		  PhyML_Printf("\n. Make simple move"); */
-/* 		  PhyML_Printf("\n. lk after simple move = %f",Lk(tree)); */
-        }
-        }
-    }
-      if(improvement) break;
-    }
-
-  /*
-  ** If there was no improvement at all, try local t_edge length optimization at the
-  ** regraft position.
-  */
-
-/*   PhyML_Printf("\n. before local = %f %f",tree->c_lnL,Lk(tree)); */
-
-  if (!improvement)
-    {
-      /*       PhyML_Printf ("\n.  - performing local t_edge length optimizations"); */
-      if ((candidate = Find_Optim_Local (tree)) >= 0)
-    {
-/*  	  PhyML_Printf("\n. make local move"); */
-      improvement = 1;
-      Make_Move (optim_cand[candidate],1,tree);
-/* 	  PhyML_Printf("\n. lk after local move = %f",Lk(tree)); */
-    }
-    }
-
-
-  /*
-  ** If there was still no improvement, try global t_edge length optimization.
-  */
-/*   PhyML_Printf("\n. before global = %f %f",tree->c_lnL,Lk(tree)); */
-
-  if (!improvement)
-    {
-/*       PhyML_Printf ("\n.  - performing global t_edge length optimization"); */
-      if ((candidate = Find_Optim_Globl (tree)) >= 0)
-    {
-/*  	  PhyML_Printf("\n. make global move"); */
-      improvement = 1;
-      Make_Move (optim_cand[candidate],2,tree);
-/* 	  PhyML_Printf("\n. lk after global move = %f",Lk(tree)); */
-    }
-    }
-
-/*   PhyML_Printf("\n. after all = %f %f",tree->c_lnL,Lk(tree)); */
-
-  /*
-  ** Optimize all t_edge lengths again to make sure we got an updated
-  ** likelihood value.
-  */
-  Set_Both_Sides(YES,tree);
-  cur_lk = Lk(NULL,tree);
-  root = tree->a_nodes[0];
-  Optimize_Br_Len_Serie (tree);
-  Set_Both_Sides(YES,tree);
-  cur_lk = Lk(NULL,tree);
-  time(&(tree->t_current));
-  if(tree->mod->s_opt->print) Print_Lk(tree,"topology");
-
-  /*
-  ** Return the result.
-  */
-  return (improvement);
-}
-
-
-/*
-**  Calc_Tree_Length: Calculate the change in tree length, given a pruned subtree,
-**                    for each possible regraft position.
-**
-** Parameters:
-**   - e_prune: The t_edge at which the subtree is pruned.
-**   - v_prune: The root of the pruned subtree.
-*/
-
-void Calc_Tree_Length (t_edge *e_prune, t_node *v_prune, t_tree *tree)
-{
-  int     i, d0, d1, d2;
-  phydbl  d_uu;
-  t_node   *u_prune, *u1, *u2;
-
-  /*
-  ** Get the directions from t_node v_prune.
-  */
-  d0 = -1;
-  u_prune = NULL;
-  for (i = 0; i < 3; i++)
-  {
-    if (v_prune->b[i] == e_prune)
-    {
-      d0 = i;
-      u_prune = v_prune->v[i];
-      break;
-    }
-  }
-  d1 = (d0 + 1) % 3;
-  d2 = 3 - d0 - d1;
-
-  /*
-  ** Get the relevant average subtree distance within the pruned subtree.
-  */
-  if (!u_prune->tax)
-  {
-    u1 = u2 = NULL;
-    for (i = 0; i < 3; i++)
-    {
-      if (u_prune->b[i] != e_prune)
-      {
-    if (u1 == NULL)
-    {
-      u1 = u_prune->v[i];
-    }
-    else
-    {
-      u2 = u_prune->v[i];
-    }
-      }
-    }
-    d_uu = subtree_dist[u1->num][u2->num];
-  }
-  else
-  {
-    d_uu = 0.0;
-  }
-
-  /*
-  ** Recursively calculate the change in tree length for each
-  ** possible regraft position.
-  **
-  ** First recurse into direction d1.
-  */
-  if (!v_prune->v[d1]->tax)
-  {
-    u1 = u2 = NULL;
-    for (i = 0; i < 3; i++)
-    {
-      if (v_prune->v[d1]->b[i] != v_prune->b[d1])
-      {
-    if (u1 == NULL)
-    {
-      u1 = v_prune->v[d1]->v[i];
-    }
-    else
-    {
-      u2 = v_prune->v[d1]->v[i];
-    }
-      }
-    }
-    Tree_Length(v_prune, u_prune, v_prune->v[d1], v_prune->v[d2], u1, v_prune->v[d2],
-        u2, subtree_dist[u_prune->num][v_prune->v[d2]->num], d_uu, 0.0, 1, tree);
-    Tree_Length(v_prune, u_prune, v_prune->v[d1], v_prune->v[d2], u2, v_prune->v[d2],
-        u1, subtree_dist[u_prune->num][v_prune->v[d2]->num], d_uu, 0.0, 1, tree);
-  }
-  /*
-  ** Next recurse into direction d2.
-  */
-  if (!v_prune->v[d2]->tax)
-  {
-    u1 = u2 = NULL;
-    for (i = 0; i < 3; i++)
-    {
-      if (v_prune->v[d2]->b[i] != v_prune->b[d2])
-      {
-    if (u1 == NULL)
-    {
-      u1 = v_prune->v[d2]->v[i];
-    }
-    else
-    {
-      u2 = v_prune->v[d2]->v[i];
-    }
-      }
-    }
-    Tree_Length(v_prune, u_prune, v_prune->v[d2], v_prune->v[d1], u1, v_prune->v[d1],
-        u2, subtree_dist[u_prune->num][v_prune->v[d1]->num], d_uu, 0.0, 1, tree);
-    Tree_Length(v_prune, u_prune, v_prune->v[d2], v_prune->v[d1], u2, v_prune->v[d1],
-        u1, subtree_dist[u_prune->num][v_prune->v[d1]->num], d_uu, 0.0, 1, tree);
-  }
-}
-
-
-/*
-** Tree_Length: Recursively calculate the change in tree length for a given pruned
-**              subtree and regraft position.
-**
-** Parameters:
-**   - v_prune: The root of the pruned subtree.
-**   - u_prune: The t_node adjacent to v_p along the pruned edge.
-**   - v_n:     The t_node adjacent to the regraft t_edge in the "backward" direction.
-**   - v_n_1:   The previous v_n.
-**   - v_nx1:   The t_node adjacent to the regrafting t_edge in the "forward" direction.
-**   - v_0:     The other t_node originally adjacent to v_p;
-**   - u_n:     The other t_node adjecent to v_n (besides v_n_1 and v_nx1);
-**   - d_uv_1:  The distance between u_p and v_n_1;
-**   - d_uu:    The subtree distance between descendants of u_prune.
-**   - d_L_1:   The previous change in tree length.
-**   - n:       The current distance from the prune position.
-*/
-
-void Tree_Length (t_node *v_prune, t_node *u_prune, t_node *v_n, t_node *v_n_1, t_node *v_nx1,
-          t_node *v_0, t_node *u_n, phydbl d_up_v_1, phydbl d_L_1, phydbl d_uu,
-          int n, t_tree *tree)
-{
-  int     i, j;
-  phydbl  d_un_v, d_up_v, d_L;
-  t_node   *u1, *u2;
-  t_edge   *e_prune, *e_regraft;
-  _move_ *tmp_cand;
-
-  /*
-  ** Update the path and number of calculations.
-  */
-  path[n] = v_n;
-  nr_d_L++;
-  e_prune = NULL;
-  e_regraft = NULL;
-
-  /*
-  ** Calculate the change in tree length for the current pruned subtree and regraft
-  ** position.
-  */
-  if (n == 1)
-  {
-    d_un_v = subtree_dist[u_n->num][v_0->num];
-  }
-  else
-  {
-    d_un_v = subtree_dist[u_n->num][v_n_1->num] -
-        (pow (0.5, n) * subtree_dist[u_n->num][u_prune->num]) +
-        (pow (0.5, n) * subtree_dist[u_n->num][v_0->num]);
-  }
-  d_up_v = 0.5 * (d_up_v_1 + subtree_dist[u_prune->num][u_n->num]);
-  /*
-  ** Alternative method for calculating d_up_v. Just kept it around for reference...
-  **
-  d_up_v = subtree_dist[u_prune->num][u_n->num] - (0.5 * d_uu);
-  if (!u_n->tax)
-  {
-    u1 = u2 = NULL;
-    for (i = 0; i < 3; i++)
-    {
-      if (u_n->v[i] != v_n)
-      {
-    if (u1 == NULL)
-    {
-      u1 = u_n->v[i];
-    }
-    else
-    {
-      u2 = u_n->v[i];
-    }
-      }
-    }
-    d_up_v -= 0.5 * subtree_dist[u1->num][u2->num];
-  }
-  for (i = 0; i < 3; i++)
-  {
-    if (u_n->v[i] == v_n)
-    {
-      d_up_v -= u_n->b[i]->l->v;
-      break;
-    }
-  }
-  */
-  d_L = d_L_1 + 0.25*((d_up_v_1 + subtree_dist[u_n->num][v_nx1->num]) -
-              (d_un_v + subtree_dist[u_prune->num][v_nx1->num]));
-
-  /*
-  ** If the change is within the tree->mod->s_opt->wim_n_rgrft best ones so far, save it.
-  */
-  if (d_L > rgrft_cand[tree->mod->s_opt->wim_n_rgrft-1]->d_L)
-  {
-    for (i = 0; i < 3; i++)
-    {
-      if (v_prune->v[i] == u_prune)
-      {
-    e_prune = v_prune->b[i];
-      }
-      if (v_n->v[i] == v_nx1)
-      {
-    e_regraft = v_n->b[i];
-      }
-    }
-    i = tree->mod->s_opt->wim_n_rgrft-1;
-    rgrft_cand[i]->v_prune = v_prune;
-    rgrft_cand[i]->u_prune = u_prune;
-    rgrft_cand[i]->v_n = v_n;
-    rgrft_cand[i]->v_nx1 = v_nx1;
-    rgrft_cand[i]->u_n = u_n;
-    rgrft_cand[i]->e_prune = e_prune;
-    rgrft_cand[i]->e_regraft = e_regraft;
-    rgrft_cand[i]->d_L = d_L;
-    rgrft_cand[i]->d_up_v = d_up_v;
-    rgrft_cand[i]->d_un_v = d_un_v;
-    rgrft_cand[i]->dist = n;
-    for (j = 1; j <= n; j++)
-      {
-    rgrft_cand[i]->path[j] = path[j];
-      }
-
-    rgrft_cand[i]->path[n+1] = v_nx1;
-    /*
-    ** Move the candidate to the appropriate position in the list, so the list
-    ** remains sorted in decreasing d_L value.
-    */
-    while ((i > 0) && (rgrft_cand[i]->d_L > rgrft_cand[i-1]->d_L))
-    {
-      tmp_cand = rgrft_cand[i];
-      rgrft_cand[i] = rgrft_cand[i-1];
-      rgrft_cand[i-1] = tmp_cand;
-      i--;
-    }
-  }
-
-  /*
-  ** Recurse.
-  */
-  if (n < tree->mod->s_opt->wim_max_dist)
-  {
-    if (!v_nx1->tax)
-    {
-      u1 = u2 = NULL;
-      for (i = 0; i < 3; i++)
-      {
-    if (v_nx1->v[i] != v_n)
-    {
-      if (u1 == NULL)
-      {
-        u1 = v_nx1->v[i];
-      }
-      else
-      {
-        u2 = v_nx1->v[i];
-      }
-    }
-      }
-      Tree_Length (v_prune, u_prune, v_nx1, v_n, u1, v_0, u2, d_up_v, d_uu, d_L, n+1, tree);
-      Tree_Length (v_prune, u_prune, v_nx1, v_n, u2, v_0, u1, d_up_v, d_uu, d_L, n+1, tree);
-    }
-  }
-}
-
-
-/*
-** Est_Lk_Change: Estimate the changes in likelihood for the most promising candidate
-**                regraft positions given a pruned subtree.
-**
-** Parameters:
-**   - e_prune: The t_edge at which the subtree was pruned.
-**   - v_prune: The root of the pruned subtree.
-**   - tree:    The tree on which to do the calculations.
-**
-** Returns:
-**   If an improvement as found: The candidate which gives the improvement (which
-**                               will be the first one found).
-**   Otherwise:                  -1.
-*/
-
-int Est_Lk_Change (t_edge *e_prune, t_node *v_prune, t_tree *tree)
-{
-  int     i, j, cand, best_cand, d0, d1, d2, n, pat, cat, ste;
-  phydbl  d_uu, best_d_lk, l_connect, l_01, l_02, l_12, l_est[3], new_lk,
-          l_simple[3], l_dist[3];
-  phydbl *p_lk1_tmp, *p_lk2_tmp, *p_lk;
-  int *p_sum;
-  t_node   *u_prune, *v_n, *v_nx1, *u1, *u2;
-  t_edge   *e_regraft, *e_tmp;
-  _move_ *tmp_cand;
-  int dim1, dim2;
-
-
-  dim1 = tree->mod->ns * tree->mod->ras->n_catg;
-  dim2 = tree->mod->ras->n_catg;
-
-  /*
-  ** Get the directions from t_node v_prune.
-  */
-  d0 = -1;
-  u_prune = NULL;
-  for (i = 0; i < 3; i++)
-  {
-    if (v_prune->b[i] == e_prune)
-    {
-      d0 = i;
-      u_prune = v_prune->v[i];
-      break;
-    }
-  }
-  d1 = (d0 + 1) % 3;
-  d2 = 3 - d0 - d1;
-
-  /*
-  ** Copy the relevant partial likelihoods to the temporary regraft structure.
-  ** We can point to the original matrices, cos they won't be changed anyway.
-  */
-  if (v_prune == e_prune->left)
-  {
-    v_tmp->b[0]->p_lk_rght = e_prune->p_lk_rght;
-    v_tmp->b[0]->sum_scale_rght = e_prune->sum_scale_rght;
-  }
-  else
-  {
-    v_tmp->b[0]->p_lk_rght = e_prune->p_lk_left;
-    v_tmp->b[0]->sum_scale_rght = e_prune->sum_scale_left;
-  }
-  v_tmp->num = v_prune->num;
-  v_tmp->v[0]->num = u_prune->num;
-  v_tmp->b[0]->num = e_prune->num;
-
-  /*
-  ** Estimate the length of the t_edge that will connect the two "detached" nodes
-  ** after pruning. (The average of the sum of the lengths of the original two
-  ** edges and the average subtree distance based estimate.)
-  */
-  l_connect = subtree_dist[v_prune->v[d1]->num][v_prune->v[d2]->num];
-  if (!v_prune->v[d1]->tax)
-  {
-    u1 = u2 = NULL;
-    for (i = 0; i < 3; i++)
-    {
-      if (v_prune->v[d1]->b[i] != v_prune->b[d1])
-      {
-    if (u1 == NULL)
-    {
-      u1 = v_prune->v[d1]->v[i];
-    }
-    else
-    {
-      u2 = v_prune->v[d1]->v[i];
-    }
-      }
-    }
-    l_connect -= 0.5 * subtree_dist[u1->num][u2->num];
-  }
-  if (!v_prune->v[d2]->tax)
-  {
-    u1 = u2 = NULL;
-    for (i = 0; i < 3; i++)
-    {
-      if (v_prune->v[d2]->b[i] != v_prune->b[d2])
-      {
-    if (u1 == NULL)
-    {
-      u1 = v_prune->v[d2]->v[i];
-    }
-    else
-    {
-      u2 = v_prune->v[d2]->v[i];
-    }
-      }
-    }
-    l_connect -= 0.5 * subtree_dist[u1->num][u2->num];
-  }
-  l_connect += (v_prune->b[d1]->l->v + v_prune->b[d2]->l->v);
-  l_connect /= 2.0;
-
-  /*
-  ** Temporarily swap the relevant partial likelihoods at the prune site.
-  **
-  ** Direction d1.
-  */
-  if (v_prune == v_prune->b[d1]->left)
-  {
-    p_lk1_tmp = v_prune->b[d1]->p_lk_left;
-    if (v_prune == v_prune->b[d2]->left)
-    {
-      v_prune->b[d1]->p_lk_left = v_prune->b[d2]->p_lk_rght;
-    }
-    else
-    {
-      v_prune->b[d1]->p_lk_left = v_prune->b[d2]->p_lk_left;
-    }
-  }
-  else
-  {
-    p_lk1_tmp = v_prune->b[d1]->p_lk_rght;
-    if (v_prune == v_prune->b[d2]->left)
-    {
-      v_prune->b[d1]->p_lk_rght = v_prune->b[d2]->p_lk_rght;
-    }
-    else
-    {
-      v_prune->b[d1]->p_lk_rght = v_prune->b[d2]->p_lk_left;
-    }
-  }
-  /*
-  ** Direction d2.
-  */
-  if (v_prune == v_prune->b[d2]->left)
-  {
-    p_lk2_tmp = v_prune->b[d2]->p_lk_left;
-    if (v_prune == v_prune->b[d1]->left)
-    {
-      v_prune->b[d2]->p_lk_left = v_prune->b[d1]->p_lk_rght;
-    }
-    else
-    {
-      v_prune->b[d2]->p_lk_left = v_prune->b[d1]->p_lk_left;
-    }
-  }
-  else
-  {
-    p_lk2_tmp = v_prune->b[d2]->p_lk_rght;
-    if (v_prune == v_prune->b[d1]->left)
-    {
-      v_prune->b[d2]->p_lk_rght = v_prune->b[d1]->p_lk_rght;
-    }
-    else
-    {
-      v_prune->b[d2]->p_lk_rght = v_prune->b[d1]->p_lk_left;
-    }
-  }
-
-  /*
-  ** Temporarily set the t_edge lengths and update transition prob's at the
-  ** prune site.
-  */
-  v_prune->b[d1]->l_old->v = v_prune->b[d1]->l->v;
-  v_prune->b[d2]->l_old->v = v_prune->b[d2]->l->v;
-  v_prune->b[d1]->l->v = l_connect;
-  v_prune->b[d2]->l->v = l_connect;
-  Update_PMat_At_Given_Edge (v_prune->b[d1], tree);
-  Update_PMat_At_Given_Edge (v_prune->b[d2], tree);
-
-  /*
-  ** Get the relevant average subtree distance within the pruned subtree.
-  */
-  if (!u_prune->tax)
-  {
-    u1 = u2 = NULL;
-    for (i = 0; i < 3; i++)
-    {
-      if (u_prune->b[i] != e_prune)
-      {
-    if (u1 == NULL)
-    {
-      u1 = u_prune->v[i];
-    }
-    else
-    {
-      u2 = u_prune->v[i];
-    }
-      }
-    }
-    d_uu = subtree_dist[u1->num][u2->num];
-  }
-  else
-  {
-    d_uu = 0.0;
-  }
-
-  /*
-  ** Try each candidate SPR and estimate the change in likelihood.
-  */
-  best_d_lk = 1.0/BIG;
-  best_cand = -1;
-  for (cand = 0; cand < tree->mod->s_opt->wim_n_rgrft; cand++)
-  {
-    /*
-    ** If there are no more candidates, bail out...
-    */
-    if (FABS(rgrft_cand[cand]->d_L - 1.0*BIG) < SMALL)
-    {
-      break;
-    }
-    else
-    {
-      nr_d_lk++;
-    }
-
-    /*
-    ** Get the relevant nodes and edges.
-    */
-    v_n = rgrft_cand[cand]->v_n;
-    v_nx1 = rgrft_cand[cand]->v_nx1;
-    e_regraft = rgrft_cand[cand]->e_regraft;
-
-    /*
-    ** Update the relevant partial likelihoods along the path between the prune
-    ** and regraft positions (temporarily save the first one).
-    */
-    n = rgrft_cand[cand]->dist;
-    e_tmp = NULL;
-    p_lk = NULL;
-    p_sum = NULL;
-    for (i = 1; i <= n; i++)
-    {
-      /*
-      ** Get the next t_edge along the path.
-      */
-      for (j = 0; j < 3; j++)
-      {
-    if (rgrft_cand[cand]->path[i]->v[j] == rgrft_cand[cand]->path[i+1])
-    {
-      e_tmp = rgrft_cand[cand]->path[i]->b[j];
-      break;
-    }
-      }
-      if (i == 1)
-      {
-    /*
-    ** Save the first partial likelihood along the path.
-    */
-    if (rgrft_cand[cand]->path[i] == e_tmp->left)
-      {
-        p_lk  = e_tmp->p_lk_left;
-        p_sum = e_tmp->sum_scale_left;
-      }
-    else
-      {
-        p_lk  = e_tmp->p_lk_rght;
-        p_sum = e_tmp->sum_scale_rght;
-      }
-
-    for (pat = 0; pat < tree->n_pattern; pat++)
-      {
-        sum_scale_tmp[pat] = p_sum[pat];
-        for (cat = 0; cat < tree->mod->ras->n_catg; cat++)
-          {
-        for (ste = 0; ste < tree->mod->ns; ste++)
-          {
-            p_lk_tmp[pat*dim1+cat*dim2+ste] = p_lk[pat*dim1+cat*dim2+ste];
-          }
-          }
-      }
-      }
-      Update_P_Lk (tree, e_tmp, rgrft_cand[cand]->path[i]);
-    }
-    if (v_n == e_regraft->left)
-    {
-      v_tmp->b[1]->p_lk_rght = e_regraft->p_lk_left;
-      v_tmp->b[2]->p_lk_rght = e_regraft->p_lk_rght;
-      v_tmp->b[1]->sum_scale_rght = e_regraft->sum_scale_left;
-      v_tmp->b[2]->sum_scale_rght = e_regraft->sum_scale_rght;
-    }
-    else
-    {
-      v_tmp->b[1]->p_lk_rght = e_regraft->p_lk_rght;
-      v_tmp->b[2]->p_lk_rght = e_regraft->p_lk_left;
-      v_tmp->b[1]->sum_scale_rght = e_regraft->sum_scale_rght;
-      v_tmp->b[2]->sum_scale_rght = e_regraft->sum_scale_left;
-    }
-
-    /*
-    ** Estimate t_edge lengths of the three relevant regraft edges based on
-    ** average subtree distances.
-    **
-    ** l_01
-    */
-    /*
-    ** Alternative method of estimating l_01. Kept it around for reference...
-    **
-    l_01 = subtree_dist[u_prune->num][u_n->num] - (0.5 * d_uu);
-    if (!u_n->tax)
-    {
-      u1 = u2 = NULL;
-      for (i = 0; i < 3; i++)
-      {
-    if (u_n->v[i] != v_n)
-    {
-      if (u1 == NULL)
-      {
-        u1 = u_n->v[i];
-      }
-      else
-      {
-        u2 = u_n->v[i];
-      }
-    }
-      }
-      l_01 -= 0.5 * subtree_dist[u1->num][u2->num];
-    }
-    for (i = 0; i < 3; i++)
-    {
-      if (u_n->v[i] == v_n)
-      {
-    l_01 -= u_n->b[i]->l->v;
-    break;
-      }
-    }
-    */
-    l_01 = rgrft_cand[cand]->d_up_v - (0.5 * rgrft_cand[cand]->d_un_v) -
-           (0.5 * d_uu);
-    /*
-    ** l_02
-    */
-    l_02 = subtree_dist[u_prune->num][v_nx1->num] - (0.5 * d_uu);
-    if (!v_nx1->tax)
-    {
-      u1 = u2 = NULL;
-      for (i = 0; i < 3; i++)
-      {
-    if (v_nx1->v[i] != v_n)
-    {
-      if (u1 == NULL)
-      {
-        u1 = v_nx1->v[i];
-      }
-      else
-      {
-        u2 = v_nx1->v[i];
-      }
-    }
-      }
-      l_02 -= (0.5 * subtree_dist[u1->num][u2->num]);
-    }
-    /*
-    ** l_12
-    */
-    l_12 = e_regraft->l->v;
-    /*
-    ** Simple estimates.
-    */
-    l_simple[0] = l_02 - (0.5*e_regraft->l->v);
-    l_simple[1] = 0.5 * e_regraft->l->v;
-    l_simple[2] = 0.5 * e_regraft->l->v;
-    /*
-    ** Average subtree distance based estimates.
-    */
-    l_dist[0] = 0.5 * ( l_01 + l_02 - l_12);
-    l_dist[1] = 0.5 * ( l_01 - l_02 + l_12);
-    l_dist[2] = 0.5 * (-l_01 + l_02 + l_12);
-    /*
-    ** Take the average of the two estimates.
-    */
-    l_est[0] = (l_simple[0] + l_dist[0]) / 2.0;
-    l_est[1] = (l_simple[1] + l_dist[1]) / 2.0;
-    l_est[2] = (l_simple[2] + l_dist[2]) / 2.0;
-
-    /*
-    ** Set the t_edge lengths and update the relevant transition prob's and
-    ** partial likelihoods in the temporary regraft structure.
-    */
-
-    for (i = 0; i < 3; i++)
-    {
-      v_tmp->b[i]->l->v = l_est[i]; /* TO DO */
-      Update_PMat_At_Given_Edge (v_tmp->b[i], tree);
-    }
-
-    /* Beg SG 18 May 2007 */
-    if(tree->mod->s_opt->wim_inside_opt)
-      {
-    Triple_Dist(v_tmp,tree,0);
-    For(i,3) l_est[i] = v_tmp->b[i]->l->v;
-      }
-    /* End SG 18 May 2007 */
-
-
-    /*
-    ** Calculate the change in likelihood locally. Save it and the estimated edge
-    ** lengths in the current candidate in the list.
-    */
-    Update_P_Lk (tree, v_tmp->b[0], v_tmp);
-    new_lk = Lk(v_tmp->b[0],tree);
-/*     PhyML_Printf("\n. new_lk = %f",new_lk); */
-
-    rgrft_cand[cand]->delta_lk = new_lk - cur_lk;
-    rgrft_cand[cand]->rgrft_rank = cand;
-    rgrft_cand[cand]->optim_rank = -1;
-    rgrft_cand[cand]->globl_rank = -1;
-    rgrft_cand[cand]->l_connect = l_connect;
-    for (i = 0; i < 3; i++)
-    {
-      rgrft_cand[cand]->l_est[i] = v_tmp->b[i]->l->v;
-    }
-    if (rgrft_cand[cand]->delta_lk > best_d_lk)
-    {
-      best_d_lk = rgrft_cand[cand]->delta_lk;
-      best_cand = cand;
-    }
-
-    /*
-    ** If the change is within the tree->mod->s_opt->wim_n_optim best ones, save it in the list of
-    ** optimization candidates.
-    */
-    if (rgrft_cand[cand]->delta_lk > optim_cand[tree->mod->s_opt->wim_n_optim-1]->delta_lk)
-    {
-      i = tree->mod->s_opt->wim_n_optim-1;
-      optim_cand[i]->v_prune = rgrft_cand[cand]->v_prune;
-      optim_cand[i]->u_prune = rgrft_cand[cand]->u_prune;
-      optim_cand[i]->v_n = rgrft_cand[cand]->v_n;
-      optim_cand[i]->v_nx1 = rgrft_cand[cand]->v_nx1;
-      optim_cand[i]->u_n = rgrft_cand[cand]->u_n;
-      optim_cand[i]->e_prune = rgrft_cand[cand]->e_prune;
-      optim_cand[i]->e_regraft = rgrft_cand[cand]->e_regraft;
-      optim_cand[i]->d_L = rgrft_cand[cand]->d_L;
-      optim_cand[i]->dist = rgrft_cand[cand]->dist;
-      optim_cand[i]->rgrft_rank = rgrft_cand[cand]->rgrft_rank;
-      optim_cand[i]->optim_rank = rgrft_cand[cand]->optim_rank;
-      optim_cand[i]->globl_rank = rgrft_cand[cand]->globl_rank;
-      optim_cand[i]->l_connect = rgrft_cand[cand]->l_connect;
-      for (j = 0; j < 3; j++)
-      {
-    optim_cand[i]->l_est[j] = rgrft_cand[cand]->l_est[j];
-      }
-      optim_cand[i]->delta_lk = rgrft_cand[cand]->delta_lk;
-      /*
-      ** Move the candidate to the appropriate position in the list, so the list
-      ** remains sorted in decreasing delta_Lk value.
-      */
-      while ((i > 0) && (optim_cand[i]->delta_lk > optim_cand[i-1]->delta_lk))
-      {
-    tmp_cand = optim_cand[i];
-    optim_cand[i] = optim_cand[i-1];
-    optim_cand[i-1] = tmp_cand;
-    i--;
-      }
-    }
-
-    /*
-    ** Reset the partial likelihoods along the path.
-    */
-    for (pat = 0; pat < tree->n_pattern; pat++)
-    {
-      p_sum[pat] = sum_scale_tmp[pat];
-      for (cat = 0; cat < tree->mod->ras->n_catg; cat++)
-      {
-    for (ste = 0; ste < tree->mod->ns; ste++)
-    {
-      p_lk[pat*dim1+cat*dim2+ste] = p_lk_tmp[pat*dim1+cat*dim2+ste];
-    }
-      }
-    }
-    n = rgrft_cand[cand]->dist;
-    for (i = 2; i <= n; i++)
-    {
-      for (j = 0; j < 3; j++)
-      {
-    if (rgrft_cand[cand]->path[i]->v[j] == rgrft_cand[cand]->path[i+1])
-    {
-      e_tmp = rgrft_cand[cand]->path[i]->b[j];
-      break;
-    }
-      }
-      Update_P_Lk (tree, e_tmp, rgrft_cand[cand]->path[i]);
-    }
-
-    /*
-    ** If an improvement was found, forget the other candidates...
-    */
-    if (best_cand >= 0)
-    {
-      break;
-    }
-  }
-
-  /*
-  ** Swap back the relevant partial likelihoods at the prune site.
-  */
-  if (v_prune == v_prune->b[d1]->left)
-  {
-    v_prune->b[d1]->p_lk_left = p_lk1_tmp;
-  }
-  else
-  {
-    v_prune->b[d1]->p_lk_rght = p_lk1_tmp;
-  }
-  if (v_prune == v_prune->b[d2]->left)
-  {
-    v_prune->b[d2]->p_lk_left = p_lk2_tmp;
-  }
-  else
-  {
-    v_prune->b[d2]->p_lk_rght = p_lk2_tmp;
-  }
-
-  /*
-  ** Reset the relevant t_edge lengths and transition prob's at the prune site.
-  */
-  v_prune->b[d1]->l->v = v_prune->b[d1]->l_old->v;
-  v_prune->b[d2]->l->v = v_prune->b[d2]->l_old->v;
-  Update_PMat_At_Given_Edge (v_prune->b[d1], tree);
-  Update_PMat_At_Given_Edge (v_prune->b[d2], tree);
-
-  /*
-  ** Return the best candidate.
-  */
-  return (best_cand);
-}
-
-
-/*
-** Best_Lk_Change: Estimate the changes in likelihood for the most promising candidate
-**                 regraft positions given a pruned subtree and save the best one.
-**
-** Parameters:
-**   - e_prune: The t_edge at which the subtree was pruned.
-**   - v_prune: The root of the pruned subtree.
-**   - tree:    The tree on which to do the calculations.
-**
-** Returns:
-**   The candidate which gives the best (possibly negative) improvement.
-*/
-
-int Best_Lk_Change (t_edge *e_prune, t_node *v_prune, t_tree *tree)
-{
-  int     i, j, cand, best_cand, d0, d1, d2, n, pat, cat, ste;
-  phydbl  d_uu, best_d_lk, l_connect, l_01, l_02, l_12, l_est[3], new_lk, l_simple[3], l_dist[3];
-  phydbl *p_lk1_tmp, *p_lk2_tmp, *p_lk;
-  int *p_sum;
-  t_node   *u_prune, *v_n, *v_nx1, *u1, *u2;
-  t_edge   *e_regraft, *e_tmp;
-  _move_ *tmp_cand;
-  int dim1, dim2;
-
-  dim1 = tree->mod->ns * tree->mod->ras->n_catg;
-  dim2 = tree->mod->ns ;
-
-  /*
-  ** Get the directions from t_node v_prune.
-  */
-  d0 = -1;
-  u_prune = NULL;
-  for (i = 0; i < 3; i++)
-  {
-    if (v_prune->b[i] == e_prune)
-    {
-      d0 = i;
-      u_prune = v_prune->v[i];
-      break;
-    }
-  }
-  d1 = (d0 + 1) % 3;
-  d2 = 3 - d0 - d1;
-
-  /*
-  ** Copy the relevant partial likelihoods to the temporary regraft structure.
-  ** We can point to the original matrices, cos they won't be changed anyway.
-  */
-  if (v_prune == e_prune->left)
-  {
-    v_tmp->b[0]->p_lk_rght = e_prune->p_lk_rght;
-    v_tmp->b[0]->sum_scale_rght = e_prune->sum_scale_rght;
-  }
-  else
-  {
-    v_tmp->b[0]->p_lk_rght = e_prune->p_lk_left;
-    v_tmp->b[0]->sum_scale_rght = e_prune->sum_scale_left;
-  }
-  v_tmp->num = v_prune->num;
-  v_tmp->v[0]->num = u_prune->num;
-  v_tmp->b[0]->num = e_prune->num;
-
-  /*
-  ** Estimate the length of the t_edge that will connect the two "detached" nodes
-  ** after pruning. (The average of the sum of the lengths of the original two
-  ** edges and the average subtree distance based estimate.)
-  */
-  l_connect = subtree_dist[v_prune->v[d1]->num][v_prune->v[d2]->num];
-  if (!v_prune->v[d1]->tax)
-  {
-    u1 = u2 = NULL;
-    for (i = 0; i < 3; i++)
-    {
-      if (v_prune->v[d1]->b[i] != v_prune->b[d1])
-      {
-    if (u1 == NULL)
-    {
-      u1 = v_prune->v[d1]->v[i];
-    }
-    else
-    {
-      u2 = v_prune->v[d1]->v[i];
-    }
-      }
-    }
-    l_connect -= 0.5 * subtree_dist[u1->num][u2->num];
-  }
-  if (!v_prune->v[d2]->tax)
-  {
-    u1 = u2 = NULL;
-    for (i = 0; i < 3; i++)
-    {
-      if (v_prune->v[d2]->b[i] != v_prune->b[d2])
-      {
-    if (u1 == NULL)
-    {
-      u1 = v_prune->v[d2]->v[i];
-    }
-    else
-    {
-      u2 = v_prune->v[d2]->v[i];
-    }
-      }
-    }
-    l_connect -= 0.5 * subtree_dist[u1->num][u2->num];
-  }
-  l_connect += (v_prune->b[d1]->l->v + v_prune->b[d2]->l->v);
-  l_connect /= 2.0;
-
-  /*
-  ** Temporarily swap the relevant partial likelihoods at the prune site.
-  **
-  ** Direction d1.
-  */
-  if (v_prune == v_prune->b[d1]->left)
-  {
-    p_lk1_tmp = v_prune->b[d1]->p_lk_left;
-    if (v_prune == v_prune->b[d2]->left)
-    {
-      v_prune->b[d1]->p_lk_left = v_prune->b[d2]->p_lk_rght;
-    }
-    else
-    {
-      v_prune->b[d1]->p_lk_left = v_prune->b[d2]->p_lk_left;
-    }
-  }
-  else
-  {
-    p_lk1_tmp = v_prune->b[d1]->p_lk_rght;
-    if (v_prune == v_prune->b[d2]->left)
-    {
-      v_prune->b[d1]->p_lk_rght = v_prune->b[d2]->p_lk_rght;
-    }
-    else
-    {
-      v_prune->b[d1]->p_lk_rght = v_prune->b[d2]->p_lk_left;
-    }
-  }
-  /*
-  ** Direction d2.
-  */
-  if (v_prune == v_prune->b[d2]->left)
-  {
-    p_lk2_tmp = v_prune->b[d2]->p_lk_left;
-    if (v_prune == v_prune->b[d1]->left)
-    {
-      v_prune->b[d2]->p_lk_left = v_prune->b[d1]->p_lk_rght;
-    }
-    else
-    {
-      v_prune->b[d2]->p_lk_left = v_prune->b[d1]->p_lk_left;
-    }
-  }
-  else
-  {
-    p_lk2_tmp = v_prune->b[d2]->p_lk_rght;
-    if (v_prune == v_prune->b[d1]->left)
-    {
-      v_prune->b[d2]->p_lk_rght = v_prune->b[d1]->p_lk_rght;
-    }
-    else
-    {
-      v_prune->b[d2]->p_lk_rght = v_prune->b[d1]->p_lk_left;
-    }
-  }
-
-  /*
-  ** Temporarily set the t_edge lengths and update transition prob's at the
-  ** prune site.
-  */
-  v_prune->b[d1]->l_old->v = v_prune->b[d1]->l->v;
-  v_prune->b[d2]->l_old->v = v_prune->b[d2]->l->v;
-  v_prune->b[d1]->l->v = l_connect;
-  v_prune->b[d2]->l->v = l_connect;
-  Update_PMat_At_Given_Edge (v_prune->b[d1], tree);
-  Update_PMat_At_Given_Edge (v_prune->b[d2], tree);
-
-  /*
-  ** Get the relevant average subtree distance within the pruned subtree.
-  */
-  if (!u_prune->tax)
-  {
-    u1 = u2 = NULL;
-    for (i = 0; i < 3; i++)
-    {
-      if (u_prune->b[i] != e_prune)
-      {
-    if (u1 == NULL)
-    {
-      u1 = u_prune->v[i];
-    }
-    else
-    {
-      u2 = u_prune->v[i];
-    }
-      }
-    }
-    d_uu = subtree_dist[u1->num][u2->num];
-  }
-  else
-  {
-    d_uu = 0.0;
-  }
-
-  /*
-  ** Try the best candidate SPRs and estimate the change in likelihood.
-  */
-  best_d_lk = -1.0*BIG;
-  best_cand = 0;
-  for (cand = 0; cand < tree->mod->s_opt->wim_n_best; cand++)
-  {
-    /*
-    ** If there are no more candidates, bail out...
-    */
-    if (FABS(rgrft_cand[cand]->d_L - 1.0*BIG) < SMALL)
-    {
-      break;
-    }
-    else
-    {
-      nr_d_lk++;
-    }
-
-    /*
-    ** Get the relevant nodes and edges.
-    */
-    v_n = rgrft_cand[cand]->v_n;
-    v_nx1 = rgrft_cand[cand]->v_nx1;
-    e_regraft = rgrft_cand[cand]->e_regraft;
-
-    /*
-    ** Update the relevant partial likelihoods along the path between the prune
-    ** and regraft positions (temporarily save the first one).
-    */
-    n = rgrft_cand[cand]->dist;
-    e_tmp = NULL;
-    p_lk = NULL;
-    p_sum = NULL;
-    for (i = 1; i <= n; i++)
-    {
-      /*
-      ** Get the next t_edge along the path.
-      */
-      for (j = 0; j < 3; j++)
-      {
-    if (rgrft_cand[cand]->path[i]->v[j] == rgrft_cand[cand]->path[i+1])
-    {
-      e_tmp = rgrft_cand[cand]->path[i]->b[j];
-      break;
-    }
-      }
-      if (i == 1)
-      {
-    /*
-    ** Save the first partial likelihood along the path.
-    */
-    if (rgrft_cand[cand]->path[i] == e_tmp->left)
-    {
-      p_lk = e_tmp->p_lk_left;
-      p_sum = e_tmp->sum_scale_left;
-    }
-    else
-    {
-      p_lk = e_tmp->p_lk_rght;
-      p_sum = e_tmp->sum_scale_rght;
-    }
-    for (pat = 0; pat < tree->n_pattern; pat++)
-    {
-      sum_scale_tmp[pat] = p_sum[pat];
-      for (cat = 0; cat < tree->mod->ras->n_catg; cat++)
-      {
-        for (ste = 0; ste < tree->mod->ns; ste++)
-        {
-          p_lk_tmp[pat*dim1+cat*dim2+ste] = p_lk[pat*dim1+cat*dim2+ste];
-        }
-      }
-    }
-      }
-      Update_P_Lk (tree, e_tmp, rgrft_cand[cand]->path[i]);
-    }
-    if (v_n == e_regraft->left)
-    {
-      v_tmp->b[1]->p_lk_rght = e_regraft->p_lk_left;
-      v_tmp->b[2]->p_lk_rght = e_regraft->p_lk_rght;
-      v_tmp->b[1]->sum_scale_rght = e_regraft->sum_scale_left;
-      v_tmp->b[2]->sum_scale_rght = e_regraft->sum_scale_rght;
-    }
-    else
-    {
-      v_tmp->b[1]->p_lk_rght = e_regraft->p_lk_rght;
-      v_tmp->b[2]->p_lk_rght = e_regraft->p_lk_left;
-      v_tmp->b[1]->sum_scale_rght = e_regraft->sum_scale_rght;
-      v_tmp->b[2]->sum_scale_rght = e_regraft->sum_scale_left;
-    }
-
-    /*
-    ** Estimate t_edge lengths of the three relevant regraft edges based on
-    ** average subtree distances.
-    **
-    ** l_01
-    */
-    /*
-    ** Alternative method of estimating l_01. Kept it around for reference...
-    **
-    l_01 = subtree_dist[u_prune->num][u_n->num] - (0.5 * d_uu);
-    if (!u_n->tax)
-    {
-      u1 = u2 = NULL;
-      for (i = 0; i < 3; i++)
-      {
-    if (u_n->v[i] != v_n)
-    {
-      if (u1 == NULL)
-      {
-        u1 = u_n->v[i];
-      }
-      else
-      {
-        u2 = u_n->v[i];
-      }
-    }
-      }
-      l_01 -= 0.5 * subtree_dist[u1->num][u2->num];
-    }
-    for (i = 0; i < 3; i++)
-    {
-      if (u_n->v[i] == v_n)
-      {
-    l_01 -= u_n->b[i]->l->v;
-    break;
-      }
-    }
-    */
-    l_01 = rgrft_cand[cand]->d_up_v - (0.5 * rgrft_cand[cand]->d_un_v) -
-           (0.5 * d_uu);
-    /*
-    ** l_02
-    */
-    l_02 = subtree_dist[u_prune->num][v_nx1->num] - (0.5 * d_uu);
-    if (!v_nx1->tax)
-    {
-      u1 = u2 = NULL;
-      for (i = 0; i < 3; i++)
-      {
-    if (v_nx1->v[i] != v_n)
-    {
-      if (u1 == NULL)
-      {
-        u1 = v_nx1->v[i];
-      }
-      else
-      {
-        u2 = v_nx1->v[i];
-      }
-    }
-      }
-      l_02 -= (0.5 * subtree_dist[u1->num][u2->num]);
-    }
-    /*
-    ** l_12
-    */
-    l_12 = e_regraft->l->v;
-    /*
-    ** Simple estimates.
-    */
-    l_simple[0] = l_02 - (0.5*e_regraft->l->v);
-    l_simple[1] = 0.5 * e_regraft->l->v;
-    l_simple[2] = 0.5 * e_regraft->l->v;
-    /*
-    ** Average subtree distance based estimates.
-    */
-    l_dist[0] = 0.5 * ( l_01 + l_02 - l_12);
-    l_dist[1] = 0.5 * ( l_01 - l_02 + l_12);
-    l_dist[2] = 0.5 * (-l_01 + l_02 + l_12);
-    /*
-    ** Take the average of the two estimates.
-    */
-    l_est[0] = (l_simple[0] + l_dist[0]) / 2.0;
-    l_est[1] = (l_simple[1] + l_dist[1]) / 2.0;
-    l_est[2] = (l_simple[2] + l_dist[2]) / 2.0;
-
-    /*
-    ** Set the t_edge lengths and update the relevant transition prob's and
-    ** partial likelihoods in the temporary regraft structure.
-    */
-    for (i = 0; i < 3; i++)
-    {
-      v_tmp->b[i]->l->v = l_est[i];
-      Update_PMat_At_Given_Edge (v_tmp->b[i], tree);
-    }
-    Update_P_Lk (tree, v_tmp->b[0], v_tmp);
-
-    /*
-    ** Calculate the change in likelihood locally. Save it and the estimated edge
-    ** lengths in the current candidate in the list.
-    */
-    new_lk = Lk(v_tmp->b[0],tree);
-    rgrft_cand[cand]->delta_lk = new_lk - cur_lk;
-    rgrft_cand[cand]->rgrft_rank = cand;
-    rgrft_cand[cand]->optim_rank = -1;
-    rgrft_cand[cand]->globl_rank = -1;
-    rgrft_cand[cand]->l_connect = l_connect;
-    for (i = 0; i < 3; i++)
-    {
-      rgrft_cand[cand]->l_est[i] = v_tmp->b[i]->l->v;
-    }
-    if (rgrft_cand[cand]->delta_lk > best_d_lk)
-    {
-      best_d_lk = rgrft_cand[cand]->delta_lk;
-      best_cand = cand;
-    }
-
-    /*
-    ** Reset the partial likelihoods along the path.
-    */
-    for (pat = 0; pat < tree->n_pattern; pat++)
-    {
-      p_sum[pat] = sum_scale_tmp[pat];
-      for (cat = 0; cat < tree->mod->ras->n_catg; cat++)
-      {
-    for (ste = 0; ste < tree->mod->ns; ste++)
-    {
-      p_lk[pat*dim1+cat*dim2+ste] = p_lk_tmp[pat*dim1+cat*dim2+ste];
-    }
-      }
-    }
-    n = rgrft_cand[cand]->dist;
-    for (i = 2; i <= n; i++)
-    {
-      for (j = 0; j < 3; j++)
-      {
-    if (rgrft_cand[cand]->path[i]->v[j] == rgrft_cand[cand]->path[i+1])
-    {
-      e_tmp = rgrft_cand[cand]->path[i]->b[j];
-      break;
-    }
-      }
-      Update_P_Lk (tree, e_tmp, rgrft_cand[cand]->path[i]);
-    }
-  }
-
-  /*
-  ** If the best candidate is within the tree->mod->s_opt->wim_n_optim best ones, save it in the list of
-  ** optimization candidates.
-  */
-  if (rgrft_cand[best_cand]->delta_lk > optim_cand[tree->mod->s_opt->wim_n_optim-1]->delta_lk)
-    {
-      i = tree->mod->s_opt->wim_n_optim-1;
-      optim_cand[i]->v_prune = rgrft_cand[best_cand]->v_prune;
-      optim_cand[i]->u_prune = rgrft_cand[best_cand]->u_prune;
-      optim_cand[i]->v_n = rgrft_cand[best_cand]->v_n;
-      optim_cand[i]->v_nx1 = rgrft_cand[best_cand]->v_nx1;
-      optim_cand[i]->u_n = rgrft_cand[best_cand]->u_n;
-      optim_cand[i]->e_prune = rgrft_cand[best_cand]->e_prune;
-      optim_cand[i]->e_regraft = rgrft_cand[best_cand]->e_regraft;
-      optim_cand[i]->d_L = rgrft_cand[best_cand]->d_L;
-      optim_cand[i]->dist = rgrft_cand[best_cand]->dist;
-      optim_cand[i]->rgrft_rank = rgrft_cand[best_cand]->rgrft_rank;
-      optim_cand[i]->optim_rank = rgrft_cand[best_cand]->optim_rank;
-      optim_cand[i]->globl_rank = rgrft_cand[best_cand]->globl_rank;
-      optim_cand[i]->l_connect = rgrft_cand[best_cand]->l_connect;
-
-      for (j = 0; j < 3; j++)
-    {
-      optim_cand[i]->l_est[j] = rgrft_cand[best_cand]->l_est[j];
-    }
-      optim_cand[i]->delta_lk = rgrft_cand[best_cand]->delta_lk;
-      /*
-      ** Move the candidate to the appropriate position in the list, so the list
-      ** remains sorted in decreasing delta_Lk value.
-      */
-      while ((i > 0) && (optim_cand[i]->delta_lk > optim_cand[i-1]->delta_lk))
-    {
-      tmp_cand = optim_cand[i];
-      optim_cand[i] = optim_cand[i-1];
-      optim_cand[i-1] = tmp_cand;
-      i--;
-    }
-    }
-
-  /*
-  ** Swap back the relevant partial likelihoods at the prune site.
-  */
-  if (v_prune == v_prune->b[d1]->left)
-    {
-      v_prune->b[d1]->p_lk_left = p_lk1_tmp;
-    }
-  else
-    {
-      v_prune->b[d1]->p_lk_rght = p_lk1_tmp;
-    }
-  if (v_prune == v_prune->b[d2]->left)
-    {
-      v_prune->b[d2]->p_lk_left = p_lk2_tmp;
-    }
-  else
-    {
-      v_prune->b[d2]->p_lk_rght = p_lk2_tmp;
-    }
-
-  /*
-  ** Reset the relevant t_edge lengths and transition prob's at the prune site.
-  */
-  v_prune->b[d1]->l->v = v_prune->b[d1]->l_old->v;
-  v_prune->b[d2]->l->v = v_prune->b[d2]->l_old->v;
-  Update_PMat_At_Given_Edge (v_prune->b[d1], tree);
-  Update_PMat_At_Given_Edge (v_prune->b[d2], tree);
-
-  /*
-  ** Return the best candidate.
-  */
-  return (best_cand);
-}
-
-
-/*
-** Make_Move: Perform an actual SPR move and calculate the new likelihood.
-**
-** Parameters:
-**   - candidate: The candidate move to perform.
-**   - tree:      The tree on which to perform the move.
-**
-*/
-
-void Make_Move (_move_ *move, int type, t_tree *tree)
-{
-  int     i;
-  t_node   *v_prune, *u_prune, *v_n, *root;
-  t_edge   *e_prune, *e_regraft, *e_connect, *e_avail;
-  phydbl  new_lk;
-
-  /*
-  ** Get the relevant nodes and edges.
-  */
-  v_prune = move->v_prune;
-  u_prune = move->u_prune;
-  v_n = move->v_n;
-  e_prune = move->e_prune;
-  e_regraft = move->e_regraft;
-  /*   PhyML_Printf ("  making move: %d -> %d (%f)\n", e_prune->num, e_regraft->num, move->delta_lk); */
-  /*
-  ** Perform the move and set t_edge lengths.
-  */
-  Prune (e_prune, v_prune, &(e_connect), &(e_avail), tree);
-  Regraft (e_regraft, v_prune, e_avail, tree);
-  e_connect->l->v = move->l_connect;
-
-  for (i = 0; i < 3; i++)
-    {
-      if (v_prune->v[i] == u_prune)
-    {
-      v_prune->b[i]->l->v = move->l_est[0];
-    }
-      else if (v_prune->v[i] == v_n)
-    {
-      v_prune->b[i]->l->v = move->l_est[1];
-    }
-      else
-    {
-      v_prune->b[i]->l->v = move->l_est[2];
-    }
-    }
-
-
-  if(type > 0) /* local or global move */
-    {
-      Restore_Br_Len(tree);
-    }
-
-  /*
-  ** Calculate the new likelihood.
-  */
-  Set_Both_Sides(YES,tree);
-  new_lk = Lk(NULL,tree);
-
-  if(tree->c_lnL < cur_lk-tree->mod->s_opt->min_diff_lk_local)
-    {
-      PhyML_Printf("\n== tree->c_lnL = %f cur_lk = %f",tree->c_lnL,cur_lk);
-      PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__);
-      Warn_And_Exit("");
-    }
-  cur_lk = new_lk;
-
-  /*
-  ** Recalculate the average distances between all (non-overlapping) subtrees.
-  */
-  root = tree->a_nodes[0];
-  PostOrder_v (tree, root->v[2], root->b[2]);
-}
-
-
-/*
-** Find_Optim_Local: Perform local t_edge length optimization on the candidates in the
-**                   optimization list, and return the first one that gives an
-**                   improvement in likelihood.
-**
-** Parameters:
-**   - tree: The tree on which to check the moves.
-**
-** Returns:
-**   If an improvement was found: The candidate that gives the improvement.
-**   Otherwise:                   -1.
-*/
-
-int Find_Optim_Local (t_tree *tree)
-{
-  int     best_cand, cand, i;
-  t_node   *v_prune, *u_prune, *v_n;
-  t_edge   *e_prune, *e_regraft, *e_connect, *e_avail;
-  phydbl  max_change, new_lk;
-  _move_ *move, *tmp_cand;
-
-  /*
-  ** Try all candidate moves starting from the first one.
-  */
-  best_cand = -1;
-  max_change = 1.0/BIG;
-  for(cand = 0; cand < tree->mod->s_opt->wim_n_optim; cand++)
-    {
-      move = optim_cand[cand];
-      if(move->delta_lk > -1.0*BIG)
-    {
-      /*
-      ** Get the relevant nodes and edges.
-      */
-      v_prune   = move->v_prune;
-      u_prune   = move->u_prune;
-      v_n       = move->v_n;
-      e_prune   = move->e_prune;
-      e_regraft = move->e_regraft;
-
-      /*
-      ** Perform the move and set t_edge lengths.
-      */
-      Prune (e_prune, v_prune, &(e_connect), &(e_avail), tree);
-      Regraft (e_regraft, v_prune, e_avail, tree);
-      e_connect->l_old->v = e_connect->l->v;
-      e_connect->l->v = move->l_connect;
-
-      for (i = 0; i < 3; i++)
-        {
-          v_prune->b[i]->l_old->v = v_prune->b[i]->l->v;
-
-          if (v_prune->v[i] == u_prune)
-        {
-          v_prune->b[i]->l->v = move->l_est[0];
-        }
-          else if (v_prune->v[i] == v_n)
-        {
-          v_prune->b[i]->l->v = move->l_est[1];
-        }
-          else
-        {
-          v_prune->b[i]->l->v = move->l_est[2];
-        }
-        }
-
-      Set_Both_Sides(YES,tree);
-      Lk(NULL,tree);  // Not sure anymore whether this is required...
-
-      /*
-      ** Use Brent optimization on the relevant edges at the regraft position
-      ** and calculate the new likelihood value.
-      */
-      Br_Len_Brent (0.05,20.,v_prune->b[0], tree);
-      Br_Len_Brent (0.05,20.,v_prune->b[1], tree);
-      Br_Len_Brent (0.05,20.,v_prune->b[2], tree);
-
-/* 	  Update_PMat_At_Given_Edge (v_prune->b[0], tree); */
-/* 	  Update_PMat_At_Given_Edge (v_prune->b[1], tree); */
-/* 	  Update_PMat_At_Given_Edge (v_prune->b[2], tree); */
-
-      Update_P_Lk (tree, v_prune->b[0], v_prune);
-      new_lk = Lk(v_prune->b[0],tree);
-
-/* 	  PhyML_Printf("\n. local new_lk = %f",new_lk); */
-
-      /*
-      ** Save the change in likelihood and move the current candidate to the
-      ** appropriate place in the list.
-      */
-      move->delta_lk = new_lk - cur_lk;
-      move->optim_rank = cand;
-      i = cand;
-      while ((i > 0) && (optim_cand[i]->delta_lk > optim_cand[i-1]->delta_lk))
-        {
-          tmp_cand = optim_cand[i];
-          optim_cand[i] = optim_cand[i-1];
-          optim_cand[i-1] = tmp_cand;
-          i--;
-        }
-      if (move->delta_lk > max_change)
-        {
-          best_cand = i;
-          max_change = move->delta_lk;
-          Record_Br_Len(tree);
-        }
-
-
-      /*
-      ** Undo the move again.
-      */
-      Prune (e_prune, v_prune, &(e_regraft), &(e_avail), tree);
-      Regraft (e_connect, v_prune, e_avail, tree);
-      e_regraft->l->v = e_regraft->l_old->v;
-      for (i = 0; i < 3; i++)
-        {
-          v_prune->b[i]->l->v = v_prune->b[i]->l_old->v;
-        }
-      Set_Both_Sides(YES,tree);
-      Lk(NULL,tree);
-      nr_loc++;
-/* 	  PhyML_Printf("\n. local back to = %f",tree->c_lnL); */
-    }
-      else
-    {
-      break;
-    }
-
-      /*
-      ** If an improvement was found, forget the other candidates...
-      */
-      if (best_cand >= 0)
-    {
-      break;
-    }
-    }
-
-  /*
-  ** Return the best candidate.
-  */
-  return (best_cand);
-}
-
-
-/*
-** Find_Optim_Globl: Perform global t_edge length optimization on the candidates in the
-**                   optimization list, and return the first one that gives an
-**                   improvement in likelihood.
-**
-** Parameters:
-**   - tree: The tree on which to check the moves.
-**
-** Returns:
-**   If an improvement is found: The candidate that gives the improvement.
-**   Otherwise:                  -1.
-*/
-
-int Find_Optim_Globl (t_tree *tree)
-{
-  int     best_cand, cand, i;
-  t_node   *v_prune, *u_prune, *v_n;
-  t_edge   *e_prune, *e_regraft, *e_connect, *e_avail;
-  phydbl  max_change, new_lk;
-  _move_ *move;
-
-  /*
-  ** Try all moves.
-  */
-  best_cand = -1;
-  max_change = 1.0/BIG;
-  for (cand = 0; cand < tree->mod->s_opt->wim_n_globl; cand++)
-  {
-    move = optim_cand[cand];
-    if (move->delta_lk > -1.0*BIG)
-    {
-      Record_Br_Len(tree);
-
-      /*
-      ** Get the relevant nodes and edges.
-      */
-      v_prune = move->v_prune;
-      u_prune = move->u_prune;
-      v_n = move->v_n;
-      e_prune = move->e_prune;
-      e_regraft = move->e_regraft;
-
-      /*
-      ** Perform the move and optimize all t_edge lengths.
-      */
-      Prune (e_prune, v_prune, &(e_connect), &(e_avail), tree);
-      Regraft (e_regraft, v_prune, e_avail, tree);
-      e_connect->l_old->v = e_connect->l->v;
-      e_connect->l->v = move->l_connect;
-
-      for (i = 0; i < 3; i++)
-    {
-      v_prune->b[i]->l_old->v = v_prune->b[i]->l->v;
-      if (v_prune->v[i] == u_prune)
-        {
-          v_prune->b[i]->l->v = move->l_est[0];
-        }
-      else if (v_prune->v[i] == v_n)
-        {
-          v_prune->b[i]->l->v = move->l_est[1];
-        }
-      else
-        {
-          v_prune->b[i]->l->v = move->l_est[2];
-        }
-    }
-
-      Set_Both_Sides(YES,tree);
-      Lk(NULL,tree);
-      Optimize_Br_Len_Serie (tree);
-      Set_Both_Sides(YES,tree);
-      new_lk = Lk (NULL,tree);
-
-/*       PhyML_Printf("\n. global new_lk = %f\n",tree->c_lnL); */
-
-      /*
-      ** Save the change in likelihood and undo the move.
-      */
-
-      move->delta_lk = new_lk - cur_lk;
-      move->globl_rank = cand;
-      if (move->delta_lk > max_change)
-    {
-      best_cand = cand;
-      max_change = move->delta_lk;
-      Record_Br_Len(tree);
-    }
-
-      Prune (e_prune, v_prune, &(e_regraft), &(e_avail), tree);
-      Regraft (e_connect, v_prune, e_avail, tree);
-      e_regraft->l->v = e_regraft->l_old->v;
-      for (i = 0; i < 3; i++)
-    {
-      v_prune->b[i]->l->v = v_prune->b[i]->l_old->v;
-    }
-      Set_Both_Sides(YES,tree);
-      Restore_Br_Len(tree);
-      Lk(NULL,tree);
-      nr_glb++;
-/*       PhyML_Printf("\n. global back to = %f",tree->c_lnL); */
-
-    }
-    else break;
-
-    /*
-    ** If an improvement was found, forget the other candidates...
-    */
-    if (best_cand >= 0) break;
-  }
-
-  /*
-  ** Return the best candidate.
-  */
-  return (best_cand);
-}
-
-
-/*
-** Prune: Prune the subtree at a certain t_edge and node. Note that edge
-**        lengths are not set and partial likelihoods are not updated.
-**
-** Parameters:
-**   - e:         The t_edge at which to prune the subtree.
-**   - v:         The t_node adjacent to t_edge e which forms the root of the subtree.
-**   - e_connect: An t_edge pointer which will point to the t_edge that was left
-**                after pruning.
-**   - e_avail:   The t_edge that is "left over" and should be used in the
-**                regrafting step.
-**   - tree:      The tree on which the pruning is done.
-**
-**
-**
-**          \ /
-**           o
-**           |
-**           | e    --> subtree to be pruned
-**           |
-**           o v
-**          / \
-**       e1/   \e2
-**        /     \
-**       o       o
-**      u1       u2   --> such that u1->num < u2->num
-*/
-
-void Prune (t_edge *e, t_node *v, t_edge **e_connect, t_edge **e_avail, t_tree *tree)
-{
-  int     dir0, dir1, dir2, v0, v1, v2, tmp_dir, i, j, k;
-  t_node   *u1, *u2, *tmp_node;
-  t_edge   *e1, *e2;
-  int *sum_scale_f;
-  phydbl *p_lk;
-  int dim1, dim2;
-
-
-  dim1 = tree->mod->ns * tree->mod->ras->n_catg;
-  dim2 = tree->mod->ns;
-
-  /*
-  ** Get the relevant directions, nodes and edges.
-  ** Make sure that t_node u1 is the t_node with the smaller number.
-  */
-  dir0 = -1;
-  for (i = 0; i < 3; i++)
-  {
-    if (v->b[i] == e)
-    {
-      dir0 = i;
-      break;
-    }
-  }
-  dir1 = (dir0 + 1) % 3;
-  dir2 = 3 - dir0 - dir1;
-  u1 = v->v[dir1];
-  u2 = v->v[dir2];
-  if (u1->num > u2->num)
-  {
-    tmp_node = u1;
-    u1 = u2;
-    u2 = tmp_node;
-    tmp_dir = dir1;
-    dir1 = dir2;
-    dir2 = tmp_dir;
-  }
-  e1 = v->b[dir1];
-  e2 = v->b[dir2];
-
-  /*
-  ** Detach t_node v from the tree.
-  */
-  v->v[dir1] = NULL;
-  v->v[dir2] = NULL;
-  v->b[dir1] = NULL;
-  v->b[dir2] = NULL;
-
-  /*
-  ** Connect nodes u1 and u2 via t_edge e1 and copy relevant partial likelihoods.
-  */
-  if (u2 == e2->left)
-  {
-    v0 = e2->l_r;
-    v1 = e2->l_v1;
-    v2 = e2->l_v2;
-    sum_scale_f = e2->sum_scale_left;
-    p_lk = e2->p_lk_left;
-  }
-  else
-  {
-    v0 = e2->r_l;
-    v1 = e2->r_v1;
-    v2 = e2->r_v2;
-    sum_scale_f = e2->sum_scale_rght;
-    p_lk = e2->p_lk_rght;
-  }
-  if (u1 == e1->left)
-  {
-    e1->rght = u2;
-    e1->r_l = v0;
-    e1->r_v1 = v1;
-    e1->r_v2 = v2;
-    for (i = 0; i < tree->n_pattern; i++)
-    {
-      e1->sum_scale_rght[i] = sum_scale_f[i];
-      for (j = 0; j < tree->mod->ras->n_catg; j++)
-      {
-    for (k = 0; k < tree->mod->ns; k++)
-    {
-      e1->p_lk_rght[i*dim1+j*dim2+k] = p_lk[i*dim1+j*dim2+k];
-    }
-      }
-    }
-  }
-  else
-  {
-    e1->left = u2;
-    e1->l_r = v0;
-    e1->l_v1 = v1;
-    e1->l_v2 = v2;
-    for (i = 0; i < tree->n_pattern; i++)
-    {
-      e1->sum_scale_left[i] = sum_scale_f[i];
-      for (j = 0; j < tree->mod->ras->n_catg; j++)
-      {
-    for (k = 0; k < tree->mod->ns; k++)
-    {
-      e1->p_lk_left[i*dim1+j*dim2+k] = p_lk[i*dim1+j*dim2+k];
-    }
-      }
-    }
-  }
-  for (i = 0; i < 3; i++)
-  {
-    if (u1->v[i] == v)
-    {
-      u1->v[i] = u2;
-    }
-    if (u2->v[i] == v)
-    {
-      u2->v[i] = u1;
-      u2->b[i] = e1;
-      u2->l[i] = e1->l->v;
-    }
-  }
-
-  /*
-  ** Make sure that a possible tip t_node is still on the right side.
-  */
-  if (e1->left->tax)
-  {
-    /*
-    ** Swap left and right.
-    */
-    tmp_node = e1->left;
-    e1->left = e1->rght;
-    e1->rght = tmp_node;
-    tmp_dir = e1->l_r;
-    e1->l_r = e1->r_l;
-    e1->r_l = tmp_dir;
-    tmp_dir = e1->l_v1;
-    e1->l_v1 = e1->r_v1;
-    e1->r_v1 = tmp_dir;
-    tmp_dir = e1->l_v2;
-    e1->l_v2 = e1->r_v2;
-    e1->r_v2 = tmp_dir;
-    p_lk = e1->p_lk_left;
-    e1->p_lk_left = e1->p_lk_rght;
-    e1->p_lk_rght = p_lk;
-    sum_scale_f = e1->sum_scale_left;
-    e1->sum_scale_left = e1->sum_scale_rght;
-    e1->sum_scale_rght = sum_scale_f;
-  }
-
-  /*
-  ** Set the connecting and available edges.
-  */
-  *(e_connect) = e1;
-  *(e_avail) = e2;
-}
-
-
-/*
-** Regraft: Regraft a subtree at a certain edge. Note that t_edge lengths
-**          are not set and partial likelihoods are not updated.
-**
-** Parameters:
-**   - e:     The t_edge to regraft the subtree on.
-**   - v:     The root of the subtree to regraft.
-**   - avail: A previously deleted t_edge now available for insertion again.
-**   - tree:  The tree on which the regrafting is done.
-**
-**
-**      \ /
-**       o
-**       |
-**       |   --> subtree to regraft
-**       |
-**       o v
-**
-**   o--------o
-**  u1   e    u2   --> such that u1->num < u2->num
-*/
-
-void Regraft (t_edge *e, t_node *v, t_edge *avail, t_tree *tree)
-{
-  int     dir0, dir1, dir2, i, j, k;
-  int *sum_scale_f;
-  phydbl *p_lk;
-  t_node   *u1, *u2;
-  int dim1, dim2;
-
-  dim1 = tree->mod->ns * tree->mod->ras->n_catg;
-  dim2 = tree->mod->ns ;
-
-  /*
-  ** Get the relevant directions and nodes.
-  */
-  dir0 = -1;
-  for (i = 0; i < 3; i++)
-  {
-    if (v->b[i] != NULL)
-    {
-      dir0 = i;
-      break;
-    }
-  }
-  dir1 = (dir0 + 1) % 3;
-  dir2 = 3 - dir0 - dir1;
-  if (e->left->num < e->rght->num)
-  {
-    u1 = e->left;
-    u2 = e->rght;
-    sum_scale_f = e->sum_scale_rght;
-    p_lk = e->p_lk_rght;
-  }
-  else
-  {
-    u1 = e->rght;
-    u2 = e->left;
-    sum_scale_f = e->sum_scale_left;
-    p_lk = e->p_lk_left;
-  }
-
-  /*
-  ** Connect nodes v and u2 via the available t_edge 'avail' and copy the
-  ** relevant partial likelihood.
-  ** (We want to do this first, cos we need some of the values of edge
-  **  e before changing them below).
-  */
-  avail->left = v;
-  avail->rght = u2;
-  avail->l_r = dir2;
-  avail->l_v1 = dir0;
-  avail->l_v2 = dir1;
-  v->v[dir2] = u2;
-  v->b[dir2] = avail;
-  for (i = 0; i < 3; i++)
-  {
-    if (e == u2->b[i])
-    {
-      u2->v[i] = v;
-      u2->b[i] = avail;
-      avail->r_l = i;
-      avail->r_v1 = (i + 1) % 3;
-      avail->r_v2 = 3 - i - avail->r_v1;
-      break;
-    }
-  }
-  for (i = 0; i < tree->n_pattern; i++)
-  {
-    avail->sum_scale_rght[i] = sum_scale_f[i];
-    for (j = 0; j < tree->mod->ras->n_catg; j++)
-    {
-      for (k = 0; k < tree->mod->ns; k++)
-      {
-    avail->p_lk_rght[i*dim1+j*dim2+k] = p_lk[i*dim1+j*dim2+k];
-      }
-    }
-  }
-
-  /*
-  ** Connect nodes v and u1 via t_edge e.
-  */
-  if (u1 == e->left)
-  {
-    e->rght = v;
-    e->r_l = dir1;
-    e->r_v1 = dir0;
-    e->r_v2 = dir2;
-  }
-  else
-  {
-    e->left = v;
-    e->l_r = dir1;
-    e->l_v1 = dir0;
-    e->l_v2 = dir2;
-  }
-  v->v[dir1] = u1;
-  v->b[dir1] = e;
-  for (i = 0; i < 3; i++)
-  {
-    if (u1->v[i] == u2)
-    {
-      u1->v[i] = v;
-      break;
-    }
-  }
-}
-
-
-/*
-** PostOrder_v: Recursively visit all nodes v in postorder to calculate
-**              the average distance between subtrees.
-**
-** Parameters:
-**   - tree: The tree for which to calculate the average distances.
-**   - v:    The current node.
-**   - e:    The t_edge we came from.
-*/
-
-void PostOrder_v (t_tree *tree, t_node *v, t_edge *e)
-{
-  int   i;
-  t_node *w;
-
-  /*
-  ** If v is not a taxon, recurse.
-  */
-  if (!v->tax)
-  {
-    for (i = 0; i < 3; i++)
-    {
-      if (v->b[i] != e)
-      {
-    PostOrder_v (tree, v->v[i], v->b[i]);
-      }
-    }
-  }
-
-  /*
-  ** Recurse over all nodes w not in the current subtree and calculate
-  ** the average distance between the current subtree and all others.
-  */
-  if (v == e->left)
-  {
-    w = e->rght;
-  }
-  else
-  {
-    w = e->left;
-  }
-  PostOrder_w (tree, v, e, w, e);
-}
-
-
-/*
-** PostOrder_w: Recursively visit all nodes w not in the subtree of v in
-**              postorder and calculate the average distance between the
-**              subtree of v and all others.
-**
-** Parameters:
-**   - tree: The tree for which to calculate the average distances.
-**   - v:    The root t_node of the first subtree.
-**   - v_e:  The t_edge adjacent to the first subtree.
-**   - w:    The current node.
-**   - e:    The t_edge we came from.
-*/
-
-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 shallowest moves first */
+void Sort_Spr_List_Depth(t_tree *tree)
 {
-  int   i;
-  t_node *w1, *w2, *v1, *v2;
-
-  /*
-  ** If w is not a taxon, recurse.
-  */
-  if (!w->tax)
-  {
-    for (i = 0; i < 3; i++)
-    {
-      if (w->b[i] != e)
-      {
-    PostOrder_w (tree, v, v_e, w->v[i], w->b[i]);
-      }
-    }
-  }
+  int i,j;
+  t_spr *buff;
 
-  /*
-  ** Calculate the average distance between the subtrees defined by
-  ** nodes v and w.
-  */
-  if (v->tax && w->tax)
-  {
-    subtree_dist[v->num][w->num] = seq_dist->dist[v->num][w->num];
-  }
-  else if (!v->tax)
-  {
-    v1 = v2 = NULL;
-    for (i = 0; i < 3; i++)
-    {
-      if (v->b[i] != v_e)
-      {
-    if (v1 == NULL)
-    {
-      v1 = v->v[i];
-    }
-    else
-    {
-      v2 = v->v[i];
-    }
-      }
-    }
-    subtree_dist[v->num][w->num] = 0.5*(subtree_dist[v1->num][w->num] +
-                    subtree_dist[v2->num][w->num]);
-  }
-  else
-  {
-    w1 = w2 = NULL;
-    for (i = 0; i < 3; i++)
-    {
-      if (w->b[i] != e)
-      {
-    if (w1 == NULL)
+  for(i=0;i<tree->n_moves-1;i++)
     {
-      w1 = w->v[i];
-    }
-    else
-    {
-      w2 = w->v[i];
-    }
-      }
+      for(j=i+1;j<tree->n_moves;j++)
+        {
+          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];
+              tree->spr_list[j] = buff;
+            }
+        }
     }
-    subtree_dist[v->num][w->num] = 0.5*(subtree_dist[v->num][w1->num] +
-                    subtree_dist[v->num][w2->num]);
-  }
-  subtree_dist[w->num][v->num] = subtree_dist[v->num][w->num];
 }
 
-
 /*********************************************************/
 /*********************************************************/
-/* Sort list of SPR move by putting the deepest moves first */
-void Sort_Spr_List_Depth(t_tree *tree)
+/* Sort list of SPR move by putting the more likely moves first */
+void Sort_Spr_List_LnL(t_tree *tree)
 {
   int i,j;
   t_spr *buff;
 
-  For(i,tree->size_spr_list-1)
+  for(i=0;i<tree->size_spr_list-1;i++)
     {
       for(j=i+1;j<tree->size_spr_list;j++)
         {
-          if(tree->spr_list[j]->depth_path > tree->spr_list[i]->depth_path)
+          if(tree->spr_list[j]->lnL > tree->spr_list[i]->lnL)
             {
               buff              = tree->spr_list[i];
               tree->spr_list[i] = tree->spr_list[j];
@@ -3105,19 +66,20 @@ void Sort_Spr_List_Depth(t_tree *tree)
     }
 }
 
+
 /*********************************************************/
 /*********************************************************/
-/* Sort list of SPR move by putting the more likely moves first */
-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(i=0;i<tree->size_spr_list-1;i++)
     {
       for(j=i+1;j<tree->size_spr_list;j++)
         {
-          if(tree->spr_list[j]->lnL > tree->spr_list[i]->lnL)
+          if(tree->spr_list[j]->pars < tree->spr_list[i]->pars)
             {
               buff              = tree->spr_list[i];
               tree->spr_list[i] = tree->spr_list[j];
@@ -3128,20 +90,18 @@ void Sort_Spr_List_LnL(t_tree *tree)
 }
 
 
-
 /*********************************************************/
 /*********************************************************/
 /*********************************************************/
-/* 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=0;i<tree->n_moves;i++)
     {
-      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,42 +110,82 @@ 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;
 
+  tree->n_improvements = 0;
+  tree->max_spr_depth  = 0;
+
   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)
+  br_idx = Permutate(2*tree->n_otu-3);
+
+  For(i,MAX(1,(int)((2*tree->n_otu-3)*prop_spr)))
     {
+      br = br_idx[i];
+
+      if(!(br%10)) if(tree->io->print_json_trace == YES) JSON_Tree_Io(tree,tree->io->fp_out_json_trace);
+
       b = tree->a_edges[br];
+      if(Uni() < .5)
+        {
+          Spr_Subtree(b,b->left,tree);
+          Spr_Subtree(b,b->rght,tree);
+        }
+      else
+        {
+          Spr_Subtree(b,b->rght,tree);
+          Spr_Subtree(b,b->left,tree);
+        }
+    }
 
-      old_pars = tree->c_pars;
-      Spr_Subtree(b,b->left,tree);
-      new_pars = tree->c_pars;
 
-      pars_diff =  new_pars - old_pars;
-      if(pars_diff > max_pars_diff) max_pars_diff = pars_diff;
+  /* int start_otu = Rand_Int(0,tree->n_otu-1); */
+  /* Spr_Pre_Order(tree->a_nodes[start_otu], */
+  /*               tree->a_nodes[start_otu]->v[0], */
+  /*               tree->a_nodes[start_otu]->b[0], */
+  /*               tree); */
+  /* Free(br_idx); */
 
-      old_pars = tree->c_pars;
-      Spr_Subtree(b,b->rght,tree);
-      new_pars = tree->c_pars;
+  return tree->n_improvements;
+}
 
-      pars_diff = new_pars - old_pars;
-      if(pars_diff > max_pars_diff) max_pars_diff = pars_diff;
-    }
+/*********************************************************/
+
+void Spr_Pre_Order(t_node *a, t_node *d, t_edge *b, t_tree *tree)
+{
+  if(d->tax) return;
+  else
+    {
+      unsigned int i;
+      
+
+      /* printf("\n. a: %d d: %d score: %d d1: %d d2: %d ",a->num,d->num,tree->c_pars); */
+
+      /* for(i=0;i<3;++i) */
+      /*   { */
+      /*     if(d->v[i] != a) */
+      /*       { */
+      /*         Spr_Subtree(d->b[i],d->v[i],tree); */
+      /*       } */
+      /*   } */
 
-/*   tree->mod->s_opt->pars_thresh = MAX(5,max_pars_diff); */
+      Spr_Subtree(b,a,tree);
+      
+      for(i=0;i<3;++i)
+        {
+          if(d->v[i] != a)
+            {
+              Spr_Pre_Order(d,d->v[i],d->b[i],tree);
+            }
+        }
 
-  return 1;
+    }
 }
 
 /*********************************************************/
@@ -3193,13 +193,14 @@ 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;
+  t_edge *init_target, *dummy, *residual;
+    
+  if(link->v[0] == NULL || link->v[1] == NULL || link->v[2] == NULL) return;
+ 
+  best_move_idx = -1;
   tree->n_moves = 0;
-  curr_pars     = tree->c_pars;
 
   MIXT_Set_Pars_Thresh(tree);
 
@@ -3210,122 +211,120 @@ 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"); */
+      tree->mod->s_opt->worst_lnL_spr = BIG;
 
       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;
-
-          if(!tree->io->fp_in_constraint_tree) n_moves = MAX(1,n_moves);
-          n_moves = MIN(n_moves,2*tree->n_otu-3);
+          n_moves_pars = MIN(3,tree->n_moves);
+          n_moves      = MIN(3,tree->n_moves);
 
-          if(tree->mod->s_opt->spr_pars)
+          if(tree->mod->s_opt->spr_lnL == NO) n_moves = n_moves_pars;
+          n_moves = MAX(1,n_moves);
+          
+          if(tree->mod->s_opt->spr_pars == YES)
             {
-              if(tree->io->fp_in_constraint_tree)
-                {
-                  PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__);
-                  Exit("\n");
-                }
-
               min_pars = 1E+8;
               best_pars_move = NULL;
+              
+              for(i=0;i<n_moves;i++)
+                {
+                  if(tree->spr_list[i]->pars < min_pars)
+                    {
+                      best_pars_move = tree->spr_list[i];
+                      min_pars = tree->spr_list[i]->pars;
+                    }
+                }
 
-
-              For(i,n_moves)
-                if(tree->spr_list[i]->pars < min_pars)
-                  {
-                    best_pars_move = tree->spr_list[i];
-                    min_pars = tree->spr_list[i]->pars;
-                  }
-
-              if(best_pars_move->pars < tree->best_pars)
+              if(best_pars_move->pars <= tree->best_pars)
                 {
-                  Prune_Subtree(best_pars_move->n_link,best_pars_move->n_opp_to_link,&target,&residual,tree);
-                  Graft_Subtree(best_pars_move->b_target,best_pars_move->n_link,residual,tree);
-                  Set_Both_Sides(YES,tree);
-                  Pars(NULL,tree);
-                  tree->best_pars = tree->c_pars;
-                  if(tree->best_pars != best_pars_move->pars)
+                  Prune_Subtree(best_pars_move->n_link,best_pars_move->n_opp_to_link,&init_target,&residual,tree);
+                  Graft_Subtree(best_pars_move->b_target,best_pars_move->n_link,NULL,residual,NULL,tree);                  
+                  if(!Check_Topo_Constraints(tree,tree->io->cstr_tree))
+                    {
+                      Prune_Subtree(best_pars_move->n_link,best_pars_move->n_opp_to_link,&dummy,&residual,tree);
+                      Graft_Subtree(init_target,best_pars_move->n_link,NULL,residual,NULL,tree);                  
+                      Set_Both_Sides(YES,tree);
+                      Pars(NULL,tree);
+                    }
+                  else
                     {
-                      PhyML_Printf("\n== best_pars = %d move_pars = %d",tree->best_pars,best_pars_move->pars);
-                      PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__);
-                      Exit("\n");
+                      if(best_pars_move->depth_path > tree->max_spr_depth) tree->max_spr_depth = best_pars_move->depth_path;
+                      Set_Both_Sides(YES,tree);
+                      Pars(NULL,tree);
+                      tree->best_pars = tree->c_pars;
+                      if(tree->best_pars != best_pars_move->pars)
+                        {
+                          PhyML_Printf("\n== best_pars = %d move_pars = %d",tree->best_pars,best_pars_move->pars);
+                          PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__);
+                          Exit("\n");
+                        }
+                      tree->n_improvements++;
                     }
-                  tree->n_improvements++;
                 }
               else
-                Pars(NULL,tree);
+                {
+                  Set_Both_Sides(YES,tree);
+                  Pars(NULL,tree);
+                }
             }
           else
             {
               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);
 
-              /* printf("\n. 2"); fflush(NULL); */
-              /* if(!Check_Lk_At_Given_Edge(YES,tree)) Exit("\n"); */
+                  if(tree->spr_list[0]->lnL > tree->best_lnL)
+                    {
+                      best_move_idx = 0;
+                    }
+                  else if(tree->mod->s_opt->eval_list_regraft == YES)
+                    {
+                      best_move_idx = Evaluate_List_Of_Regraft_Pos_Triple(tree->spr_list,n_moves,tree);
+                    }
+                  else
+                    {
+                      best_move_idx = -1;
+                    }
+                }
+              else
+                {
+                  best_move_idx = Evaluate_List_Of_Regraft_Pos_Triple(tree->spr_list,n_moves,tree);
+                }
 
-              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 +332,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,161 +347,191 @@ 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)
+  for(i=0;i<3;i++)
     if(n_link->v[i] != n_opp_to_link)
       {
         if(dir1<0) dir1 = i;
         else       dir2 = i;
       }
 
+  assert(dir1 > -1);
+  assert(dir2 > -1);
+
   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); */
-        }
+      if(tree->mod->s_opt->spr_lnL == YES) Update_PMat_At_Given_Edge(b_target,tree);
+      
+      for(i=0;i<tree->size_spr_list;++i) tree->spr_list[i]->path_prev = NULL;
 
-      best_found = 0;
+      tree->edge_list = NULL;
+      tree->node_list = NULL;
+      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);
+                                b_target->left,
+                                b_pulled,n_link,b_residual,b_target,&best_found,NULL,tree);
 
+      if(best_found == NO || tree->perform_spr_right_away == 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,NULL,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);
+      Graft_Subtree(b_target,n_link,NULL,b_residual,NULL,tree);
 
+      if((n_link->v[dir1] != n_v1) || (n_link->v[dir2] != n_v2)) PhyML_Printf("\n== Warning: -- SWITCH NEEDED -- ! \n");
 
-      Graft_Subtree(b_target,n_link,b_residual,tree);
+      Copy_Scalar_Dbl(init_l_v1,n_link->b[dir1]->l);
+      Copy_Scalar_Dbl(init_v_v1,n_link->b[dir1]->l_var);
 
+      Copy_Scalar_Dbl(init_l_v2,n_link->b[dir2]->l);
+      Copy_Scalar_Dbl(init_v_v2,n_link->b[dir2]->l_var);
 
-      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_pulled,b_pulled->l);
+      Copy_Scalar_Dbl(init_v_pulled,b_pulled->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; */
+      if(tree->mod->s_opt->spr_pars == 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);
+        }
 
-      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);
+      if(tree->mod->s_opt->spr_pars == NO)
+      	{
+          Update_Partial_Lk(tree,b_pulled,  n_link);
+          Update_Partial_Lk(tree,b_target,  n_link);
+          Update_Partial_Lk(tree,b_residual,n_link);
+        }
+      else
+      	{
+          Update_Partial_Pars(tree,b_pulled,  n_link);
+          Update_Partial_Pars(tree,b_target,  n_link);
+          Update_Partial_Pars(tree,b_residual,n_link);
+        }
 
-      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);
+      t_ll *e_ll = tree->edge_list->head;
+      t_ll *n_ll = tree->node_list->head;
+      t_edge *e;
+      t_node *n;
+      do
+        {
+          assert(e_ll);
+          assert(n_ll);
 
-      /* 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);
-    /* } */
-
-      For(i,3)
-        if(n_link->v[i] != n_opp_to_link)
-          {
-            if(tree->mod->s_opt->spr_lnL)
-              {
-                MIXT_Set_Alias_Subpatt(YES,tree);
-                Pre_Order_Lk(n_link,n_link->v[i],tree);
-                MIXT_Set_Alias_Subpatt(NO,tree);
-              }
-            else
-              Pre_Order_Pars(n_link,n_link->v[i],tree);
-          }
+          e = (t_edge *)e_ll->v;
+          n = (t_node *)n_ll->v;
 
-      /* printf("\n. 000000"); fflush(NULL); */
-      /* if(!Check_Lk_At_Given_Edge(NO,tree)) Exit("\n"); */
+          /* printf("\n. update on edge %d node %d",e->num,n->num); fflush(NULL); */
+          if(tree->mod->s_opt->spr_lnL)
+            Update_Partial_Lk(tree,e,n);
+          else
+            Update_Partial_Pars(tree,e,n);
+            
+          e_ll = e_ll->next;
+          n_ll = n_ll->next;
+        }
+      while(e_ll != NULL);
+
+      Free_Linked_List(tree->edge_list);
+      Free_Linked_List(tree->node_list);
     }
 
   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_spr *prev_move, t_tree *tree)
 {
-  int i;
-
-  if(*best_found) return;
+  unsigned int i;
+  t_spr *move,*next_move;
+  
+  move = next_move = NULL;
+  
+  if(*best_found == YES && tree->perform_spr_right_away == YES) return;
   
   if(d->tax) return;
   else
-    {
-      phydbl move_lnL;
-      
-      For(i,3)
+    {      
+      for(i=0;i<3;++i)
         {
           if(d->v[i] != a)
             {
-              
-              if(tree->mod->s_opt->spr_lnL)
-                {
-                  MIXT_Set_Alias_Subpatt(YES,tree);
-                  Update_P_Lk(tree,d->b[i],d);
-                  MIXT_Set_Alias_Subpatt(NO,tree);
-                }
+              if(tree->mod->s_opt->spr_pars == NO)
+                Update_Partial_Lk(tree,d->b[i],d);
               else
-                Update_P_Pars(tree,d->b[i],d);
-              
+                Update_Partial_Pars(tree,d->b[i],d);
+
+              /* printf("\n push edge %d node %d",d->b[i]->num,d->num); fflush(NULL); */
+              Push_Bottom_Linked_List(d->b[i],&tree->edge_list,NO);
+              Push_Bottom_Linked_List(d,&tree->node_list,NO);
+
               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 = Test_One_Spr_Target(d->b[i],pulled,link,residual,init_target,d,tree);
+
+                  move->path_prev = prev_move;
+
+                  if((tree->mod->s_opt->spr_pars == NO  && move->lnL > tree->best_lnL + tree->mod->s_opt->min_diff_lk_move) ||
+                      (tree->mod->s_opt->spr_pars == YES && move->pars < tree->best_pars)) 
                     {
-                      *best_found = 1;
+                      *best_found = YES;
                     }
                 }
+
+              bool go_to_next =
+                tree->depth_curr_path < tree->mod->s_opt->max_depth_path &&
+                ((tree->mod->s_opt->spr_pars == NO  && move->lnL > tree->best_lnL - tree->mod->s_opt->max_delta_lnL_spr) ||
+                 tree->mod->s_opt->spr_pars == YES);
               
-              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);
-              
+              if(go_to_next == YES) Test_One_Spr_Target_Recur(d,d->v[i],pulled,link,residual,init_target,best_found,move,tree);
+
               tree->depth_curr_path--;
             }
         }
@@ -3510,19 +540,19 @@ 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)
+t_spr *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_node *polarity, 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;
-  phydbl init_lnL, move_lnL;
+  scalar_dbl *l0,*l1,*l2;
+  scalar_dbl *v0,*v1,*v2;
+  t_node *n1,*n2;
+  phydbl init_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;
+  unsigned int rk;
+  
   if(tree->mixt_tree != NULL)
     {
       PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__);
@@ -3530,212 +560,161 @@ phydbl Test_One_Spr_Target(t_edge *b_target, t_edge *b_arrow, t_node *n_link, t_
     }
 
   tree->n_moves++;
-
-  move_lnL  = UNLIKELY;
+  
   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_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_arrow_l    = Duplicate_Scalar_Dbl(b_arrow->l);
+  init_arrow_v    = Duplicate_Scalar_Dbl(b_arrow->l_var);
 
-  if(tree->mod->s_opt->spr_lnL)
+  init_residual_l = Duplicate_Scalar_Dbl(b_residual->l);
+  init_residual_v = Duplicate_Scalar_Dbl(b_residual->l_var);
+
+  Graft_Subtree(b_target,n_link,NULL,b_residual,NULL,tree);
+
+  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);
+      Update_PMat_At_Given_Edge(b_residual,tree);
+      Update_Partial_Lk(tree,b_arrow,n_link);
+      Lk(b_arrow,tree);
     }
   else
     {
-      Update_P_Pars(tree,b_residual,n_link);
-      Pars(b_residual,tree);
+      Update_Partial_Pars(tree,b_arrow,n_link);
+      Pars(b_arrow,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)
+  for(i=0;i<3;++i)
     {
-      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];
-
-      if(tree->mod->gamma_mgf_bl == YES)
-        {
-          move->v0            = l0[i+1];
-          move->v1            = l1[i+1];
-          move->v2            = l2[i+1];
-        }
-
-      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(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;
-        }
+      Free_Scalar_Dbl(move->l0);
+      Free_Scalar_Dbl(move->v0);
+    }
 
-      i+=2;
+  if(move->l1 != NULL)
+    {
+      Free_Scalar_Dbl(move->l1);
+      Free_Scalar_Dbl(move->v1);
     }
-  while(tree);
 
-  b_target = orig_target;
-  n_link   = orig_link;
-  b_arrow  = orig_arrow;
-  tree     = orig_tree;
-  move     = orig_move;
+  if(move->l2 != NULL)
+    {
+      Free_Scalar_Dbl(move->l2);
+      Free_Scalar_Dbl(move->v2);
+    }
 
-  Include_One_Spr_To_List_Of_Spr(move,tree);
+  move->l0 = l0;
+  move->v0 = v0;
 
-  /* b_target->l->v   = init_target_len; */
-  /* b_arrow->l->v    = init_arrow_len; */
-  /* b_residual->l->v = init_residual_len; */
+  move->l1 = l1;
+  move->v1 = v1;
 
-  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);
+  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);
+  
+  rk = Include_One_Spr_To_List_Of_Spr(move,tree);
+    
   Prune_Subtree(n_link,
-        (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);
-
-  tree->c_lnL   = init_lnL;
-  tree->c_pars  = init_pars;
-
-  Free(l0);
-  Free(l1);
-  Free(l2);
+                (n_link==b_arrow->left)?(b_arrow->rght):(b_arrow->left),
+                &b_target,
+                &b_residual,
+                tree);
 
-  Free(init_target_len);
-  Free(init_arrow_len);
-  Free(init_residual_len);
-
-  return move_lnL;
-}
-
-/*********************************************************/
-
-void Speed_Spr_Loop(t_tree *tree)
-{
-  phydbl lk_old;
-
-  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;
-
-  if((tree->mod->s_opt->print) && (!tree->io->quiet)) PhyML_Printf("\n\n. Maximizing likelihood (using SPR moves)...\n");
-
-  SPR_Shuffle(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;
-  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;
-    }
-  while(1);
-  /*****************************/
+  
+  Copy_Scalar_Dbl(init_target_l,b_target->l);
+  Copy_Scalar_Dbl(init_target_v,b_target->l_var);
 
+  Copy_Scalar_Dbl(init_arrow_l,b_arrow->l);
+  Copy_Scalar_Dbl(init_arrow_v,b_arrow->l_var);
 
-  /*****************************/
-  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));
-    }
-  while(FABS(lk_old - tree->c_lnL) > tree->mod->s_opt->min_diff_lk_local);
-  /*****************************/
+  Copy_Scalar_Dbl(init_residual_l,b_residual->l);
+  Copy_Scalar_Dbl(init_residual_v,b_residual->l_var);
 
+  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;
 
-  /*****************************/
-  do
-    {
-      Round_Optimize(tree,tree->data,ROUND_MAX);
-      if(!Check_NNI_Five_Branches(tree)) break;
-    }
-  while(1);
-  /*****************************/
+  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);
 
-/*   if((tree->mod->s_opt->print) && (!tree->io->quiet)) PhyML_Printf("\n"); */
+  return tree->spr_list[rk];
+}
+
+/*********************************************************/
 
+void Speed_Spr_Loop(t_tree *tree)
+{
+  Spr_List_Of_Trees(tree);
+  return;
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-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;
@@ -3747,11 +726,12 @@ void Speed_Spr(t_tree *tree, int max_cycles)
       Exit("\n");
     }
 
-  Set_Both_Sides(YES,tree);
+
+  Set_Both_Sides(NO,tree);
   Pars(NULL,tree);
-  Lk(NULL,tree);
+  if(tree->mod->s_opt->spr_pars == NO) Lk(NULL,tree);
   Record_Br_Len(tree);
-
+ 
   tree->mod->s_opt->deepest_path  = 0;
   tree->best_pars                 = tree->c_pars;
   tree->best_lnL                  = tree->c_lnL;
@@ -3765,29 +745,31 @@ 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);
+      Set_Both_Sides(YES,tree);
+      Pars(NULL,tree);
+      if(tree->mod->s_opt->spr_pars == NO) Lk(NULL,tree);
+      Spr(UNLIKELY,prop_spr,tree);
+
+      // Set maximum depth for future spr rounds to deepest spr found so far
+      tree->mod->s_opt->max_depth_path = tree->max_spr_depth;
 
-      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);
+              /* Print log-likelihood and parsimony scores */
+              if(tree->verbose > VL2 && tree->io->quiet == NO) Print_Lk(tree,"[Branch lengths     ]");
+            }
         }
       else
         {
-          if((tree->mod->s_opt->print) && (!tree->io->quiet)) Print_Pars(tree);
+          if(tree->verbose > VL2 && tree->io->quiet == NO) Print_Pars(tree);
         }
 
       Pars(NULL,tree);
-
+      
       if(tree->io->print_trace)
         {
           char *s = Write_Tree(tree,NO);
@@ -3795,12 +777,14 @@ 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;
-      tree->best_pars = tree->c_pars;
+      if(tree->c_lnL  > tree->best_lnL)  tree->best_lnL  = tree->c_lnL; 
+      if(tree->c_pars < tree->best_pars) tree->best_pars = tree->c_pars;
 
-      if(!tree->mod->s_opt->spr_pars)
+      if(tree->mod->s_opt->spr_pars == NO)
         {
           if(tree->c_lnL < old_lnL-tree->mod->s_opt->min_diff_lk_local)
             {
@@ -3824,25 +808,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,better_found;
   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,18 +837,19 @@ 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;
+  better_found = NO;
 
-  if(!list_size && !tree->io->fp_in_constraint_tree)
+  if(list_size == 0)
     {
       PhyML_Printf("\n== List size is 0 !");
       PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__);
       Exit("\n");
     }
 
-
+  
   recorded = NO;
-  For(i,list_size)
+  for(i=0;i<list_size;i++)
     {
       move = spr_list[i];
 
@@ -3882,7 +866,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 +883,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 */
@@ -3960,130 +914,48 @@ int Evaluate_List_Of_Regraft_Pos_Triple(t_spr **spr_list, int list_size, t_tree
           /* Update conditional likelihoods along the path from the prune to
              the regraft position */
           MIXT_Set_Alias_Subpatt(YES,tree);
-          Update_P_Lk_Along_A_Path(move->path,move->depth_path+1,tree);
+          Update_Partial_Lk_Along_A_Path(move->path,move->depth_path+1,tree);
           MIXT_Set_Alias_Subpatt(NO,tree);
           
           /* Regraft subtree */
-          Graft_Subtree(move->b_target,move->n_link,b_residual,tree);
+          Graft_Subtree(move->b_target,move->n_link,NULL,b_residual,NULL,tree);
+                    
+          MIXT_Set_Alias_Subpatt(YES,tree);
+          move->lnL = Triple_Dist(move->n_link,tree);
+          MIXT_Set_Alias_Subpatt(NO,tree);
+
+          /* printf("\n\u2022 %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 */
           dir_v1 = dir_v2 = dir_v0 = -1;
-          For(j,3)
+          for(j=0;j<3;j++)
             {
               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))
+
+          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)
             {
-              /* Estimate the three t_edge lengths at the regraft site */
-              move->lnL = Triple_Dist(move->n_link,tree,NO);
+              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);
             }
-          
-          /* Record updated branch lengths for this move */
-          orig_move = move;
-          orig_tree = tree;
-          do
+          else
             {
-              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;
-                }
+              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)
+          if(move->lnL > best_lnL)
             {
               best_lnL  = move->lnL;
               best_move = i;
@@ -4098,69 +970,71 @@ int Evaluate_List_Of_Regraft_Pos_Triple(t_spr **spr_list, int list_size, t_tree
           
           Graft_Subtree(init_target,
                         move->n_link,
+                        NULL,
                         b_residual,
+                        NULL,
                         tree);
           
           /* Restore branch lengths */
           Restore_Br_Len(tree);
           
           /* Update relevant change proba matrices */
-          /* 	  Update_PMat_At_Given_Edge(move->n_link->b[0],tree); */
-          /* 	  Update_PMat_At_Given_Edge(move->n_link->b[1],tree); */
-          /* 	  Update_PMat_At_Given_Edge(move->n_link->b[2],tree); */
           Update_PMat_At_Given_Edge(move->b_target,tree);
-          
-          /* 	  Update_P_Lk(tree,move->n_link->b[0],move->n_link); */
-          /* 	  Update_P_Lk(tree,move->n_link->b[1],move->n_link); */
-          /* 	  Update_P_Lk(tree,move->n_link->b[2],move->n_link); */
-          
-          /* Update conditional likelihoods along the path from the prune to
-             the regraft position */
-          /* 	  Update_P_Lk_Along_A_Path(move->path,move->depth_path+1,tree); */
-          
+                    
           tree->c_lnL = init_lnL;
         }
       
+      /* PhyML_Printf("\n\u2022 [ %4d/%4d ] %f %f %s", */
+      /*              i,list_size,tree->best_lnL,move->lnL, */
+      /*              (move->lnL > tree->best_lnL + tree->mod->s_opt->min_diff_lk_move) ? "**" : ""); */
+
+
       /* Bail out as soon as you've found a true improvement */
-      if(move->lnL > tree->best_lnL + tree->mod->s_opt->min_diff_lk_move) break;
+      if(move->lnL > tree->best_lnL + tree->mod->s_opt->min_diff_lk_move) 
+        {
+          better_found = YES;
+          break;      
+        }
     }
   
-  /*   PhyML_Printf("\n. [ %4d/%4d ]",i,list_size); */
-  /*   PhyML_Printf("\n. max_improv = %f",max_improv); */
+  /*   PhyML_Printf("\n\u2022 max_improv = %f",max_improv); */
   
   
-  MIXT_Set_Alias_Subpatt(YES,tree);
-  For(i,list_size)
+  if(better_found == NO)
     {
-      move = spr_list[i];
-      if(move->b_target)
+      MIXT_Set_Alias_Subpatt(YES,tree);
+      for(i=0;i<list_size;i++)
         {
-          For(j,3) Update_PMat_At_Given_Edge(move->n_link->b[j],tree);
-          For(j,3) Update_P_Lk(tree,move->n_link->b[j],move->n_link);
-          
-          /* TO DO : we don't need to update all these partial likelihoods here.
-             Would need to record only those that were along the paths examined
-             above */
-          
-          For(j,3)
-            if(move->n_link->v[j] != move->n_opp_to_link)
-              Pre_Order_Lk(move->n_link,move->n_link->v[j],tree);
-          
-          break;
+          move = spr_list[i];
+          if(move->b_target)
+            {
+              for(j=0;j<3;j++) Update_PMat_At_Given_Edge(move->n_link->b[j],tree);
+              for(j=0;j<3;j++) Update_Partial_Lk(tree,move->n_link->b[j],move->n_link);
+              
+              /* TO DO : we don't need to update all these partial likelihoods here.
+                 Would need to record only those that were along the paths examined
+                 above */
+              
+              for(j=0;j<3;j++)
+                if(move->n_link->v[j] != move->n_opp_to_link)
+                  Pre_Order_Lk(move->n_link,move->n_link->v[j],tree);
+              
+              break;
+            }
         }
-    }  
-  MIXT_Set_Alias_Subpatt(NO,tree);
-  
+      MIXT_Set_Alias_Subpatt(NO,tree);
+    }
+
 #ifdef DEBUG
   if(best_move < 0 && list_size > 0)
     {
-      PhyML_Printf("\n\n. Best_move < 0 !");
-      
-      PhyML_Printf("\n. List size = %d",list_size);
-      For(i,list_size)
+      PhyML_Printf("\n\n== Best_move < 0 !");
+      PhyML_Printf("\n== List size = %d",list_size);
+      PhyML_Printf("\n== Best lnL = %f",best_lnL);
+      for(i=0;i<list_size;i++)
         {
           move = spr_list[i];
-          PhyML_Printf("\n. %p %p",move,move->b_target);
+          PhyML_Printf("\n== move %p %p lnL: %f",move,move->b_target,move->lnL);
         }
       
       PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__);
@@ -4168,7 +1042,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 +1056,7 @@ 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,173 +1067,110 @@ 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);
+  Graft_Subtree(move->b_target,move->n_link,NULL,b_residual,NULL,tree);
 
   dir_v1 = dir_v2 = dir_v0 = -1;
-  For(j,3)
+  for(j=0;j<3;j++)
     {
       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_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;
 
+  
   if(accept == YES) /* Apply the move */
     {
       time(&(tree->t_current));
       Pars(NULL,tree);
       Set_Both_Sides(YES,tree);
-      MIXT_Set_Alias_Subpatt(YES,tree);
       Lk(NULL,tree);
-      MIXT_Set_Alias_Subpatt(NO,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== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__);
-          Exit("\n");
+          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.\n",__FILE__,__LINE__);
+          Check_Lk_At_Given_Edge(YES,tree);
+          Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
         }
 
-      //
-/*       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))
+      if(tree->verbose > VL2 && tree->io->quiet == NO)
         {
           Print_Lk_And_Pars(tree);
           PhyML_Printf(" [depth=%5d]",move->depth_path); fflush(NULL);
         }
 
-      if(move->depth_path > tree->max_spr_depth) tree->max_spr_depth = move->depth_path;
 
       tree->n_improvements++;
+
+      t_spr *dum_move = move;
+      phydbl delta = 0.0;
+      while(dum_move)
+        {
+          delta = move->lnL - dum_move->lnL;          
+          if(delta > tree->mod->s_opt->max_delta_lnL_spr_current)
+            tree->mod->s_opt->max_delta_lnL_spr_current = delta;
+          dum_move = dum_move->path_prev;
+        }
+      
       if(tree->c_lnL > tree->best_lnL) tree->best_lnL = tree->c_lnL;
       Record_Br_Len(tree);
 
       if(move->depth_path > tree->mod->s_opt->deepest_path)
         tree->mod->s_opt->deepest_path = move->depth_path;
 
+      if(move->depth_path > tree->max_spr_depth) tree->max_spr_depth = move->depth_path;
+        
       return 1;
     }
 
   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,
+                NULL,
+                b_residual,
+                NULL,
+                tree);
+  
   Restore_Br_Len(tree);
-
+  
   Set_Both_Sides(YES,tree);
   MIXT_Set_Alias_Subpatt(YES,tree);
   Lk(NULL,tree);
@@ -4383,12 +1193,7 @@ int Try_One_Spr_Move_Full(t_spr *move, t_tree *tree)
         &b_residual,
         tree);
 
-  Graft_Subtree(move->b_target,move->n_link,b_residual,tree);
-
-  MIXT_Set_Alias_Subpatt(YES,tree);
-  Set_Both_Sides(YES,tree);
-  Lk(NULL,tree);
-  MIXT_Set_Alias_Subpatt(NO,tree);
+  Graft_Subtree(move->b_target,move->n_link,NULL,b_residual,NULL,tree);
 
   Optimize_Br_Len_Serie(tree);
 
@@ -4398,7 +1203,7 @@ int Try_One_Spr_Move_Full(t_spr *move, t_tree *tree)
   if(tree->c_lnL > tree->best_lnL + tree->mod->s_opt->min_diff_lk_move)
     {
       Pars(NULL,tree);
-      if((tree->mod->s_opt->print) && (!tree->io->quiet)) Print_Lk(tree,"[Topology           ]");
+      if(tree->verbose > VL0 && tree->io->quiet == NO) Print_Lk(tree,"[Topology           ]");
       tree->n_improvements++;
       tree->best_lnL = tree->c_lnL;
       Record_Br_Len(tree);
@@ -4413,9 +1218,11 @@ int Try_One_Spr_Move_Full(t_spr *move, t_tree *tree)
             tree);
 
       Graft_Subtree(init_target,
-            move->n_link,
-            b_residual,
-            tree);
+                    move->n_link,
+                    NULL,
+                    b_residual,
+                    NULL,
+                    tree);
 
       Restore_Br_Len(tree);
       Set_Both_Sides(YES,tree);
@@ -4432,9 +1239,9 @@ int Try_One_Spr_Move_Full(t_spr *move, t_tree *tree)
 
 /*********************************************************/
 
-void Include_One_Spr_To_List_Of_Spr(t_spr *move, t_tree *tree)
+unsigned int Include_One_Spr_To_List_Of_Spr(t_spr *move, t_tree *tree)
 {
-  int i;
+  unsigned int i, rk;
   t_spr *buff_spr,*orig_move, *orig_move_list, *move_list;
   t_tree *orig_tree;
 
@@ -4444,8 +1251,10 @@ 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)))
+  rk = 0;
+  
+  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,37 +1263,68 @@ 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;
-          
-          
-          if(tree->next)
-            {
-              move      = move->next;
-              move_list = move_list->next;
-              tree      = tree->next;
-            }
-          else
-            {
-              move      = move->next;
-              move_list = move_list->next;
-              tree      = tree->next;
-            }
+          move_list->b_init_target = move->b_init_target;
+
+          move      = move->next;
+          move_list = move_list->next;
+          tree      = tree->next;
         }
       while(tree);
+
       move      = orig_move;
       move_list = orig_move_list;
       tree      = orig_tree;
@@ -4493,8 +1333,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,15 +1345,20 @@ 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;
               
             }
-          else  break;
+          else
+            {
+              rk = i;
+              break;
+            }
         }
     }
+  return rk;
 }
 
 /*********************************************************/
@@ -4529,7 +1374,7 @@ void Random_Spr(int n_moves, t_tree *tree)
   Init_One_Spr(spr_struct);
   target = residual = NULL;
 
-  For(i,n_moves)
+  for(i=0;i<n_moves;i++)
     {
       /* br_pulled = (int)((phydbl)rand()/RAND_MAX * (2*tree->n_otu-3-1)); */
       br_pulled = Rand_Int(0,2*tree->n_otu-3-1);
@@ -4574,8 +1419,9 @@ void Random_Spr(int n_moves, t_tree *tree)
                     tree);
 
       Graft_Subtree(spr_struct->b_target,
-                    spr_struct->n_link,
-                    residual,tree);
+                    spr_struct->n_link,                    
+                    NULL,
+                    residual,NULL,tree);
     }
   Free(spr_struct);
 }
@@ -4586,7 +1432,7 @@ void Reset_Spr_List(t_tree *tree)
 {
   int i;
 
-  For(i,tree->size_spr_list)
+  for(i=0;i<tree->size_spr_list;i++)
     {
       tree->spr_list[i]->depth_path     = 0;
       tree->spr_list[i]->pars           = MAX_PARS;
@@ -4616,35 +1462,37 @@ int Check_Spr_Move_Validity(t_spr *this_spr_move, t_tree *tree)
 
 /*********************************************************/
 
-void Spr_Pars(t_tree *tree)
-{
-
-  PhyML_Printf("\n. Minimizing parsimony...\n");
+void Spr_Pars(int threshold, int n_round_max, t_tree *tree)
+{  
+  int curr_pars,round;
 
-  tree->best_pars = 1E+8;
-  tree->best_lnL  = UNLIKELY;
-  tree->mod->s_opt->spr_lnL = 0;
+  if(tree->verbose > VL2 && tree->io->quiet == NO) PhyML_Printf("\n\u2022 Minimizing parsimony...\n");
 
-  tree->mod->s_opt->spr_pars = 1;
+  tree->best_pars                  = 1E+8;
+  tree->best_lnL                   = UNLIKELY;
+  tree->mod->s_opt->spr_lnL        = NO;
+  tree->mod->s_opt->spr_pars       = YES;
+  curr_pars                        = tree->c_pars;
+  tree->mod->s_opt->max_depth_path = tree->n_otu;
+  round                            = 1;
   do
     {
-      Speed_Spr(tree,1);
-    }while(tree->n_improvements);
-  tree->mod->s_opt->spr_pars = 0;
-
-  PhyML_Printf("\n");
+      curr_pars = tree->c_pars;
+      Speed_Spr(tree,1.0,1,0.0);      
+    }
+  while(tree->n_improvements && FABS(tree->c_pars - curr_pars) > threshold && round++ < n_round_max);
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-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");
+  if(mixt_tree->verbose > VL0) PhyML_Printf("\n\n\u2022 Refining the tree...\n");
 
   /*! Get the number of classes in each mixture */
   orig_catg = MIXT_Get_Number_Of_Classes_In_All_Mixtures(mixt_tree);
@@ -4693,16 +1541,16 @@ 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);
@@ -4710,35 +1558,29 @@ void SPR_Shuffle(t_tree *mixt_tree)
       Pars(NULL,mixt_tree);
       Record_Br_Len(mixt_tree);
 
-      mixt_tree->n_improvements = 0;
-      mixt_tree->max_spr_depth  = 0;
-      mixt_tree->best_pars      = mixt_tree->c_pars;
-      mixt_tree->best_lnL       = mixt_tree->c_lnL;
+      mixt_tree->best_pars = mixt_tree->c_pars;
+      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);
 
   mixt_tree->annealing_temp = 0.0;
 
-  if(mixt_tree->mod->s_opt->print && (!mixt_tree->io->quiet))
+  if(mixt_tree->verbose > VL0 && mixt_tree->io->quiet == NO)
     {
-      PhyML_Printf("\n\n. End of refining stage...\n");
+      PhyML_Printf("\n\n\u2022 End of refining stage...\n");
     }
 
   /*! Go back to the original data structure, with potentially more
@@ -4783,14 +1625,635 @@ 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(NO,tree);
+  Pars(NULL,tree);
+  Lk(NULL,tree);
+
+  tree->mod->s_opt->max_depth_path    = (int)(tree->n_otu/3);
+  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=0;i<3;i++)
+                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=0;i<3;i++)
+                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,NULL,b_residual,NULL,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;
+      Spr(UNLIKELY,prop_spr,tree);
+      
+      tree->annealing_temp -= 0.5;
+      prop_spr+=0.2;
+
+      Optimiz_All_Free_Param(tree,(tree->io->quiet == YES)?(0):(tree->verbose > VL0));
+      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;
+          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);
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void Spr_List_Of_Trees(t_tree *tree)
+{
+  unsigned int i,list_size,max_list_size,iter,n_trees;
+  int *rk,*max_depth_list;
+  t_tree **tree_list,**tree_list_cpy;
+  phydbl *lnL_list,*max_delta_lnL_list,best_lnL;
+  
+  /* const unsigned int list_size_first_round  = 5 + (int)tree->n_otu/20; */
+  const unsigned int list_size_first_round  = 15;
+  const unsigned int list_size_second_round  = 1;
+  const unsigned int list_size_third_round  = 1;
+  
+  best_lnL      = UNLIKELY;
+  tree->verbose = (tree->verbose == VL0) ? VL0 : VL1;
+  max_list_size = MAX(MAX(list_size_first_round,list_size_second_round),list_size_third_round);
+
+  tree_list          = (t_tree **)mCalloc(max_list_size,sizeof(t_tree *));
+  tree_list_cpy      = (t_tree **)mCalloc(max_list_size,sizeof(t_tree *));
+  lnL_list           = (phydbl *)mCalloc(max_list_size,sizeof(phydbl));
+  max_delta_lnL_list = (phydbl *)mCalloc(max_list_size,sizeof(phydbl));
+  max_depth_list     = (int *)mCalloc(max_list_size,sizeof(int));
+
+  for(i=0;i<max_list_size;++i) lnL_list[i] = UNLIKELY;
+  for(i=0;i<max_list_size;++i) tree_list[i] = Make_Tree_From_Scratch(tree->n_otu,tree->data);
+  for(i=0;i<max_list_size;++i) tree_list_cpy[i] = Make_Tree_From_Scratch(tree->n_otu,tree->data);
+  
+  if(tree->io->print_json_trace == YES) JSON_Tree_Io(tree,tree->io->fp_out_json_trace);
+
+  Round_Optimize(tree,10);
+
+  best_lnL = tree->c_lnL;
+  if(tree->verbose > VL0 && tree->io->quiet == NO) PhyML_Printf("\n\n\u2022 Score of initial tree: %12.2f",tree->c_lnL);
+  if(tree->verbose > VL0 && tree->io->quiet == NO) PhyML_Printf("\n\n\u2022 Building a list of starting trees (NNI search)...\n");
+
+  list_size = 0;
+  do
+    {
+      /* if(list_size > 0) */
+        {
+          /* Randomize_Tree(tree,2*tree->n_otu); */
+          Stepwise_Add_Pars(tree);
+          Spr_Pars(0,tree->n_otu,tree);
+        }
+      
+      Add_BioNJ_Branch_Lengths(tree,tree->data,tree->mod,NULL);
+      tree->c_lnL = UNLIKELY;
+      Simu(tree,tree->n_otu);
+      /* Optimize_Br_Len_Serie(tree); */
+      /* Lk(NULL,tree); */
+      
+      if(tree->verbose > VL0 && tree->io->quiet == NO)
+        {
+          if(list_size == 0) Table_Top(25);
+          PhyML_Printf("\n\t \u2502 %3d      %12.2f   \u2502",list_size,tree->c_lnL);
+        }
+      
+      if(tree->c_lnL > best_lnL)
+        {
+          best_lnL = tree->c_lnL;
+          if(tree->verbose > VL0 && tree->io->quiet == NO) PhyML_Printf(" \u2022");
+          if(tree->io->print_json_trace == YES) JSON_Tree_Io(tree,tree->io->fp_out_json_trace);
+        }
+      
+      if(tree->verbose > VL0 && tree->io->quiet == NO)
+        {
+          if(list_size == list_size_first_round - 1) Table_Bottom(25);
+          else Table_Row(25);
+        }
+      
+      Copy_Tree(tree,tree_list[list_size]);
+      lnL_list[list_size] = tree->c_lnL;
+    }
+  while(++list_size < list_size_first_round);
+  
+  rk = Ranks(lnL_list,max_list_size);
+
+  if(tree->verbose > VL0 && tree->io->quiet == NO) PhyML_Printf("\n\n\u2022 Fast optimisation of the best trees (SPR search)...\n");
+  list_size = 0;
+  n_trees   = 0;
+  do
+    {
+      Copy_Tree(tree_list[rk[list_size]],tree);
+ 
+      if(list_size == 0) Round_Optimize(tree,ROUND_MAX);
+
+      do
+        {
+          /* tree->mod->s_opt->max_depth_path            = 1+(int)tree->n_otu/5; */
+          tree->mod->s_opt->max_depth_path            = 15;
+          tree->mod->s_opt->spr_lnL                   = YES;
+          tree->mod->s_opt->spr_pars                  = NO;
+          tree->mod->s_opt->min_diff_lk_move          = 1.E-1;
+          tree->perform_spr_right_away                = YES;
+          tree->mod->s_opt->eval_list_regraft         = NO;
+          tree->mod->s_opt->max_delta_lnL_spr         = 500.;
+          tree->mod->s_opt->max_delta_lnL_spr_current = 0.0;
+          
+          Set_Both_Sides(YES,tree);
+          Lk(NULL,tree);
+          tree->best_lnL = tree->c_lnL;
+          Spr(tree->c_lnL,1.0,tree);
+          Optimize_Br_Len_Serie(tree);
+          tree->mod->s_opt->max_delta_lnL_spr = tree->mod->s_opt->max_delta_lnL_spr_current;
+          tree->mod->s_opt->max_depth_path = tree->max_spr_depth;
+          
+          /* printf("\n. tree->mod->s_opt->max_delta_lnL_spr_current: %12f depth: %4d n_improv: %4d lnL: %f", */
+          /*        tree->mod->s_opt->max_delta_lnL_spr, */
+          /*        tree->mod->s_opt->max_depth_path, */
+          /*        tree->n_improvements, */
+          /*        tree->c_lnL); */
+          
+        }
+      while(tree->n_improvements > 5);
+        
+      n_trees++;
+        
+      if(tree->verbose > VL0 && tree->io->quiet == NO)
+        {
+          if(list_size == 0) Table_Top(25);
+          PhyML_Printf("\n\t \u2502 %3d      %12.2f   \u2502",n_trees,tree->c_lnL);
+        }
+      if(tree->c_lnL > best_lnL)
+        {
+          best_lnL = tree->c_lnL;
+          if(tree->verbose > VL0 && tree->io->quiet == NO) PhyML_Printf(" \u2022");
+          if(tree->io->print_json_trace == YES) JSON_Tree_Io(tree,tree->io->fp_out_json_trace);
+        }
+
+      if(tree->verbose > VL0 && tree->io->quiet == NO)
+        {
+          if(list_size == list_size_second_round - 1) Table_Bottom(25);
+          else Table_Row(25);
+        }
+      
+      Copy_Tree(tree,tree_list[rk[list_size]]);
+      lnL_list[rk[list_size]] = tree->c_lnL;
+      max_depth_list[rk[list_size]] = tree->mod->s_opt->max_depth_path;
+      max_delta_lnL_list[rk[list_size]] = tree->mod->s_opt->max_delta_lnL_spr;
+    }
+  while(++list_size < list_size_second_round);
+
+  Free(rk);
+  rk = Ranks(lnL_list,max_list_size);
+
+  if(tree->verbose > VL0 && tree->io->quiet == NO) PhyML_Printf("\n\n\u2022 Thorough optimisation of the best trees (SPR search)...\n");
+  list_size = 0;
+  n_trees   = 0;
+  do
+    {
+      Copy_Tree(tree_list[rk[list_size]],tree);
+ 
+      if(list_size == 0) Round_Optimize(tree,ROUND_MAX);
+
+      tree->mod->s_opt->max_depth_path            = MAX(5,max_depth_list[rk[list_size]]);
+      tree->mod->s_opt->spr_lnL                   = YES;
+      tree->mod->s_opt->spr_pars                  = NO;
+      tree->mod->s_opt->min_diff_lk_move          = 1.E-1;
+      tree->perform_spr_right_away                = YES;
+      tree->mod->s_opt->eval_list_regraft         = YES;
+      tree->mod->s_opt->max_delta_lnL_spr         = MAX(50.,max_delta_lnL_list[rk[list_size]]);
+
+      /* printf("\n. tree->mod->s_opt->max_delta_lnL_spr: %f max_depth: %d", */
+      /*        tree->mod->s_opt->max_delta_lnL_spr, */
+      /*        tree->mod->s_opt->max_depth_path); */
 
+      iter = 0;
+      do
+        {
+          Set_Both_Sides(YES,tree);
+          Lk(NULL,tree);
+          tree->best_lnL = tree->c_lnL;
+          Spr(tree->c_lnL,1.0,tree);
+          Optimize_Br_Len_Serie(tree);
+          n_trees++;
+          
+          if(tree->verbose > VL0 && tree->io->quiet == NO)
+            {
+              if(iter == 0) Table_Top(25);
+              PhyML_Printf("\n\t \u2502 %3d      %12.2f   \u2502",n_trees,tree->c_lnL);
+            }
+          if(tree->c_lnL > best_lnL)
+            {
+              best_lnL = tree->c_lnL;
+              if(tree->verbose > VL0 && tree->io->quiet == NO) PhyML_Printf(" \u2022");
+              if(tree->io->print_json_trace == YES) JSON_Tree_Io(tree,tree->io->fp_out_json_trace);
+            }
+          if(tree->verbose > VL0 && tree->io->quiet == NO)
+            {
+              if(tree->n_improvements == 0 && iter > 0) Table_Bottom(25);
+              else Table_Row(25);
+            }
+          iter++;
+        }
+      while(tree->n_improvements > 0 || iter <= 1);
+      
+      
+      Copy_Tree(tree,tree_list[rk[list_size]]);
+      lnL_list[rk[list_size]] = tree->c_lnL;
+    }
+  while(++list_size < list_size_third_round);
+  
+  Free(rk);
+  rk = Ranks(lnL_list,max_list_size);
+  Copy_Tree(tree_list[rk[0]],tree);
 
+  
+  if(tree->verbose > VL0 && tree->io->quiet == NO) PhyML_Printf("\n\n\u2022 Final optimisation steps...\n");
 
+  i = tree->verbose;
+  tree->verbose = VL0;
+  tree->mod->s_opt->min_diff_lk_move  = 1.E-2;
+  do
+    {
+      tree->mod->s_opt->fast_nni = NO;
+      Round_Optimize(tree,ROUND_MAX);
+      if(!Check_NNI_Five_Branches(tree)) break;
+    }
+  while(1);
+  tree->verbose = i;
+  
+  for(i=0;i<max_list_size;++i) if(tree_list[i] != NULL) Free_Tree(tree_list[i]);
+  for(i=0;i<max_list_size;++i) if(tree_list_cpy[i] != NULL) Free_Tree(tree_list_cpy[i]);
 
+  Free(tree_list);
+  Free(lnL_list);
+  Free(max_delta_lnL_list);
+  Free(max_depth_list);
+  Free(rk);
+}
 
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
 
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
 
+void Prune_Regraft_Time_Tree(t_tree *tree)
+{
+  phydbl u,ratio;
+  phydbl t_min,t_max;
+  phydbl cur_lnL_seq,new_lnL_seq;
+  phydbl cur_lnL_time,new_lnL_time;
+  phydbl new_t;
+  int i,j,k,prune_idx,n_regraft_nd,regraft_idx,dir_prune;
+  phydbl *times;
+  int rnd_dir,dir_v1,dir_v2,keepon;
+  t_node *prune,*prune_daughter,*new_regraft_nd,*cur_regraft_nd;
+  t_ll *regraft_nd_list;
+  t_edge *target, *ori_target, *residual,*regraft_edge;
+  phydbl regraft_t_min,regraft_t_max;
+  
+  times = tree->rates->nd_t;
+  
+  do
+    {
+      keepon = NO;
+      for(i=tree->n_otu;i<2*tree->n_otu-2;i++) // for each internal node
+        {
+          
+          TIMES_Update_Node_Ordering(tree);
+          
+          RATES_Record_Times(tree);
+          
+          cur_lnL_seq  = tree->c_lnL;
+          new_lnL_seq  = UNLIKELY;
+          cur_lnL_time = tree->rates->c_lnL_times;
+          new_lnL_time = UNLIKELY;
+          
+          regraft_edge   = NULL;
+          new_regraft_nd = NULL;
+          cur_regraft_nd = NULL;
+          new_t          = 0.0;
+          
+          // Prune node
+          prune_idx = i;      
+          prune = tree->a_nodes[prune_idx];      
+          assert(prune && prune->tax == NO);
+          
+          
+          // Select a daughter of prune node
+          dir_v1 = dir_v2 = -1;
+          for(j=0;j<3;j++) 
+            if(prune->v[j] != prune->anc && prune->b[j] != tree->e_root)
+              {
+                if(dir_v1 < 0) dir_v1 = j;
+                else           dir_v2 = j;
+              }
+          
+          u = Uni();
+          if(u < 0.5) rnd_dir = dir_v1;
+          else        rnd_dir = dir_v2;
+          
+          prune_daughter = prune->v[rnd_dir];
+          cur_regraft_nd = prune->v[rnd_dir == dir_v1 ? dir_v2 : dir_v1];            
+          
+          if(prune == tree->n_root)
+            {
+              if(prune_daughter == prune->v[dir_v1] && prune->v[dir_v2]->tax == YES)
+                {
+                  prune_daughter = prune->v[dir_v2];
+                  cur_regraft_nd = prune->v[dir_v1];
+                }
+              
+              if(prune_daughter == prune->v[dir_v2] && prune->v[dir_v1]->tax == YES)
+                {
+                  prune_daughter = prune->v[dir_v1];
+                  cur_regraft_nd = prune->v[dir_v2];
+                }
+            }
+          
+          assert(prune_daughter->anc == prune);
+          
+          dir_prune = -1;
+          for(j=0;j<3;j++)
+            {
+              if(prune_daughter->v[j] == prune || prune_daughter->b[j] == tree->e_root)
+                {
+                  dir_prune = j;
+                  break;
+                }
+            }
+          assert(dir_prune > -1);
+          
+          
+          // Get the list of potential regraft nodes (oldest node on regraft edge)
+          regraft_nd_list = DATE_List_Of_Regraft_Nodes(prune_daughter->v[dir_prune],prune_daughter,&regraft_t_min,&regraft_t_max,NO,tree);
+          assert(regraft_nd_list);
+          if(prune == tree->n_root) Push_Bottom_Linked_List(prune,&regraft_nd_list,YES);
+          
+          
+          // Number of regraft nodes
+          n_regraft_nd = Linked_List_Len(regraft_nd_list);
+          
+          
+          for(j=0;j<n_regraft_nd;j++)
+            {
+              // Randomly select one (uniform)
+              regraft_idx = Rand_Int(0,n_regraft_nd-1);      
+              new_regraft_nd = Linked_List_Elem(regraft_idx,regraft_nd_list);      
+              
+              // Time of regraft node           
+              t_max = MIN(times[prune_daughter->num],times[new_regraft_nd->num]);      
+              if(new_regraft_nd == tree->n_root) t_min = 10.0*t_max;
+              else t_min = times[new_regraft_nd->anc->num];
+              t_min = MAX(t_min,regraft_t_min);
+              
+              new_t = Uni()*(t_max-t_min) + t_min;      
+              
+              
+              // New age
+              if(prune == tree->n_root || new_regraft_nd == tree->n_root)
+                {
+                  if(prune == tree->n_root)
+                    {
+                      if(prune_daughter == tree->n_root->v[1]) times[tree->n_root->num] = times[tree->n_root->v[2]->num];
+                      else                                     times[tree->n_root->num] = times[tree->n_root->v[1]->num];
+                      times[prune_daughter->v[dir_prune]->num] = new_t;
+                    }
+                  if(new_regraft_nd == tree->n_root)
+                    {
+                      times[prune_daughter->v[dir_prune]->num] = times[tree->n_root->num];
+                      times[tree->n_root->num] = new_t;
+                    }
+                }
+              else
+                {
+                  times[prune->num] = new_t;
+                }
+              
+              
+              // Prune
+              target = residual = NULL;
+              Prune_Subtree(prune_daughter->v[dir_prune],
+                            prune_daughter,
+                            &target,&residual,tree);
+              ori_target = target;
+              
+              
+              // Regraft edge is the one sitting above regraft_nd
+              if(new_regraft_nd == tree->n_root->v[1] ||
+                 new_regraft_nd == tree->n_root->v[2] ||
+                 new_regraft_nd == tree->n_root) regraft_edge = tree->e_root;
+              else
+                {
+                  for(k=0;k<3;k++) if(new_regraft_nd->v[k] == new_regraft_nd->anc) break;
+                  assert(k!=3);
+                  regraft_edge = new_regraft_nd->b[k];
+                }
+              
+              assert(regraft_edge);      
+              
+              
+              // Regraft
+              Graft_Subtree(regraft_edge,
+                            prune_daughter->v[dir_prune],
+                            prune_daughter,
+                            residual,
+                            new_regraft_nd,tree);
+              
+              
+              if(!TIMES_Check_Node_Height_Ordering(tree))
+                {
+                  printf("\n== prune[%d]->t:%.3f daughter[%d]->t:%.3f prune_anc[%d]->t:%.3f regraft[%d]->t:%.3f regraft_anc[%d]->t:%.3f [effective:%d] t_prior_min/max: [prune:[%.3f %.3f] regraft:[%.3f %.3f]] ",
+                         prune->num,
+                         times[prune->num],
+                         prune_daughter->num,
+                         times[prune_daughter->num],
+                         prune->anc ? prune->anc->num : -1,
+                         prune->anc ? times[prune->anc->num] : -1.,
+                         new_regraft_nd->num,
+                         times[new_regraft_nd->num],
+                         new_regraft_nd->anc ? new_regraft_nd->anc->num : -1,
+                         new_regraft_nd->anc ? times[new_regraft_nd->anc->num] : +1.,
+                         prune->num,
+                         tree->rates->t_prior_min[prune->num],
+                         tree->rates->t_prior_max[prune->num],
+                         tree->rates->t_prior_min[new_regraft_nd->num],
+                         tree->rates->t_prior_max[new_regraft_nd->num]);
+                  PhyML_Printf("\n== root: %d %d %d",tree->n_root->num,tree->n_root->v[1]->num,tree->n_root->v[2]->num);
+                  Generic_Exit(__FILE__,__LINE__,__FUNCTION__);    
+                }
+              
+              DATE_Assign_Primary_Calibration(tree);
+              new_lnL_time = TIMES_Lk_Times(NO,tree); 
+              
+              if(new_lnL_time > UNLIKELY)
+                {
+                  Set_Both_Sides(NO,tree);
+                  new_lnL_seq = Lk(NULL,tree);
+                }
+              
+              ratio = (new_lnL_seq - cur_lnL_seq);
 
+              
+              if(ratio < .0)
+                {
+                  // Reject
+                  Prune_Subtree(prune_daughter->v[dir_prune],
+                                prune_daughter,
+                                &target,&residual,tree);
+                  Graft_Subtree(ori_target,
+                                prune_daughter->v[dir_prune],
+                                prune_daughter,residual,prune == tree->n_root ? tree->n_root : cur_regraft_nd,tree);
+                  
+                  RATES_Reset_Times(tree);
+                  RATES_Update_Cur_Bl(tree);
+                  DATE_Assign_Primary_Calibration(tree);
+                  TIMES_Lk_Times(NO,tree); 
+                  
+                  
+                  if(!(tree->rates->c_lnL_times > UNLIKELY))
+                    {
+                      printf("\n== time prune: %f",times[prune->num]);
+                      printf("\n== time prune_daughter: %f",times[prune_daughter->num]);
+                      printf("\n== prune: %d prune_daughter: %d prune_daughter->v[dir_prune]: %d cur_regraft_nd: %d new_regraft_nd: %d",
+                             prune->num,
+                             prune_daughter->num,
+                             prune_daughter->v[dir_prune]->num,
+                             cur_regraft_nd->num,
+                             new_regraft_nd->num);
+                      TIMES_Lk_Times(YES,tree); 
+                      fflush(NULL);
+                    }
+                  assert(tree->rates->c_lnL_times > UNLIKELY);
+                  
+                  tree->c_lnL              = cur_lnL_seq;
+                  tree->rates->c_lnL_times = cur_lnL_time;
+                }
+              else
+                {
+                  PhyML_Printf("\n\u2022 Hill-climbing step :: subtree [%4d/%4d] target [%4d/%4d] lnl: %f delta: %f",
+                               i,2*tree->n_otu-2,
+                               j,n_regraft_nd,
+                               tree->c_lnL,
+                               ratio);
+                  if(ratio > 10.) keepon = YES;
+                  break;
+                }
+            }
+          Free_Linked_List(regraft_nd_list);
+        }
+    }while(keepon == YES);
+}
+  
+  
+  //////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
 
 /*
 ** EOF: spr.c
diff --git a/src/spr.h b/src/spr.h
index f10867e..e57a8c3 100644
--- a/src/spr.h
+++ b/src/spr.h
@@ -55,32 +55,37 @@ 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_spr *prev_move, t_tree *tree);
+t_spr *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_node *polarity, 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);
 void Make_Best_Spr(t_tree *tree);
 void Random_Spr(int n_moves, t_tree *tree);
-void Include_One_Spr_To_List_Of_Spr(t_spr *move, t_tree *tree);
+unsigned int Include_One_Spr_To_List_Of_Spr(t_spr *move, t_tree *tree);
 void Reset_Spr_List(t_tree *tree);
 int Evaluate_List_Of_Regraft_Pos_Triple(t_spr **spr_list, int list_size, t_tree *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);
+void Spr_List_Of_Trees(t_tree *tree);
+void Prune_Regraft_Time_Tree(t_tree *tree);
+void Spr_Pre_Order(t_node *a, t_node *d, t_edge *b, t_tree *tree);
 
 
 
diff --git a/src/sse.c b/src/sse.c
new file mode 100644
index 0000000..9bfe3ca
--- /dev/null
+++ b/src/sse.c
@@ -0,0 +1,406 @@
+/*
+
+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 "assert.h"
+#include "sse.h"
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+#if defined(__SSE3__)
+
+void SSE_Update_Eigen_Lr(t_edge *b, t_tree *tree)
+{
+  unsigned int site,catg,state;
+  int is_ambigu,observed_state;
+  unsigned int i,j,k,l;
+  
+  unsigned const int npattern = tree->n_pattern;
+  unsigned const int ncatg = tree->mod->ras->n_catg;
+  unsigned const int ns = tree->mod->ns;
+  unsigned const int sz = (int)BYTE_ALIGN / 8;  
+  unsigned const int nscatg = ncatg * ns;
+  unsigned const int nblocks = ns / sz;
+
+  __m128d _fplk[nblocks],_fplkev[sz],_colsum[nblocks];
+  phydbl *ev;
+  
+  observed_state = -1;
+  
+  ev = NULL;
+#ifndef WIN32
+  if(posix_memalign((void **)&ev,BYTE_ALIGN,(size_t)sz*sizeof(double))) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
+#else
+  ev = _aligned_malloc(sz * sizeof(phydbl),BYTE_ALIGN);
+#endif
+  
+  for(site=0;site<npattern;++site)
+    {
+      is_ambigu = YES;
+      if(b->rght->tax == YES) is_ambigu = b->rght->c_seq->is_ambigu[site];
+      if(is_ambigu == NO) observed_state = b->rght->c_seq->d_state[site];
+
+      for(catg=0;catg<ncatg;++catg)
+        {
+          // Dot product left partial likelihood with equilibrium freqs
+          for(i=0;i<nblocks;++i) _fplk[i] = _mm_mul_pd(_mm_load_pd(b->p_lk_left + site*nscatg + catg*ns + i*sz),
+                                                       _mm_load_pd(tree->mod->e_frq->pi->v + i*sz));
+          
+          for(i=0;i<nblocks;++i) _colsum[i] = _mm_setzero_pd();
+          // Multiply by matrix of right eigen vectors
+          // This matrix is made of nblocks*nblocks squares,
+          // each square being of 'area' sz*sz
+          for(i=0;i<nblocks;++i) // row 
+            {
+              for(j=0;j<nblocks;++j) // column
+                {
+                  for(k=0;k<sz;++k) // column in sz*sz square
+                    {
+                      for(l=0;l<sz;++l) // row in that same square
+                        {
+                          // Copy right eigen vector values column-by-column in block (i,j)
+                          ev[l] = tree->mod->eigen->r_e_vect[i*nblocks*sz*sz + j*sz + l*nblocks*sz + k];
+                        }
+                      _fplkev[k] = _mm_mul_pd(_mm_load_pd(ev),_fplk[i]);
+                    }
+                  _colsum[j] = _mm_add_pd(_colsum[j],_mm_hadd_pd(_fplkev[0],_fplkev[1])); // won't work if sz != 2
+                }
+            }          
+          for(j=0;j<nblocks;++j) _mm_store_pd(tree->eigen_lr_left + catg*ns + j*sz,_colsum[j]);
+
+
+          if(b->rght->tax == YES)
+            for(i=0;i<nblocks;++i) _fplk[i] = _mm_load_pd(b->p_lk_tip_r + site*ns + i*sz); 
+          else
+            for(i=0;i<nblocks;++i) _fplk[i] = _mm_load_pd(b->p_lk_rght + site*nscatg + catg*ns + i*sz); 
+
+          if(is_ambigu == YES)
+            {
+              for(i=0;i<nblocks;++i) _colsum[i] = _mm_setzero_pd();
+              // Multiply by matrix of right eigen vectors
+              // This matrix is made of nblocks*nblocks squares,
+              // each square being of 'area' sz*sz
+              for(i=0;i<nblocks;++i) // row
+                {
+                  for(j=0;j<nblocks;++j) // column
+                    {
+                      for(l=0;l<sz;++l) // row in that same square
+                        {
+                          for(k=0;k<sz;++k) // column in sz*sz square
+                            {
+                              // Copy left eigen vector values column-by-column in block (i,j)
+                              ev[k] = tree->mod->eigen->l_e_vect[i*nblocks*sz*sz + j*sz + l*nblocks*sz + k];
+                            }                          
+                          _fplkev[l] = _mm_mul_pd(_mm_load_pd(ev),_fplk[j]);
+                        }
+                      _colsum[i] = _mm_add_pd(_colsum[i],_mm_hadd_pd(_fplkev[0],_fplkev[1]));
+                    }
+                }
+              for(j=0;j<nblocks;++j) _mm_store_pd(tree->eigen_lr_rght + catg*ns + j*sz,_colsum[j]);
+            }
+          else
+            {
+              for(state=0;state<ns;++state)
+                tree->eigen_lr_rght[catg*ns + state] =
+                  tree->mod->eigen->l_e_vect[state*ns + observed_state];
+            }
+          for(j=0;j<nblocks;++j)
+            _mm_store_pd(&(tree->dot_prod[site*nscatg + catg*ns + j*sz]),
+                         _mm_mul_pd(_mm_load_pd(tree->eigen_lr_rght + catg*ns + j*sz),
+                                    _mm_load_pd(tree->eigen_lr_left + catg*ns + j*sz)));
+        }
+      
+    }
+  
+  if(ev)  Free(ev);
+
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+phydbl SSE_Lk_Core_One_Class_Eigen_Lr(phydbl *dot_prod, phydbl *expl, int ns)
+{
+  phydbl lk;
+  unsigned int l;
+  const unsigned sz = (int)BYTE_ALIGN / 8;
+  const unsigned int nblocks = ns/sz;
+  __m128d _prod[nblocks],_x;
+    
+  for(l=0;l<nblocks;++l) _prod[l] = _mm_load_pd(dot_prod + l*sz);
+  if(expl != NULL) for(l=0;l<nblocks;++l) _prod[l] = _mm_mul_pd(_prod[l],_mm_load_pd(expl + l*sz));
+  _x = _mm_setzero_pd();
+  for(l=0;l<nblocks;++l) _x = _mm_add_pd(_x,_prod[l]);
+  _x = _mm_hadd_pd(_x,_x);
+  _mm_store_sd(&lk,_x);
+  
+  return lk;
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+phydbl SSE_Lk_Core_One_Class_No_Eigen_Lr(phydbl *p_lk_left, phydbl *p_lk_rght, phydbl *Pij, phydbl *pi, int ns, int ambiguity_check, int state)
+{
+  phydbl lk = 0.0;
+  phydbl dum = 0.0;
+  const unsigned int sz = (int)BYTE_ALIGN / 8;
+  const unsigned nblocks = ns/sz;
+  unsigned int i,j,k;
+  __m128d _plk;
+  __m128d _plk_l[nblocks],_plk_r[nblocks];
+  
+  /* [ Pi . Lkr ]' x Pij x Lkl */
+  
+  if(ambiguity_check == NO) // tip case.
+    {
+      for(i=0;i<nblocks;++i) _plk_l[i] = _mm_load_pd(p_lk_left + i*sz);      
+      for(i=0;i<nblocks;++i) _plk_r[i] = _mm_load_pd(Pij + state*ns + i*sz);
+      for(i=0;i<nblocks;++i) _plk_r[i] = _mm_mul_pd(_plk_r[i],_mm_set1_pd(pi[state]));
+      for(i=0;i<nblocks;++i) _plk_r[i] = _mm_mul_pd(_plk_r[i],_plk_l[i]);
+      _plk = _mm_setzero_pd();
+      for(i=0;i<nblocks;++i) _plk = _mm_add_pd(_plk,_plk_r[i]);
+      _plk = _mm_hadd_pd(_plk,_plk);
+      _mm_store_sd(&lk,_plk);
+    }
+  else
+    {
+      __m128d _pij[sz]; 
+      __m128d _pijplk[sz];
+
+      for(i=0;i<nblocks;++i) _plk_r[i] = _mm_load_pd(p_lk_rght + i*sz);
+      for(i=0;i<nblocks;++i) _plk_r[i] = _mm_mul_pd(_plk_r[i],_mm_load_pd(pi + i*sz));
+      for(i=0;i<nblocks;++i) _plk_l[i] = _mm_load_pd(p_lk_left + i*sz);
+
+      for(j=0;j<nblocks;++j)
+        {
+          for(i=0;i<sz;++i) _pijplk[i] = _mm_setzero_pd();
+
+          for(i=0;i<nblocks;++i)
+            {
+              for(k=0;k<sz;++k)
+                {
+                  _pij[k] = _mm_load_pd(Pij + j*nblocks*sz*sz + i*sz + k*ns);
+                  _pij[k] = _mm_mul_pd(_pij[k],_plk_l[i]);
+                  _pijplk[k] = _mm_add_pd(_pijplk[k],_pij[k]);
+                }
+            }
+          
+          _plk = _mm_setzero_pd();
+          for(k=0;k<sz;++k) _plk = _mm_hadd_pd(_plk,_pijplk[k]);
+          
+          _plk = _mm_mul_pd(_plk,_plk_r[j]);
+          _mm_store_sd(&dum,_mm_hadd_pd(_plk,_plk));
+          lk += dum;
+        }
+    }
+  return lk;
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void SSE_Update_Partial_Lk(t_tree *tree, t_edge *b, t_node *d)
+{
+/*
+           |
+           |<- b
+           |
+           d
+          / \
+         /   \
+        /     \
+    n_v1   n_v2
+*/
+  t_node *n_v1, *n_v2;//d's "left" and "right" neighbor nodes
+  phydbl *p_lk,*p_lk_v1,*p_lk_v2;//Partial likelihood vector of node d, d's "left" neighbor, d's "right" neighbor. We fill *p_lk, and assume *p_lk_v1 and *p_lk_v2 are already filled.
+  phydbl *Pij1,*Pij2;
+  phydbl *tPij1,*tPij2;
+  int *sum_scale, *sum_scale_v1, *sum_scale_v2;
+  int sum_scale_v1_val, sum_scale_v2_val;
+  unsigned int  i,k;
+  unsigned int catg/*index over the number of rate categories*/;
+  unsigned int site;
+  phydbl smallest_p_lk,largest_p_lk;
+  phydbl p_lk_lim_inf;
+  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
+
+  const unsigned int ns = tree->mod->ns;
+  const unsigned int ncatg = tree->mod->ras->n_catg;
+  const unsigned int npattern = tree->n_pattern;
+  
+  const unsigned int sz = (int)BYTE_ALIGN / 8;
+  const unsigned nblocks = ns/sz;
+  
+  const unsigned int ncatgns =  ncatg * ns;
+  const unsigned int nsns =  ns * ns;
+  
+  __m128d _x1[nblocks], _x2[nblocks];
+  __m128d _plk[nblocks],_plk1[nblocks],_plk2[nblocks];
+
+    
+  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);
+    }
+
+  sum_scale_v1_val = sum_scale_v2_val = 0;
+
+  if(d->tax)
+    {
+      PhyML_Printf("\n== t_node %d is a leaf...",d->num);
+      PhyML_Printf("\n== Err. in file %s at line %d (function '%s')\n",__FILE__,__LINE__,__FUNCTION__);
+      Exit("\n");
+    }
+
+  sum_scale_v1_val            = 0;
+  sum_scale_v2_val            = 0;  
+  p_lk_lim_inf                = (phydbl)P_LK_LIM_INF;
+  n_v1 = n_v2                 = NULL;
+  p_lk = p_lk_v1 = p_lk_v2    = NULL;
+  Pij1 = Pij2                 = NULL;
+  tPij1 = tPij2               = NULL;
+  sum_scale_v1 = sum_scale_v2 = NULL;
+  p_lk_loc                    = NULL;
+
+  Set_All_Partial_Lk(&n_v1,&n_v2,
+                     &p_lk,&sum_scale,&p_lk_loc,
+                     &Pij1,&tPij1,&p_lk_v1,&sum_scale_v1,
+                     &Pij2,&tPij2,&p_lk_v2,&sum_scale_v2,
+                     d,b,tree);
+
+  if(tree->mod->augmented == YES && n_v1 && n_v1->tax == NO)
+    {
+      PhyML_Printf("\n== SSE version of the Update_Partial_Lk function does not");
+      PhyML_Printf("\n== allow augmented data.");
+      Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
+    }
+
+  /* For every site in the alignment */
+  for(site=0;site<npattern;++site)
+    {
+      if(n_v1->tax == YES &&
+         n_v2->tax == YES &&
+         n_v1->c_seq->state[site] == 'X' &&
+         n_v2->c_seq->state[site] == 'X')
+        {
+          for(i=0;i<ncatgns;++i) p_lk[site*ncatgns + i] = 1.0;
+        }                                                  
+      else
+        {
+          /* For all rate classes */
+          for(catg=0;catg<ncatg;++catg)
+            {                            
+              for(k=0;k<nblocks;++k) _plk1[k] =  _mm_setzero_pd();
+              for(k=0;k<nblocks;++k) _plk2[k] =  _mm_setzero_pd();
+              
+              for(i=0;i<ns;++i) // for each *column*
+                {
+                  
+                  for(k=0;k<nblocks;++k) _x1[k] =  _mm_setzero_pd();
+                  for(k=0;k<nblocks;++k) _x2[k] =  _mm_setzero_pd();
+                  
+                  if(n_v1->tax == NO)
+                    {
+                      if(p_lk_v1[site*ncatgns + catg*ns + i] > 0.0)
+                        for(k=0;k<nblocks;++k) _x1[k] = _mm_mul_pd(_mm_load_pd(tPij1 + catg*nsns + i*ns + sz*k),
+                                                                   _mm_set1_pd(p_lk_v1[site*ncatgns + catg*ns + i]));
+                      
+                      for(k=0;k<nblocks;++k) _plk1[k] = _mm_add_pd(_plk1[k],_x1[k]);
+                    }
+                  else
+                    {
+                      if(p_lk_v1[site*ns + i] > 0.0)
+                        for(k=0;k<nblocks;++k) _x1[k] = _mm_mul_pd(_mm_load_pd(tPij1 + catg*nsns + i*ns + sz*k),
+                                                                   _mm_set1_pd(p_lk_v1[site*ns + i]));
+                      
+                      for(k=0;k<nblocks;++k) _plk1[k] = _mm_add_pd(_plk1[k],_x1[k]);
+                    }
+                  
+                  if(n_v2->tax == NO)
+                    {
+                      if(p_lk_v2[site*ncatgns + catg*ns + i] > 0.0)
+                        for(k=0;k<nblocks;++k) _x2[k] = _mm_mul_pd(_mm_load_pd(tPij2 + catg*nsns + i*ns + sz*k),
+                                                                   _mm_set1_pd(p_lk_v2[site*ncatgns + catg*ns + i]));
+                      
+                      for(k=0;k<nblocks;++k) _plk2[k] = _mm_add_pd(_plk2[k],_x2[k]);
+                    }
+                  else
+                    {
+                      if(p_lk_v2[site*ns + i] > 0.0)
+                        for(k=0;k<nblocks;++k) _x2[k] = _mm_mul_pd(_mm_load_pd(tPij2 + catg*nsns + i*ns + sz*k),
+                                                                   _mm_set1_pd(p_lk_v2[site*ns + i]));
+                      
+                      for(k=0;k<nblocks;++k) _plk2[k] = _mm_add_pd(_plk2[k],_x2[k]);
+                    }                  
+                }
+              
+              for(k=0;k<nblocks;++k) _plk[k] = _mm_mul_pd(_plk1[k],_plk2[k]);
+              
+              for(k=0;k<nblocks;++k) _mm_store_pd(p_lk + site*ncatgns + catg*ns + sz*k,_plk[k]);
+              
+              
+              if(tree->scaling_method == SCALE_RATE_SPECIFIC)
+                {                  
+                  smallest_p_lk = BIG;
+                  for(i=0;i<ns;++i) 
+                    if(p_lk[site*ncatgns+catg*ns+i] < smallest_p_lk) 
+                      smallest_p_lk = p_lk[site*ncatgns+catg*ns+i] ;
+                  
+                  /* Current scaling values at that site */
+                  sum_scale_v1_val = (sum_scale_v1)?(sum_scale_v1[site*ncatg+catg]):(0);
+                  sum_scale_v2_val = (sum_scale_v2)?(sum_scale_v2[site*ncatg+catg]):(0);
+                  
+                  sum_scale[site*ncatg+catg] = sum_scale_v1_val + sum_scale_v2_val;
+                  
+                  /* Scaling. We have p_lk_lim_inf = 2^-500. Consider for instance that
+                     smallest_p_lk = 2^-600, then curr_scaler_pow will be equal to 100, and
+                     each element in the partial likelihood vector will be multiplied by
+                     2^100. */
+                  if(smallest_p_lk < p_lk_lim_inf &&
+                     tree->mod->augmented == NO &&
+                     tree->apply_lk_scaling == YES)
+                    {
+                      int curr_scaler_pow;
+                      curr_scaler_pow = (int)(-500.*LOG2-log(smallest_p_lk))/LOG2;
+                      sum_scale[site*ncatg+catg] += curr_scaler_pow;
+                      for(i=0;i<ns;++i) Rate_Correction(curr_scaler_pow, p_lk + site*ncatgns + catg*ns + i);
+                    }
+                }
+            }              
+        }
+            
+      if(tree->scaling_method == SCALE_FAST)
+        {
+          sum_scale_v1_val = (sum_scale_v1)?(sum_scale_v1[site]):(0);
+          sum_scale_v2_val = (sum_scale_v2)?(sum_scale_v2[site]):(0);              
+          sum_scale[site] = sum_scale_v1_val + sum_scale_v2_val;
+          
+          largest_p_lk = -BIG; 
+          for(i=0;i<ns*ncatg;++i)
+            if(p_lk[site*ncatgns+i] > largest_p_lk)
+              largest_p_lk = p_lk[site*ncatgns+i] ;
+          
+          if(largest_p_lk < INV_TWO_TO_THE_LARGE &&
+             tree->mod->augmented == NO &&
+             tree->apply_lk_scaling == YES)
+            {
+              for(i=0;i<ns*ncatg;++i) p_lk[site*ncatgns + i] *= TWO_TO_THE_LARGE;
+              sum_scale[site] += LARGE;
+            }
+        }
+    }
+}
+
+#endif
diff --git a/src/sse.h b/src/sse.h
new file mode 100644
index 0000000..0f879b2
--- /dev/null
+++ b/src/sse.h
@@ -0,0 +1,36 @@
+/*
+
+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 SSE_H
+#define SSE_H
+
+#include "utilities.h"
+#include "optimiz.h"
+#include "models.h"
+#include "free.h"
+#include "times.h"
+#include "mixt.h"
+
+#if defined(__SSE3__)
+
+void SSE_Update_Partial_Lk(t_tree *tree,t_edge *b_fcus,t_node *n);
+void SSE_Update_Eigen_Lr(t_edge *b, t_tree *tree);
+phydbl SSE_Lk_Core_One_Class_Eigen_Lr(phydbl *dot_prod, phydbl *expl, int ns);
+phydbl SSE_Lk_Core_One_Class_No_Eigen_Lr(phydbl *p_lk_left, phydbl *p_lk_rght, phydbl *Pij, phydbl *pi, int ns, int ambiguity_check, int state);
+phydbl SSE_Lk_Core(int state, int ambiguity_check, t_edge *b, t_tree *tree);
+phydbl SSE_Lk_Core_Nucl(int state, int ambiguity_check, t_edge *b, t_tree *tree);
+phydbl SSE_Lk_Core_AA(int state, int ambiguity_check, t_edge *b, t_tree *tree);
+
+#endif
+#endif
diff --git a/src/stats.c b/src/stats.c
index 742b188..73395bf 100644
--- a/src/stats.c
+++ b/src/stats.c
@@ -112,7 +112,7 @@ int Rand_Int(int min, int max)
 * (2) X1 = Gamma(alpha1,1), X2 = Gamma(alpha2,1) independent
 *     then X = X1+X2 = Gamma(alpha1+alpha2,1)
 * (3) alpha = k = integer then
-*     X = Gamma(k,1) = Erlang(k,1) = -sum(LOG(Ui)) = -LOG(prod(Ui))
+*     X = Gamma(k,1) = Erlang(k,1) = -sum(log(Ui)) = -log(prod(Ui))
 *     where U1,...Uk iid uniform(0,1)
 *
 * Decompose alpha = k+delta with k = [alpha], and 0<delta<1
@@ -127,7 +127,7 @@ phydbl Ahrensdietergamma(phydbl alpha)
   if (alpha>0.) 
     {
       phydbl y = 0.;
-      phydbl b = (alpha+EXP(1.))/EXP(1.);
+      phydbl b = (alpha+exp(1.))/exp(1.);
       phydbl p = 1./alpha;
       int go = 0;
       while (go==0) 
@@ -138,11 +138,11 @@ phydbl Ahrensdietergamma(phydbl alpha)
 	  if (v<=1.) 
 	    {
 	      x = POW(v,p);
-	      y = EXP(-x);
+	      y = exp(-x);
 	    }
 	  else 
 	    {
-	      x = -LOG(p*(b-v));
+	      x = -log(p*(b-v));
 	      y = POW(x,alpha-1.);
 	    }
 	  go = (w<y); // x is accepted when go=1
@@ -219,13 +219,13 @@ phydbl Rgamma(phydbl shape, phydbl scale)
           p = e * Uni();
           if (p >= 1.0) 
             {
-              x = -LOG((e - p) / a);
-              if (Rexp(1.) >= (1.0 - a) * LOG(x))
+              x = -log((e - p) / a);
+              if (Rexp(1.) >= (1.0 - a) * log(x))
                 break;
 	    } 
           else 
             {
-              x = EXP(LOG(p) / a);
+              x = exp(log(p) / a);
               if (Rexp(1.) >= x)
                 break;
 	    }
@@ -302,7 +302,7 @@ phydbl Rgamma(phydbl shape, phydbl scale)
         
         
 	/* Step 7: quotient acceptance (q) */
-	if (LOG(1.0 - u) <= q)
+	if (log(1.0 - u) <= q)
           return scale * ret_val;
       }
     
@@ -327,13 +327,13 @@ phydbl Rgamma(phydbl shape, phydbl scale)
 		    ((((((a7 * v + a6) * v + a5) * v + a4) * v + a3) * v
 		      + a2) * v + a1) * v;
 	    else
-		q = q0 - s * t + 0.25 * t * t + (s2 + s2) * LOG(1.0 + v);
+		q = q0 - s * t + 0.25 * t * t + (s2 + s2) * log(1.0 + v);
 	    /* Step 11:	 hat acceptance (h) */
 	    /* (if q not positive go to step 8) */
 	    if (q > 0.0) {
-		w = EXP(q)-1.0;
+		w = exp(q)-1.0;
 		/* if t is rejected sample again at step 8 */
-		if (c * FABS(u) <= w * EXP(e - 0.5 * t * t))
+		if (c * FABS(u) <= w * exp(e - 0.5 * t * t))
 		    break;
 	    }
 	}
@@ -347,7 +347,7 @@ phydbl Rgamma(phydbl shape, phydbl scale)
 
 phydbl Rexp(phydbl lambda)
 {
-  return -LOG(Uni()+1.E-30)/lambda;
+  return -log(Uni()+1.E-30)/lambda;
 }
 
 /*////////////////////////////////////////////////////////////
@@ -359,7 +359,7 @@ phydbl Rexp_Trunc(phydbl lambda, phydbl left, phydbl rght)
 {
   phydbl u;
   u = Uni();
-  return (left-LOG(1. - u*(1.-EXP(-lambda*(rght-left))))/lambda);
+  return (left-log(1. - u*(1.-exp(-lambda*(rght-left))))/lambda);
 }
 
 /*////////////////////////////////////////////////////////////
@@ -372,7 +372,7 @@ phydbl Rnorm(phydbl mean, phydbl sd)
   
   /* u1=Uni(); */
   /* u2=Uni(); */
-  /* u1 = SQRT(-2.*LOG(u1))*COS(6.28318530717959f*u2); */
+  /* u1 = SQRT(-2.*log(u1))*COS(6.28318530717959f*u2); */
 
   /* Polar */
   phydbl d,x,y;
@@ -387,7 +387,7 @@ phydbl Rnorm(phydbl mean, phydbl sd)
       if(d>.0 && d<1.) break;
     }
   while(1);
-  u1 = x*SQRT((-2.*LOG(d))/d);
+  u1 = x*SQRT((-2.*log(d))/d);
 
   res = u1*sd+mean;
 
@@ -412,9 +412,9 @@ phydbl *Rnorm_Multid(phydbl *mu, phydbl *cov, int dim)
 
   L = (phydbl *)Cholesky_Decomp(cov,dim);
 
-  For(i,dim) x[i]=Rnorm(0.0,1.0);
-  For(i,dim) For(j,dim) y[i] += L[i*dim+j]*x[j];
-  For(i,dim) y[i] += mu[i];
+  for(i=0;i<dim;i++) x[i]=Rnorm(0.0,1.0);
+  for(i=0;i<dim;i++) for(j=0;j<dim;j++) y[i] += L[i*dim+j]*x[j];
+  for(i=0;i<dim;i++) y[i] += mu[i];
 
   Free(L);
   Free(x);
@@ -513,11 +513,11 @@ phydbl Rnorm_Trunc(phydbl mean, phydbl sd, phydbl min, phydbl max, int *error)
     {
       algo = 0;
     }
-  if((z_min > 0.0 || Are_Equal(z_min,0.0,1.E-10)) && z_max > z_min + 2.*SQRT(EXP(1.0))/(z_min + SQRT(z_min*z_min+4.)) * EXP((z_min*z_min - z_min*SQRT(z_min*z_min+4.))/4.))
+  if((z_min > 0.0 || Are_Equal(z_min,0.0,1.E-10)) && z_max > z_min + 2.*SQRT(exp(1.0))/(z_min + SQRT(z_min*z_min+4.)) * exp((z_min*z_min - z_min*SQRT(z_min*z_min+4.))/4.))
     {
       algo = 1;
     }
-  else if((z_max < 0.0 || Are_Equal(z_max,0.0,1.E-10)) && -z_min > -z_max + 2.*SQRT(EXP(1.0))/(-z_max + SQRT(z_max*z_max+4.)) * EXP((z_max*z_max - (-z_max)*SQRT(z_max*z_max+4.))/4.))
+  else if((z_max < 0.0 || Are_Equal(z_max,0.0,1.E-10)) && -z_min > -z_max + 2.*SQRT(exp(1.0))/(-z_max + SQRT(z_max*z_max+4.)) * exp((z_max*z_max - (-z_max)*SQRT(z_max*z_max+4.))/4.))
     {
       algo = 2;
     }
@@ -559,7 +559,7 @@ phydbl Rnorm_Trunc(phydbl mean, phydbl sd, phydbl min, phydbl max, int *error)
                 PhyML_Printf("\n== Too many iterations in Rnorm_Trunc()");
                 *error = YES; 
               }
-          }while(u > EXP(-POW(q-a,2)/2.));
+          }while(u > exp(-POW(q-a,2)/2.));
         z = q;
         break;
       }
@@ -577,7 +577,7 @@ phydbl Rnorm_Trunc(phydbl mean, phydbl sd, phydbl min, phydbl max, int *error)
                 PhyML_Printf("\n== Too many iterations in Rnorm_Trunc()");
                 *error = YES; 
               }
-          }while(u > EXP(-POW(q-a,2)/2.));
+          }while(u > exp(-POW(q-a,2)/2.));
         z = -q;
         break;
       }
@@ -587,9 +587,9 @@ phydbl Rnorm_Trunc(phydbl mean, phydbl sd, phydbl min, phydbl max, int *error)
         do
           {
             z = Uni()*(z_max - z_min) + z_min;
-            if(z_min < 0.0 && z_max > 0.0) q = EXP(-z*z/2.);
-            else if (z_max < 0.0) q = EXP((z_max*z_max-z*z)/2.);
-            else q = EXP((z_min*z_min-z*z)/2.);
+            if(z_min < 0.0 && z_max > 0.0) q = exp(-z*z/2.);
+            else if (z_max < 0.0) q = exp((z_max*z_max-z*z)/2.);
+            else q = exp((z_min*z_min-z*z)/2.);
             u = Uni();
             n_iter++;
             if(n_iter > n_max_iter)
@@ -633,7 +633,7 @@ phydbl *Rnorm_Multid_Trunc(phydbl *mean, phydbl *cov, phydbl *min, phydbl *max,
   for(i=1;i<dim;i++)
     {
       rec = .0;
-      For(j,i) rec += L[i*dim+j] * u[j];
+      for(j=0;j<i;j++) rec += L[i*dim+j] * u[j];
       low  = (min[i]-mean[i]-rec)/L[i*dim+i];
       up   = (max[i]-mean[i]-rec)/L[i*dim+i];
       u[i] = Rnorm_Trunc(0.0,1.0,low,up,&err);
@@ -642,9 +642,9 @@ phydbl *Rnorm_Multid_Trunc(phydbl *mean, phydbl *cov, phydbl *min, phydbl *max,
   x = Matrix_Mult(L,u,dim,dim,dim,1);
 
 /*   PhyML_Printf("\n>>>\n"); */
-/*   For(i,dim) */
+/*   for(i=0;i<dim;i++) */
 /*     { */
-/*       For(j,dim) */
+/*       for(j=0;j<dim;j++) */
 /* 	{ */
 /* 	  PhyML_Printf("%10lf ",L[i*dim+j]); */
 /* 	} */
@@ -652,15 +652,15 @@ phydbl *Rnorm_Multid_Trunc(phydbl *mean, phydbl *cov, phydbl *min, phydbl *max,
 /*     } */
 /*   PhyML_Printf("\n"); */
 
-/*   For(i,dim) PhyML_Printf("%f ",u[i]); */
+/*   for(i=0;i<dim;i++) PhyML_Printf("%f ",u[i]); */
 /*   PhyML_Printf("\n"); */
 
   
 /*   PhyML_Printf("\n"); */
-/*   For(i,dim) PhyML_Printf("%10lf ",x[i]); */
+/*   for(i=0;i<dim;i++) PhyML_Printf("%10lf ",x[i]); */
 /*   PhyML_Printf("\n<<<\n"); */
 
-  For(i,dim) x[i] += mean[i];
+  for(i=0;i<dim;i++) x[i] += mean[i];
 
   Free(L);
   Free(u);
@@ -677,7 +677,7 @@ phydbl Rgeom(phydbl p)
 
   u = Uni();
   if(u < SMALL) return(0.0);
-  x = LOG(u) / LOG(1. - p);
+  x = log(u) / log(1. - p);
   
   return(CEIL(x));  
 }
@@ -697,7 +697,7 @@ phydbl Dgeom(phydbl k, phydbl p, int logit)
     }
 
   if(logit == YES)
-    prob = (k - 1.)*LOG(1. - p) + LOG(p);
+    prob = (k - 1.)*log(1. - p) + log(p);
   else
     prob = POW(1.-p,k-1.)*p;
 
@@ -931,7 +931,7 @@ phydbl Dnorm_Moments(phydbl x, phydbl mean, phydbl var)
   pi = 3.141593;
   sd = SQRT(var);
 
-  dens = 1./(SQRT(2*pi)*sd)*EXP(-((x-mean)*(x-mean)/(2.*sd*sd)));
+  dens = 1./(SQRT(2*pi)*sd)*exp(-((x-mean)*(x-mean)/(2.*sd*sd)));
 
   return dens;
 }
@@ -944,12 +944,12 @@ phydbl Dnorm(phydbl x, phydbl mean, phydbl sd)
 {
   phydbl dens;
 
-  /* dens = -(.5*LOG2PI+LOG(sd))  - .5*POW(x-mean,2)/POW(sd,2); */
-  /* return EXP(dens); */
+  /* dens = -(.5*LOG2PI+log(sd))  - .5*POW(x-mean,2)/POW(sd,2); */
+  /* return exp(dens); */
   
   x = (x-mean)/sd;
 
-  dens = M_1_SQRT_2_PI * EXP(-0.5*x*x);
+  dens = M_1_SQRT_2_PI * exp(-0.5*x*x);
   
   return dens / sd;
 }
@@ -965,7 +965,7 @@ phydbl Log_Dnorm(phydbl x, phydbl mean, phydbl sd, int *err)
 
   x = (x-mean)/sd;
   
-  dens = -(phydbl)LOG(SQRT(2.*PI)) - x*x*0.5 - LOG(sd);
+  dens = -(phydbl)log(SQRT(2.*PI)) - x*x*0.5 - log(sd);
 
   if(dens < -BIG)
     {
@@ -1003,11 +1003,11 @@ phydbl Log_Dnorm_Trunc(phydbl x, phydbl mean, phydbl sd, phydbl lo, phydbl up, i
 
   if(cdf_up - cdf_lo < 1.E-20)
     {
-      log_dens = -230.; /* ~LOG(1.E-100) */
+      log_dens = -230.; /* ~log(1.E-100) */
     }
   else
     {
-      log_dens -= LOG(cdf_up - cdf_lo);
+      log_dens -= log(cdf_up - cdf_lo);
     }
 
   if(isnan(log_dens) || isinf(FABS(log_dens)))
@@ -1059,7 +1059,7 @@ phydbl Dnorm_Multi(phydbl *x, phydbl *mu, phydbl *cov, int size, int _log)
   xmmu   = (phydbl *)mCalloc(size,sizeof(phydbl));
   invcov = (phydbl *)mCalloc(size*size,sizeof(phydbl));
 
-  For(i,size) xmmu[i] = x[i] - mu[i];
+  for(i=0;i<size;i++) xmmu[i] = x[i] - mu[i];
   For(i,size*size) invcov[i] = cov[i];
   
   if(!Matinv(invcov,size,size,NO))
@@ -1074,17 +1074,17 @@ phydbl Dnorm_Multi(phydbl *x, phydbl *mu, phydbl *cov, int size, int _log)
   det = Matrix_Det(cov,size,NO);
   /* det_1D(cov,size,&det); */
 
-  density = size * LOG2PI + LOG(det) + buff2[0];
+  density = size * LOG2PI + log(det) + buff2[0];
   density /= -2.;
 
-/*   density = (1./(POW(2.*PI,size/2.)*SQRT(FABS(det)))) * EXP(-0.5*buff2[0]); */
+/*   density = (1./(POW(2.*PI,size/2.)*SQRT(FABS(det)))) * exp(-0.5*buff2[0]); */
 
   Free(xmmu);
   Free(invcov);
   Free(buff1);
   Free(buff2);
 
-  return (_log)?(density):(EXP(density));
+  return (_log)?(density):(exp(density));
 }
 
 //////////////////////////////////////////////////////////////
@@ -1100,7 +1100,7 @@ phydbl Dnorm_Multi_Given_InvCov_Det(phydbl *x, phydbl *mu, phydbl *invcov, phydb
 
   xmmu = (phydbl *)mCalloc(size,sizeof(phydbl));
 
-  For(i,size) xmmu[i] = x[i] - mu[i];
+  for(i=0;i<size;i++) xmmu[i] = x[i] - mu[i];
   
   buff1 = Matrix_Mult(xmmu,invcov,1,size,size,size);
   buff2 = Matrix_Mult(buff1,xmmu,1,size,size,1);
@@ -1112,7 +1112,7 @@ phydbl Dnorm_Multi_Given_InvCov_Det(phydbl *x, phydbl *mu, phydbl *invcov, phydb
   Free(buff1);
   Free(buff2);
   
-  return (_log)?(density):(EXP(density));
+  return (_log)?(density):(exp(density));
 }
 
 //////////////////////////////////////////////////////////////
@@ -1143,7 +1143,7 @@ phydbl Bivariate_Normal_Density(phydbl x, phydbl y, phydbl mux, phydbl muy, phyd
   rho2 = rho*rho;
 
   dens = 1./(2*pi*sdx*sdy*SQRT(1.-rho2));
-  dens *= EXP((-1./(2.*(1.-rho2)))*(cx*cx/(sdx*sdx)+cy*cy/(sdy*sdy)+2*rho*cx*cy/(sdx*sdy)));
+  dens *= exp((-1./(2.*(1.-rho2)))*(cx*cx/(sdx*sdx)+cy*cy/(sdy*sdy)+2*rho*cx*cy/(sdx*sdy)));
 	      
   return dens;
 }
@@ -1154,7 +1154,7 @@ phydbl Bivariate_Normal_Density(phydbl x, phydbl y, phydbl mux, phydbl muy, phyd
 phydbl Dnbinom(phydbl x, phydbl n, phydbl p, int logit)
 {
 
-  phydbl lnDens = LnGamma(x+n) - LnGamma(n) - LnFact(x) + n*LOG(p) + x*LOG(1.-p);
+  phydbl lnDens = LnGamma(x+n) - LnGamma(n) - LnFact(x) + n*log(p) + x*log(1.-p);
 
   if(logit == TRUE)
     {
@@ -1162,7 +1162,7 @@ phydbl Dnbinom(phydbl x, phydbl n, phydbl p, int logit)
     }
   else
     {
-      return(EXP(lnDens));
+      return(exp(lnDens));
     }
 }
 
@@ -1221,13 +1221,13 @@ phydbl Dgamma(phydbl x, phydbl shape, phydbl scale)
       x = 1.E+10;
     }
 
-  if(x < 1.E-20)
+  if(x < 1.E-200)
     {
       if(x < 0.0) return 0.0;
       else
 	{
-	  PhyML_Printf("\n. WARNING: small value of x -> x = %G",x);
-	  x = 1.E-20;
+	  PhyML_Printf("\n. WARNING: Dgamma -> small value of x = %G (shape: %G scale: %G <X>: %G)",x,shape,scale,shape*scale);
+	  x = 1.E-200;
 	}
     }
 
@@ -1239,18 +1239,18 @@ phydbl Dgamma(phydbl x, phydbl shape, phydbl scale)
     }
 
 
-  v = (shape-1.) * LOG(x) - shape * LOG(scale) - x / scale - LnGamma(shape);
+  v = (shape-1.) * log(x) - shape * log(scale) - x / scale - LnGamma(shape);
 
 
   if(v < 500.)
     {
-      v = EXP(v);
+      v = exp(v);
     }
   else
     {
       PhyML_Printf("\n. WARNING v=%f x=%f shape=%f scale=%f",v,x,shape,scale);
-      PhyML_Printf("\n. LOG(x) = %G LnGamma(shape)=%G",LOG(x),LnGamma(shape));
-      v = EXP(v);
+      PhyML_Printf("\n. log(x) = %G LnGamma(shape)=%G",log(x),LnGamma(shape));
+      v = exp(v);
       /* PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); */
       /* Exit("\n"); */
     }
@@ -1264,7 +1264,7 @@ phydbl Dgamma(phydbl x, phydbl shape, phydbl scale)
 
 phydbl Dexp(phydbl x, phydbl param)
 {
-  return param * EXP(-param * x);
+  return param * exp(-param * x);
 }
 
 /*////////////////////////////////////////////////////////////
@@ -1275,7 +1275,7 @@ phydbl Dexp(phydbl x, phydbl param)
 
 phydbl Dexp_Trunc(phydbl x, phydbl lambda, phydbl left, phydbl rght)
 {
-  return (lambda * EXP(-lambda * x))/(EXP(-lambda * left) - EXP(-lambda * rght));
+  return (lambda * exp(-lambda * x))/(exp(-lambda * left) - exp(-lambda * rght));
 }
 
 /*////////////////////////////////////////////////////////////
@@ -1291,25 +1291,25 @@ phydbl Dpois(phydbl x, phydbl param, int logit)
       else return 0.0;
    }
 
-  v = x * LOG(param) - param - Factln(x);
+  v = x * log(param) - param - Factln(x);
   if(logit == YES) return v;
   else
     {
       if(v < 500.)
         {
-          v = EXP(v);
+          v = exp(v);
         }
       else
         {
           PhyML_Printf("\n. WARNING v=%f x=%f param=%f",v,x,param);
-          v = EXP(500);
+          v = exp(500);
         }
       
       /*   PhyML_Printf("\n. Poi %f %f (x=%f param=%f)", */
       /* 	 v, */
-      /* 	 POW(param,x) * EXP(-param) / EXP(LnGamma(x+1)), */
+      /* 	 POW(param,x) * exp(-param) / exp(LnGamma(x+1)), */
       /* 	 x,param); */
-      /*   return POW(param,x) * EXP(-param) / EXP(LnGamma(x+1)); */
+      /*   return POW(param,x) * exp(-param) / exp(LnGamma(x+1)); */
   
       return v;
     }
@@ -1344,13 +1344,13 @@ phydbl Pnorm(phydbl x, phydbl mean, phydbl sd)
 /*   if(x >= 0.0) */
 /*     { */
 /*       phydbl t = 1.0 / ( 1.0 + p * x ); */
-/*       return (1.0 - c * EXP( -x * x / 2.0 ) * t * */
+/*       return (1.0 - c * exp( -x * x / 2.0 ) * t * */
 /* 	      ( t *( t * ( t * ( t * b5 + b4 ) + b3 ) + b2 ) + b1 )); */
 /*     } */
 /*   else */
 /*     { */
 /*       phydbl t = 1.0 / ( 1.0 - p * x ); */
-/*       return ( c * EXP( -x * x / 2.0 ) * t * */
+/*       return ( c * exp( -x * x / 2.0 ) * t * */
 /* 	       ( t *( t * ( t * ( t * b5 + b4 ) + b3 ) + b2 ) + b1 )); */
 /*     } */
 
@@ -1656,7 +1656,7 @@ phydbl PointNormal (phydbl prob)
    p1 = (p<0.5 ? p : 1-p);
    if (p1<1e-20) z=999;
    else {
-      y = SQRT (LOG(1/(p1*p1)));   
+      y = SQRT (log(1/(p1*p1)));   
       z = y + ((((y*a4+a3)*y+a2)*y+a1)*y+a0) / ((((y*b4+b3)*y+b2)*y+b1)*y+b0);
    }
    return (p<0.5 ? -z : z);
@@ -1759,7 +1759,7 @@ phydbl PointNormal (phydbl prob)
 
 phydbl Bico(int n, int k)
 {
-  return FLOOR(0.5+EXP(Factln(n)-Factln(k)-Factln(n-k)));
+  return FLOOR(0.5+exp(Factln(n)-Factln(k)-Factln(n-k)));
 }
 
 
@@ -1947,7 +1947,7 @@ int DiscreteGamma (phydbl freqK[], phydbl rK[],
 //////////////////////////////////////////////////////////////
 
 
-/* Return LOG(n!) */
+/* Return log(n!) */
 
 phydbl LnFact(int n)
 {
@@ -1955,7 +1955,7 @@ phydbl LnFact(int n)
   phydbl res;
 
   res = .0;
-  for(i=2;i<n+1;i++) res += LOG((phydbl)i);
+  for(i=2;i<n+1;i++) res += log((phydbl)i);
   
   return(res);
 }
@@ -2003,33 +2003,33 @@ phydbl *Covariance_Matrix(t_tree *tree)
   ori_wght = (int *)mCalloc(tree->data->crunch_len,sizeof(int));
   site_num = (int *)mCalloc(tree->data->init_len,sizeof(int));
   
-  For(i,tree->data->crunch_len) ori_wght[i] = tree->data->wght[i];
+  for(i=0;i<tree->data->crunch_len;i++) ori_wght[i] = tree->data->wght[i];
 
   n_site = 0;
-  For(i,tree->data->crunch_len) For(j,tree->data->wght[i])
+  for(i=0;i<tree->data->crunch_len;i++) For(j,tree->data->wght[i])
     {
       site_num[n_site] = i;
       n_site++;
     }
 
   
-  tree->mod->s_opt->print = 0;
-  For(replicate,sample_size)
+  tree->verbose = VL0;
+  for(replicate=0;replicate<sample_size;replicate++)
     {
       For(i,2*tree->n_otu-3) tree->a_edges[i]->l->v = .1;
 
-      For(i,tree->data->crunch_len) tree->data->wght[i] = 0;
+      for(i=0;i<tree->data->crunch_len;i++) tree->data->wght[i] = 0;
 
-      For(i,tree->data->init_len)
+      for(i=0;i<tree->data->init_len;i++)
 	{
 	  position = Rand_Int(0,(int)(tree->data->init_len-1.0));
 	  tree->data->wght[site_num[position]] += 1;
 	}
 
-      Round_Optimize(tree,tree->data,ROUND_MAX);
+      Round_Optimize(tree,ROUND_MAX);
       
-      For(i,2*tree->n_otu-3) For(j,2*tree->n_otu-3) cov[i*dim+j] += LOG(tree->a_edges[i]->l->v) * LOG(tree->a_edges[j]->l->v);  
-      For(i,2*tree->n_otu-3) mean[i] += LOG(tree->a_edges[i]->l->v);
+      For(i,2*tree->n_otu-3) For(j,2*tree->n_otu-3) cov[i*dim+j] += log(tree->a_edges[i]->l->v) * log(tree->a_edges[j]->l->v);  
+      For(i,2*tree->n_otu-3) mean[i] += log(tree->a_edges[i]->l->v);
 
       PhyML_Printf("[%3d/%3d]",replicate,sample_size); fflush(NULL);
 /*       PhyML_Printf("\n. %3d %12f %12f %12f ", */
@@ -2058,7 +2058,7 @@ phydbl *Covariance_Matrix(t_tree *tree)
 /*       PhyML_Printf("\n"); */
 /*     } */
 
-  For(i,tree->data->crunch_len) tree->data->wght[i] = ori_wght[i];
+  for(i=0;i<tree->data->crunch_len;i++) tree->data->wght[i] = ori_wght[i];
 
   Free(mean);
   Free(ori_wght);
@@ -2108,16 +2108,16 @@ phydbl *Hessian(t_tree *tree)
   ori_lnL = tree->c_lnL;
 
 
-  For(i,dim) ori_bl[i] = tree->a_edges[i]->l->v;
+  for(i=0;i<dim;i++) ori_bl[i] = tree->a_edges[i]->l->v;
 
   if(tree->mod->log_l == NO)
     l_inf = MAX(tree->mod->l_min,1./(phydbl)tree->data->init_len);
   else
-    l_inf = MAX(tree->mod->l_min,-LOG((phydbl)tree->data->init_len));
+    l_inf = MAX(tree->mod->l_min,-log((phydbl)tree->data->init_len));
 
 
   n_ok_edges = 0;
-  For(i,dim) 
+  for(i=0;i<dim;i++) 
     {
       if(tree->a_edges[i]->l->v*(1.-eps) > l_inf)
 	{
@@ -2135,7 +2135,7 @@ phydbl *Hessian(t_tree *tree)
 
 
   /* Fine tune the increments */
-  For(i,dim)
+  for(i=0;i<dim;i++)
     {
       do
 	{
@@ -2154,7 +2154,7 @@ phydbl *Hessian(t_tree *tree)
   zero_zero = tree->c_lnL;
 
   /* plus zero */  
-  For(i,dim) 
+  for(i=0;i<dim;i++) 
     {
       if(is_ok[i])
 	{
@@ -2167,7 +2167,7 @@ phydbl *Hessian(t_tree *tree)
 
 
   /* minus zero */  
-  For(i,dim) 
+  for(i=0;i<dim;i++) 
     {
       if(is_ok[i])
 	{
@@ -2179,21 +2179,21 @@ phydbl *Hessian(t_tree *tree)
     }
 
 
-  For(i,dim) Update_PMat_At_Given_Edge(tree->a_edges[i],tree);
+  for(i=0;i<dim;i++) Update_PMat_At_Given_Edge(tree->a_edges[i],tree);
 
   /* plus plus  */  
-  For(i,dim)
+  for(i=0;i<dim;i++)
     {
       if(is_ok[i])
 	{
 	  tree->a_edges[i]->l->v += inc[i];
 	  Update_PMat_At_Given_Edge(tree->a_edges[i],tree);
 
-	  For(j,3)
+	  for(j=0;j<3;j++)
 	    if((!tree->a_edges[i]->left->tax) && (tree->a_edges[i]->left->v[j] != tree->a_edges[i]->rght))
 	      Recurr_Hessian(tree->a_edges[i]->left,tree->a_edges[i]->left->v[j],1,inc,plus_plus+i*dim,is_ok,tree);
 	  
-	  For(j,3)
+	  for(j=0;j<3;j++)
 	    if((!tree->a_edges[i]->rght->tax) && (tree->a_edges[i]->rght->v[j] != tree->a_edges[i]->left))
 	      Recurr_Hessian(tree->a_edges[i]->rght,tree->a_edges[i]->rght->v[j],1,inc,plus_plus+i*dim,is_ok,tree);
 		      
@@ -2204,18 +2204,18 @@ phydbl *Hessian(t_tree *tree)
 
 
   /* plus minus */  
-  For(i,dim)
+  for(i=0;i<dim;i++)
     {
       if(is_ok[i])
 	{
 	  tree->a_edges[i]->l->v += inc[i];
 	  Update_PMat_At_Given_Edge(tree->a_edges[i],tree);
 	  
-	  For(j,3)
+	  for(j=0;j<3;j++)
 	    if((!tree->a_edges[i]->left->tax) && (tree->a_edges[i]->left->v[j] != tree->a_edges[i]->rght))
 	      Recurr_Hessian(tree->a_edges[i]->left,tree->a_edges[i]->left->v[j],-1,inc,plus_minus+i*dim,is_ok,tree);
 	  
-	  For(j,3)
+	  for(j=0;j<3;j++)
 	    if((!tree->a_edges[i]->rght->tax) && (tree->a_edges[i]->rght->v[j] != tree->a_edges[i]->left))
 	      Recurr_Hessian(tree->a_edges[i]->rght,tree->a_edges[i]->rght->v[j],-1,inc,plus_minus+i*dim,is_ok,tree);
 	  
@@ -2226,7 +2226,7 @@ phydbl *Hessian(t_tree *tree)
 
 
   /* minus minus */  
-  For(i,dim)
+  for(i=0;i<dim;i++)
     {
       if(is_ok[i])
 	{
@@ -2234,11 +2234,11 @@ phydbl *Hessian(t_tree *tree)
 	  
 	  Update_PMat_At_Given_Edge(tree->a_edges[i],tree);
 	  
-	  For(j,3)
+	  for(j=0;j<3;j++)
 	    if((!tree->a_edges[i]->left->tax) && (tree->a_edges[i]->left->v[j] != tree->a_edges[i]->rght))
 	      Recurr_Hessian(tree->a_edges[i]->left,tree->a_edges[i]->left->v[j],-1,inc,minus_minus+i*dim,is_ok,tree);
 	  
-	  For(j,3)
+	  for(j=0;j<3;j++)
 	    if((!tree->a_edges[i]->rght->tax) && (tree->a_edges[i]->rght->v[j] != tree->a_edges[i]->left))
 	      Recurr_Hessian(tree->a_edges[i]->rght,tree->a_edges[i]->rght->v[j],-1,inc,minus_minus+i*dim,is_ok,tree);
 	  
@@ -2249,7 +2249,7 @@ phydbl *Hessian(t_tree *tree)
 
 
   
-  For(i,dim)
+  for(i=0;i<dim;i++)
     {
       if(is_ok[i])
 	{
@@ -2268,9 +2268,9 @@ phydbl *Hessian(t_tree *tree)
 	}
     }
         
-  For(i,n_ok_edges)
+  for(i=0;i<n_ok_edges;i++)
     {
-      For(j,n_ok_edges)
+      for(j=0;j<n_ok_edges;j++)
 	{
 	  buff[i*n_ok_edges+j] = -1.0*hessian[ok_edges[i]*dim+ok_edges[j]];
 	}
@@ -2283,9 +2283,9 @@ phydbl *Hessian(t_tree *tree)
       Exit("\n");      
     }
 
-  For(i,n_ok_edges)
+  for(i=0;i<n_ok_edges;i++)
     {
-      For(j,n_ok_edges)
+      for(j=0;j<n_ok_edges;j++)
 	{
 	  hessian[ok_edges[i]*dim+ok_edges[j]] = buff[i*n_ok_edges+j];
 	}
@@ -2293,7 +2293,7 @@ phydbl *Hessian(t_tree *tree)
 
 /*   eps = 1./(phydbl)tree->data->init_len; */
   /* Approximate variance for very short branches */
-  For(i,dim)
+  for(i=0;i<dim;i++)
     if(inc[i] < 0.0 || hessian[i*dim+i] < MIN_VAR_BL)
       {	
 	eps = 0.2 * tree->a_edges[i]->l->v;
@@ -2319,7 +2319,7 @@ phydbl *Hessian(t_tree *tree)
 
   /* Fit a straight line to the log-likelihood (i.e., an exponential to the likelihood) */
   /* It is only a straight line when considering branch length (rather than log(branch lengths)) */
-  For(i,dim)
+  for(i=0;i<dim;i++)
     if((tree->a_edges[i]->l->v / tree->mod->l_min < 1.1) &&
        (tree->a_edges[i]->l->v / tree->mod->l_min > 0.9))
       {
@@ -2328,14 +2328,14 @@ phydbl *Hessian(t_tree *tree)
 	
 	x=plus_plus;
 	y=minus_minus;
-	l=(tree->mod->log_l == YES)?(EXP(tree->a_edges[i]->l->v)):(tree->a_edges[i]->l->v); /* Get actual branch length */
+	l=(tree->mod->log_l == YES)?(exp(tree->a_edges[i]->l->v)):(tree->a_edges[i]->l->v); /* Get actual branch length */
 	
-	For(j,dim)
+	for(j=0;j<dim;j++)
 	  {
 	    x[j] = l + (100.*l-l)*((phydbl)j/dim);
-	    tree->a_edges[i]->l->v = (tree->mod->log_l)?(LOG(x[j])):(x[j]); /* Transform to log if necessary */
+	    tree->a_edges[i]->l->v = (tree->mod->log_l)?(log(x[j])):(x[j]); /* Transform to log if necessary */
 	    y[j] = Lk(tree->a_edges[i],tree);
-	    tree->a_edges[i]->l->v = (tree->mod->log_l)?(LOG(l)):(l); /* Go back to initial edge length */
+	    tree->a_edges[i]->l->v = (tree->mod->log_l)?(log(l)):(l); /* Go back to initial edge length */
 	  }
 	
 	cov = Covariance(x,y,dim);
@@ -2350,7 +2350,7 @@ phydbl *Hessian(t_tree *tree)
   /*     } */
 
 
-  For(i,dim)
+  for(i=0;i<dim;i++)
     if(hessian[i*dim+i] < 0.0)
       {
 	PhyML_Printf("\n. l=%G var=%G",tree->a_edges[i]->l->v,hessian[i*dim+i]);
@@ -2359,7 +2359,7 @@ phydbl *Hessian(t_tree *tree)
 	hessian[i*dim+i] = MIN_VAR_BL;
       }
 
-  For(i,dim)
+  for(i=0;i<dim;i++)
     {
       if(hessian[i*dim+i] < MIN_VAR_BL)
 	{
@@ -2379,9 +2379,9 @@ phydbl *Hessian(t_tree *tree)
 
   For(i,dim*dim) hessian[i] = -1.0*hessian[i];
 
-  For(i,dim)
+  for(i=0;i<dim;i++)
     {
-      For(j,dim)
+      for(j=0;j<dim;j++)
 	{
 	  if(FABS(hessian[i*dim+j]-hessian[j*dim+i]) > 1.E-3)
 	    {
@@ -2396,10 +2396,10 @@ phydbl *Hessian(t_tree *tree)
   
 /*   printf("\n"); */
 /*   printf("HESSIAN\n"); */
-/*   For(i,dim) */
+/*   for(i=0;i<dim;i++) */
 /*     { */
 /*       PhyML_Printf("[%f] ",tree->a_edges[i]->l->v); */
-/*       For(j,dim) */
+/*       for(j=0;j<dim;j++) */
 /* 	{ */
 /* 	  PhyML_Printf("%12lf ",hessian[i*dim+j]); */
 /* 	} */
@@ -2410,10 +2410,10 @@ phydbl *Hessian(t_tree *tree)
 
   /* PhyML_Printf("\n"); */
 
-  /* For(i,dim) */
+  /* for(i=0;i<dim;i++) */
   /*   { */
   /*     PhyML_Printf("[%f] ",tree->a_edges[i]->l->v); */
-  /*     For(j,dim) */
+  /*     for(j=0;j<dim;j++) */
   /* 	{ */
   /* 	  PhyML_Printf("%12G ",-hessian[i*dim+j]); */
   /* 	} */
@@ -2475,14 +2475,14 @@ phydbl *Gradient(t_tree *tree)
   Set_Both_Sides(YES,tree);
   Lk(NULL,tree);
 
-  For(i,dim) ori_bl[i] = tree->a_edges[i]->l->v;
+  for(i=0;i<dim;i++) ori_bl[i] = tree->a_edges[i]->l->v;
 
   if(tree->mod->log_l == NO)
     l_inf = MAX(tree->mod->l_min,1./(phydbl)tree->data->init_len);
   else
-    l_inf = MAX(tree->mod->l_min,-LOG((phydbl)tree->data->init_len));
+    l_inf = MAX(tree->mod->l_min,-log((phydbl)tree->data->init_len));
 
-  For(i,dim) 
+  for(i=0;i<dim;i++) 
     {
       if(tree->a_edges[i]->l->v*(1.-eps) > l_inf)
 	{
@@ -2497,7 +2497,7 @@ phydbl *Gradient(t_tree *tree)
     }
 
   /* plus */  
-  For(i,dim) 
+  for(i=0;i<dim;i++) 
     {
       if(is_ok[i] == YES)
 	{
@@ -2510,7 +2510,7 @@ phydbl *Gradient(t_tree *tree)
 
 
   /* minus */  
-  For(i,dim)
+  for(i=0;i<dim;i++)
     {
       if(is_ok[i] == YES)
 	{
@@ -2522,7 +2522,7 @@ phydbl *Gradient(t_tree *tree)
     }
 
 
-  For(i,dim)
+  for(i=0;i<dim;i++)
     {
       if(is_ok[i] == YES)
 	{
@@ -2531,7 +2531,7 @@ phydbl *Gradient(t_tree *tree)
     }
 
 
-  For(i,dim)
+  for(i=0;i<dim;i++)
     {
       if(is_ok[i] == NO)
 	{
@@ -2560,17 +2560,17 @@ phydbl *Gradient(t_tree *tree)
 
 /*   printf("\n"); */
 /*   printf("GRADIENT\n"); */
-/*   For(i,dim) */
+/*   for(i=0;i<dim;i++) */
 /*     { */
 /*       PhyML_Printf("[%f] ",tree->a_edges[i]->l->v); */
-/*       For(j,dim) */
+/*       for(j=0;j<dim;j++) */
 /* 	{ */
 /* 	  printf("%12lf ",gradient[i]*gradient[j]); */
 /* 	} */
 /*       printf("\n"); */
 /*     } */
 /*   printf("\n"); */
-/*   For(i,dim) */
+/*   for(i=0;i<dim;i++) */
 /*     { */
 /*       PhyML_Printf("[%f] [%f]\n",tree->a_edges[i]->l->v,gradient[i]); */
 /*     } */
@@ -2621,7 +2621,7 @@ phydbl *Hessian_Seo(t_tree *tree)
 
   lnL1 = lnL2 = UNLIKELY;
   
-  For(i,dim) ori_bl[i] = tree->a_edges[i]->l->v;
+  for(i=0;i<dim;i++) ori_bl[i] = tree->a_edges[i]->l->v;
   
   Set_Both_Sides(YES,tree);
   Lk(NULL,tree);
@@ -2631,9 +2631,9 @@ phydbl *Hessian_Seo(t_tree *tree)
   if(tree->mod->log_l == NO)
     l_inf = MAX(tree->mod->l_min,1./(phydbl)tree->data->init_len);
   else
-    l_inf = MAX(tree->mod->l_min,-LOG((phydbl)tree->data->init_len));
+    l_inf = MAX(tree->mod->l_min,-log((phydbl)tree->data->init_len));
 
-  For(i,dim) 
+  for(i=0;i<dim;i++) 
     {
       if(tree->a_edges[i]->l->v*(1.-eps) > l_inf)
 	{
@@ -2652,7 +2652,7 @@ phydbl *Hessian_Seo(t_tree *tree)
     }
 
   /* Fine tune the increments */
-  For(i,dim)
+  for(i=0;i<dim;i++)
     {
       do
 	{
@@ -2664,7 +2664,7 @@ phydbl *Hessian_Seo(t_tree *tree)
       inc_plus[i] /= 1.1;
     }
 
-  For(i,dim)
+  for(i=0;i<dim;i++)
     {
       do
 	{
@@ -2677,51 +2677,51 @@ phydbl *Hessian_Seo(t_tree *tree)
       inc_minus[i] /= 1.1;
     }
 
-  For(i,dim) 
+  for(i=0;i<dim;i++) 
     {
       inc[i] = MIN(inc_plus[i],inc_minus[i]);
     }
 
   /* plus */  
-  For(i,dim) 
+  for(i=0;i<dim;i++) 
     {
       if(is_ok[i] == YES)
 	{
 	  tree->a_edges[i]->l->v += inc[i];
 	  Lk(tree->a_edges[i],tree);
-	  For(j,tree->n_pattern) plus[i*tree->n_pattern+j] = LOG(tree->cur_site_lk[j]);
+	  for(j=0;j<tree->n_pattern;j++) plus[i*tree->n_pattern+j] = log(tree->cur_site_lk[j]);
 	  tree->a_edges[i]->l->v = ori_bl[i];
 	}
     }
 
 
   /* minus */
-  For(i,dim)
+  for(i=0;i<dim;i++)
     {
       if(is_ok[i] == YES)
 	{
 	  tree->a_edges[i]->l->v -= inc[i];
 	  Lk(tree->a_edges[i],tree);
-	  For(j,tree->n_pattern) minus[i*tree->n_pattern+j] = LOG(tree->cur_site_lk[j]);
+	  for(j=0;j<tree->n_pattern;j++) minus[i*tree->n_pattern+j] = log(tree->cur_site_lk[j]);
 	  tree->a_edges[i]->l->v = ori_bl[i];
 	}
     }
 
 
-  For(i,dim)
+  for(i=0;i<dim;i++)
     {
       if(is_ok[i] == NO)
 	{
 	  Lk(tree->a_edges[i],tree);	
-	  For(j,tree->n_pattern) zero[i*tree->n_pattern+j] = LOG(tree->cur_site_lk[j]);
+	  for(j=0;j<tree->n_pattern;j++) zero[i*tree->n_pattern+j] = log(tree->cur_site_lk[j]);
 	  
 	  tree->a_edges[i]->l->v += inc[i];
 	  lnL1 = Lk(tree->a_edges[i],tree);
-	  For(j,tree->n_pattern) plus[i*tree->n_pattern+j] = LOG(tree->cur_site_lk[j]);
+	  for(j=0;j<tree->n_pattern;j++) plus[i*tree->n_pattern+j] = log(tree->cur_site_lk[j]);
 	  
 	  tree->a_edges[i]->l->v += inc[i];
 	  lnL2 = Lk(tree->a_edges[i],tree);
-	  For(j,tree->n_pattern) plusplus[i*tree->n_pattern+j] = LOG(tree->cur_site_lk[j]);
+	  for(j=0;j<tree->n_pattern;j++) plusplus[i*tree->n_pattern+j] = log(tree->cur_site_lk[j]);
 	  
 	  tree->a_edges[i]->l->v = ori_bl[i];	
 
@@ -2730,9 +2730,9 @@ phydbl *Hessian_Seo(t_tree *tree)
 
   For(i,dim*dim) hessian[i] = 0.0;
 
-  For(k,tree->n_pattern)
+  for(k=0;k<tree->n_pattern;k++)
     {
-      For(i,dim) 
+      for(i=0;i<dim;i++) 
 	{
 	  if(is_ok[i] == YES)
 	    gradient[i] = (plus[i*tree->n_pattern+k] - minus[i*tree->n_pattern+k])/(inc[i] + inc[i]); 
@@ -2747,7 +2747,7 @@ phydbl *Hessian_Seo(t_tree *tree)
 	  /* 	   gradient[i]); */
 
 	}
-      For(i,dim) For(j,dim) site_hessian[i*dim+j] = gradient[i] * gradient[j];
+      for(i=0;i<dim;i++) for(j=0;j<dim;j++) site_hessian[i*dim+j] = gradient[i] * gradient[j];
       For(i,dim*dim) hessian[i] -= site_hessian[i] * tree->data->wght[k]; 
     }
 
@@ -2760,10 +2760,10 @@ phydbl *Hessian_Seo(t_tree *tree)
   n = tree->mod->ns;
   /* Delta method for variance. Assumes Jukes and Cantor with p=1/n */
   small_var = (1./(l*l))*(1.-1./l)*(n-1.)*(n-1.)/(n-1.-n/l);
-  For(i,dim)
+  for(i=0;i<dim;i++)
     if(is_ok[i] == NO)
       {
-	For(j,dim)
+	for(j=0;j<dim;j++)
 	  {
 	    hessian[i*dim+j] = 0.;
 	    hessian[j*dim+i] = 0.;
@@ -2772,15 +2772,15 @@ phydbl *Hessian_Seo(t_tree *tree)
 
 	if(tree->mod->log_l == YES) 
 	  {
-	    hessian[i*dim+i] = small_var * POW(EXP(tree->a_edges[i]->l->v),-2); 
+	    hessian[i*dim+i] = small_var * POW(exp(tree->a_edges[i]->l->v),-2); 
 	    hessian[i*dim+i] = -1./hessian[i*dim+i];
 	  }
       }
 
-  For(i,dim)
+  for(i=0;i<dim;i++)
     if(is_ok[i] == YES && hessian[i*dim+i] < -1./small_var)
       {
-  	For(j,dim)
+  	for(j=0;j<dim;j++)
   	  {
   	    hessian[i*dim+j] = 0.;
   	    hessian[j*dim+i] = 0.;
@@ -2789,15 +2789,15 @@ phydbl *Hessian_Seo(t_tree *tree)
 
   	if(tree->mod->log_l == YES)
   	  {
-  	    hessian[i*dim+i] = small_var * POW(EXP(tree->a_edges[i]->l->v),-2);
+  	    hessian[i*dim+i] = small_var * POW(exp(tree->a_edges[i]->l->v),-2);
   	    hessian[i*dim+i] = -1./hessian[i*dim+i];
   	  }
       }
 
 
-  For(i,dim)
+  for(i=0;i<dim;i++)
     {
-      For(j,dim)
+      for(j=0;j<dim;j++)
 	{
 	  if(FABS(hessian[i*dim+j]-hessian[j*dim+i]) > 1.E-3)
 	    {
@@ -2812,10 +2812,10 @@ phydbl *Hessian_Seo(t_tree *tree)
 
   /* printf("\n"); */
   /* printf("HESSIAN SEO\n"); */
-  /* For(i,dim) */
+  /* for(i=0;i<dim;i++) */
   /*   { */
   /*     PhyML_Printf("[%f] ",tree->a_edges[i]->l->v); */
-  /*     For(j,dim) */
+  /*     for(j=0;j<dim;j++) */
   /* 	{ */
   /* 	  PhyML_Printf("%12lf ",hessian[i*dim+j]); */
   /* 	} */
@@ -2847,10 +2847,10 @@ void Recurr_Hessian(t_node *a, t_node *d, int plus_minus, phydbl *inc, phydbl *r
   int i;
   phydbl ori_l;
 
-  For(i,3)
+  for(i=0;i<3;i++)
     if(a->v[i] == d)
       {
-	Update_P_Lk(tree,a->b[i],a);
+	Update_Partial_Lk(tree,a->b[i],a);
 
 	ori_l = a->b[i]->l->v;
 	if(is_ok[a->b[i]->num])
@@ -2866,7 +2866,7 @@ void Recurr_Hessian(t_node *a, t_node *d, int plus_minus, phydbl *inc, phydbl *r
 
   if(d->tax) return;
   else 
-    For(i,3) 
+    for(i=0;i<3;i++) 
       if(d->v[i] != a) 
 	Recurr_Hessian(d,d->v[i],plus_minus,inc,res,is_ok,tree);
 }
@@ -2875,7 +2875,7 @@ void Recurr_Hessian(t_node *a, t_node *d, int plus_minus, phydbl *inc, phydbl *r
 //////////////////////////////////////////////////////////////
 
 
-/* Work out the Hessian for the likelihood function. Only LOGARITHM of branch lengths are considered as variable.
+/* Work out the Hessian for the likelihood function. Only logARITHM of branch lengths are considered as variable.
    This function is very much inspired from Jeff Thorne's 'hessian' function in his program 'estbranches'. */
 phydbl *Hessian_Log(t_tree *tree)
 {
@@ -2908,10 +2908,10 @@ phydbl *Hessian_Log(t_tree *tree)
   Set_Both_Sides(YES,tree);
   Lk(NULL,tree);
 
-  For(i,dim) ori_bl[i] = tree->a_edges[i]->l->v;
+  for(i=0;i<dim;i++) ori_bl[i] = tree->a_edges[i]->l->v;
 
   n_ok_edges = 0;
-  For(i,dim) 
+  for(i=0;i<dim;i++) 
     {
       if(tree->a_edges[i]->l->v > 3.0/(phydbl)tree->data->init_len)
 	{
@@ -2925,10 +2925,10 @@ phydbl *Hessian_Log(t_tree *tree)
 
   /* zero zero */  
   lk = Log_Det(is_ok,tree);
-  For(i,dim) if(is_ok[i]) zero_zero[i] = tree->c_lnL+lk;
+  for(i=0;i<dim;i++) if(is_ok[i]) zero_zero[i] = tree->c_lnL+lk;
 
   /* plus zero */  
-  For(i,dim) 
+  for(i=0;i<dim;i++) 
     {
       if(is_ok[i])
 	{
@@ -2941,7 +2941,7 @@ phydbl *Hessian_Log(t_tree *tree)
 
 
   /* minus zero */
-  For(i,dim) 
+  for(i=0;i<dim;i++) 
     {
       if(is_ok[i])
 	{
@@ -2952,25 +2952,25 @@ phydbl *Hessian_Log(t_tree *tree)
 	}
     }
 
-  For(i,dim) Update_PMat_At_Given_Edge(tree->a_edges[i],tree);
+  for(i=0;i<dim;i++) Update_PMat_At_Given_Edge(tree->a_edges[i],tree);
 
   /* plus plus  */  
-  For(i,dim)
+  for(i=0;i<dim;i++)
     {
       if(is_ok[i])
 	{
 	  tree->a_edges[i]->l->v += inc[i];
 	  Update_PMat_At_Given_Edge(tree->a_edges[i],tree);
 
-	  For(j,3)
+	  for(j=0;j<3;j++)
 	    if((!tree->a_edges[i]->left->tax) && (tree->a_edges[i]->left->v[j] != tree->a_edges[i]->rght))
 	      Recurr_Hessian_Log(tree->a_edges[i]->left,tree->a_edges[i]->left->v[j],1,inc,plus_plus+i*dim,is_ok,tree);
 	  
-	  For(j,3)
+	  for(j=0;j<3;j++)
 	    if((!tree->a_edges[i]->rght->tax) && (tree->a_edges[i]->rght->v[j] != tree->a_edges[i]->left))
 	      Recurr_Hessian_Log(tree->a_edges[i]->rght,tree->a_edges[i]->rght->v[j],1,inc,plus_plus+i*dim,is_ok,tree);
 
-/* 	  For(j,dim)  */
+/* 	  for(j=0;j<dim;j++)  */
 /* 	    if(j != i) */
 /* 	      { */
 /* 		if(inc[j] > 0.0) */
@@ -2988,22 +2988,22 @@ phydbl *Hessian_Log(t_tree *tree)
     }
 
   /* plus minus */  
-  For(i,dim)
+  for(i=0;i<dim;i++)
     {
       if(is_ok[i])
 	{
 	  tree->a_edges[i]->l->v += inc[i];
 	  Update_PMat_At_Given_Edge(tree->a_edges[i],tree);
 	  
-	  For(j,3)
+	  for(j=0;j<3;j++)
 	    if((!tree->a_edges[i]->left->tax) && (tree->a_edges[i]->left->v[j] != tree->a_edges[i]->rght))
 	      Recurr_Hessian_Log(tree->a_edges[i]->left,tree->a_edges[i]->left->v[j],-1,inc,plus_minus+i*dim,is_ok,tree);
 	  
-	  For(j,3)
+	  for(j=0;j<3;j++)
 	    if((!tree->a_edges[i]->rght->tax) && (tree->a_edges[i]->rght->v[j] != tree->a_edges[i]->left))
 	      Recurr_Hessian_Log(tree->a_edges[i]->rght,tree->a_edges[i]->rght->v[j],-1,inc,plus_minus+i*dim,is_ok,tree);
 	  
-/* 	  For(j,dim)  */
+/* 	  for(j=0;j<dim;j++)  */
 /* 	    if(j != i) */
 /* 	      { */
 /* 		if(inc[j] > 0.0) */
@@ -3022,7 +3022,7 @@ phydbl *Hessian_Log(t_tree *tree)
 
 
   /* minus minus */  
-  For(i,dim)
+  for(i=0;i<dim;i++)
     {
       if(is_ok[i])
 	{
@@ -3030,15 +3030,15 @@ phydbl *Hessian_Log(t_tree *tree)
 	  
 	  Update_PMat_At_Given_Edge(tree->a_edges[i],tree);
 	  
-	  For(j,3)
+	  for(j=0;j<3;j++)
 	    if((!tree->a_edges[i]->left->tax) && (tree->a_edges[i]->left->v[j] != tree->a_edges[i]->rght))
 	      Recurr_Hessian_Log(tree->a_edges[i]->left,tree->a_edges[i]->left->v[j],-1,inc,minus_minus+i*dim,is_ok,tree);
 	  
-	  For(j,3)
+	  for(j=0;j<3;j++)
 	    if((!tree->a_edges[i]->rght->tax) && (tree->a_edges[i]->rght->v[j] != tree->a_edges[i]->left))
 	      Recurr_Hessian_Log(tree->a_edges[i]->rght,tree->a_edges[i]->rght->v[j],-1,inc,minus_minus+i*dim,is_ok,tree);
 	  
-/* 	  For(j,dim)  */
+/* 	  for(j=0;j<dim;j++)  */
 /* 	    if(j != i) */
 /* 	      { */
 /* 		if(inc[j] > 0.0) */
@@ -3055,12 +3055,12 @@ phydbl *Hessian_Log(t_tree *tree)
 	}
     }
 
-/*   For(i,dim) if(is_ok[i]) inc[i] = POW(tree->a_edges[i]->l->v+inc[i],2)-POW(tree->a_edges[i]->l->v,2); */
-  For(i,dim) if(is_ok[i]) inc[i] = LOG(tree->a_edges[i]->l->v+inc[i])-LOG(tree->a_edges[i]->l->v);
-/*   For(i,dim) inc[i] = 2.*inc[i]; */
-/*   For(i,dim) if(is_ok[i]) inc[i] = SQRT(tree->a_edges[i]->l->v+inc[i])-SQRT(tree->a_edges[i]->l->v); */
+/*   for(i=0;i<dim;i++) if(is_ok[i]) inc[i] = POW(tree->a_edges[i]->l->v+inc[i],2)-POW(tree->a_edges[i]->l->v,2); */
+  for(i=0;i<dim;i++) if(is_ok[i]) inc[i] = log(tree->a_edges[i]->l->v+inc[i])-log(tree->a_edges[i]->l->v);
+/*   for(i=0;i<dim;i++) inc[i] = 2.*inc[i]; */
+/*   for(i=0;i<dim;i++) if(is_ok[i]) inc[i] = SQRT(tree->a_edges[i]->l->v+inc[i])-SQRT(tree->a_edges[i]->l->v); */
   
-  For(i,dim)
+  for(i=0;i<dim;i++)
     {
       if(is_ok[i])
 	{
@@ -3080,9 +3080,9 @@ phydbl *Hessian_Log(t_tree *tree)
     }
         
 
-  For(i,n_ok_edges)
+  for(i=0;i<n_ok_edges;i++)
     {
-      For(j,n_ok_edges)
+      for(j=0;j<n_ok_edges;j++)
 	{
 	  buff[i*n_ok_edges+j] = -hessian[ok_edges[i]*dim+ok_edges[j]];
 	}
@@ -3094,16 +3094,16 @@ phydbl *Hessian_Log(t_tree *tree)
       Exit("\n");      
     }
 
-  For(i,n_ok_edges)
+  for(i=0;i<n_ok_edges;i++)
     {
-      For(j,n_ok_edges)
+      for(j=0;j<n_ok_edges;j++)
 	{
 	  hessian[ok_edges[i]*dim+ok_edges[j]] = buff[i*n_ok_edges+j];
 	}
     }
 
   /* Approximate variance for very short branches */
-  For(i,dim)
+  for(i=0;i<dim;i++)
     if(!is_ok[i])
       {
 	hessian[i*dim+i] = 1./POW(tree->data->init_len,2);
@@ -3117,7 +3117,7 @@ phydbl *Hessian_Log(t_tree *tree)
 
   For(i,dim*dim) hessian[i] = -1.0*hessian[i];
 
-/*   For(i,dim) */
+/*   for(i=0;i<dim;i++) */
 /*     { */
 /*       PhyML_Printf("[%f] ",tree->a_edges[i]->l->v); */
 /*       For(j,i+1) */
@@ -3131,7 +3131,7 @@ phydbl *Hessian_Log(t_tree *tree)
 
 /*   PhyML_Printf("\n"); */
 
-  For(i,dim)
+  for(i=0;i<dim;i++)
     {
       PhyML_Printf("[%f] ",tree->a_edges[i]->l->v);
       For(j,i+1)
@@ -3168,10 +3168,10 @@ void Recurr_Hessian_Log(t_node *a, t_node *d, int plus_minus, phydbl *inc, phydb
   int i;
   phydbl ori_l;
 
-  For(i,3)
+  for(i=0;i<3;i++)
     if(a->v[i] == d)
       {
-	Update_P_Lk(tree,a->b[i],a);
+	Update_Partial_Lk(tree,a->b[i],a);
 
 	ori_l = a->b[i]->l->v;
 	if(is_ok[a->b[i]->num])
@@ -3188,7 +3188,7 @@ void Recurr_Hessian_Log(t_node *a, t_node *d, int plus_minus, phydbl *inc, phydb
 
   if(d->tax) return;
   else 
-    For(i,3) 
+    for(i=0;i<3;i++) 
       if(d->v[i] != a) 
 	Recurr_Hessian_Log(d,d->v[i],plus_minus,inc,res,is_ok,tree);
 }
@@ -3203,9 +3203,9 @@ phydbl Log_Det(int *is_ok, t_tree *tree)
   phydbl ldet;
 
   ldet = 0.0;
-/*   For(i,2*tree->n_otu-3) if(is_ok[i]) ldet += LOG(2.*SQRT(tree->a_edges[i]->l->v)); */
-  For(i,2*tree->n_otu-3) if(is_ok[i]) ldet += LOG(tree->a_edges[i]->l->v);
-/*   For(i,2*tree->n_otu-3) if(is_ok[i]) ldet -= LOG(2*tree->a_edges[i]->l->v); */
+/*   For(i,2*tree->n_otu-3) if(is_ok[i]) ldet += log(2.*SQRT(tree->a_edges[i]->l->v)); */
+  For(i,2*tree->n_otu-3) if(is_ok[i]) ldet += log(tree->a_edges[i]->l->v);
+/*   For(i,2*tree->n_otu-3) if(is_ok[i]) ldet -= log(2*tree->a_edges[i]->l->v); */
   
   return ldet;
 
@@ -3214,7 +3214,6 @@ phydbl Log_Det(int *is_ok, t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 phydbl Normal_Trunc_Mean(phydbl mu, phydbl sd, phydbl min, phydbl max)
 {
   phydbl mean;
@@ -3251,7 +3250,7 @@ phydbl Constraint_Normal_Trunc_Mean(phydbl wanted_mu, phydbl sd, phydbl min, phy
 
   rtb = f < 0.0 ? (dx=x2-x1,x1) : (dx=x1-x2,x2);
 
-  For(j,100) 
+  for(j=0;j<100;j++) 
     {
       xmid=rtb+(dx *= 0.5);
       fmid=Normal_Trunc_Mean(xmid,sd,min,max)-wanted_mu;
@@ -3318,16 +3317,16 @@ int Matinv(phydbl *x, int n, int m, int verbose)
 	{
 	  if (j == i) continue;
 	  t1 = t*x[j*m+i];
-	  For(k,m)  x[j*m+k] -= t1*x[i*m+k];
+	  for(k=0;k<m;k++)  x[j*m+k] -= t1*x[i*m+k];
 	  x[j*m+i] = -t1;
 	}
-      For(j,m)   x[i*m+j] *= t;
+      for(j=0;j<m;j++)   x[i*m+j] *= t;
       x[i*m+i] = t;
    }                            /* i  */
    for (i=n-1; i>=0; i--)
      {
        if (irow[i] == i) continue;
-       For(j,n)
+       for(j=0;j<n;j++)
 	 {
 	   t = x[j*m+i];
 	   x[j*m+i] = x[j*m + irow[i]];
@@ -3433,9 +3432,9 @@ phydbl *Matrix_Mult(phydbl *A, phydbl *B, int nra, int nca, int nrb, int ncb)
       Exit("\n");      
     }
   
-  For(i,nra)
-    For(j,ncb)
-       For(k,nca)
+  for(i=0;i<nra;i++)
+    for(j=0;j<ncb;j++)
+       for(k=0;k<nca;k++)
          C[i*ncb+j] += A[i*nca+k] * B[k*ncb+j];
   
   return C;
@@ -3454,7 +3453,7 @@ phydbl *Matrix_Transpose(phydbl *A, int dim)
 
   For(i,dim*dim) tA[i]=A[i];
 
-  For(i,dim) for(j=i+1;j<dim;j++) 
+  for(i=0;i<dim;i++) for(j=i+1;j<dim;j++) 
     {
       buff        = tA[i*dim+j];
       tA[i*dim+j] = tA[j*dim+i];
@@ -3476,12 +3475,12 @@ phydbl Matrix_Det(phydbl *A, int size, int _log)
 
   triA = Cholesky_Decomp(A,size);
   det = 0.0;
-  For(i,size) det += LOG(triA[i*size+i]);
+  for(i=0;i<size;i++) det += log(triA[i*size+i]);
   Free(triA);
  
   if(_log == NO)
     {
-      det = EXP(det);
+      det = exp(det);
       return det*det;
     }
   else
@@ -3519,23 +3518,23 @@ void Normal_Conditional(phydbl *mu, phydbl *cov, phydbl *a, int n, short int *is
   buff_mat        = (phydbl *)mCalloc(n2*n2,sizeof(phydbl));
 
   nr=0;
-  For(i,n) { if(!is_1[i]) { ctrd_a[nr] = a[i]-mu[i]; nr++; } }
+  for(i=0;i<n;i++) { if(!is_1[i]) { ctrd_a[nr] = a[i]-mu[i]; nr++; } }
 
   nr=0;
-  For(i,n) { if( is_1[i]) { mu1[nr] = mu[i]; nr++; } }
+  for(i=0;i<n;i++) { if( is_1[i]) { mu1[nr] = mu[i]; nr++; } }
 
   nr=0;
-  For(i,n) { if(!is_1[i]) { mu2[nr] = mu[i]; nr++; } }
+  for(i=0;i<n;i++) { if(!is_1[i]) { mu2[nr] = mu[i]; nr++; } }
 
   nr=0; nc=0;
-  For(i,n)
+  for(i=0;i<n;i++)
     {
       if(is_1[i])
 	{
 	  nc = nr;
  	  for(j=i;j<n;j++)
 /* 	  nc = 0; */
-/* 	  For(j,n) */
+/* 	  for(j=0;j<n;j++) */
 	    {
 	      if(is_1[j])
 		{
@@ -3550,14 +3549,14 @@ void Normal_Conditional(phydbl *mu, phydbl *cov, phydbl *a, int n, short int *is
 
 
   nr=0; nc=0;
-  For(i,n)
+  for(i=0;i<n;i++)
     {
       if(is_1[i])
 	{
 /* 	  nc = nr; */
 /*  	  for(j=i;j<n;j++) */
 	  nc = 0;
-	  For(j,n)
+	  for(j=0;j<n;j++)
 	    {
 	      if(!is_1[j])
 		{
@@ -3571,14 +3570,14 @@ void Normal_Conditional(phydbl *mu, phydbl *cov, phydbl *a, int n, short int *is
     }
 
   nr=0; nc=0;
-  For(i,n)
+  for(i=0;i<n;i++)
     {
       if(!is_1[i])
 	{
 /* 	  nc = nr; */
 /* 	  for(j=i;j<n;j++) */
 	  nc = 0;
-	  For(j,n)
+	  for(j=0;j<n;j++)
 	    {
 	      if(is_1[j])
 		{
@@ -3593,14 +3592,14 @@ void Normal_Conditional(phydbl *mu, phydbl *cov, phydbl *a, int n, short int *is
 
 
   nr=0; nc=0;
-  For(i,n)
+  for(i=0;i<n;i++)
     {
       if(!is_1[i])
 	{
 	  nc = nr;
 	  for(j=i;j<n;j++)
 /* 	  nc = 0; */
-/* 	  For(j,n) */
+/* 	  for(j=0;j<n;j++) */
 	    {
 	      if(!is_1[j])
 		{
@@ -3618,23 +3617,23 @@ void Normal_Conditional(phydbl *mu, phydbl *cov, phydbl *a, int n, short int *is
   sig12_invsig22 = Matrix_Mult(sig12,sig22,n1,n2,n2,n2);
 
   buff = Matrix_Mult(sig12_invsig22,ctrd_a,n1,n2,n2,1);
-  For(i,n1) cond_mu_norder[i] = mu1[i]+buff[i];
+  for(i=0;i<n1;i++) cond_mu_norder[i] = mu1[i]+buff[i];
   Free(buff);
 
   buff = Matrix_Mult(sig12_invsig22,sig21,n1,n2,n2,n1);
-  For(i,n1) For(j,n1) cond_cov_norder[i*n1+j] = sig11[i*n1+j] - buff[i*n1+j];
+  for(i=0;i<n1;i++) for(j=0;j<n1;j++) cond_cov_norder[i*n1+j] = sig11[i*n1+j] - buff[i*n1+j];
   Free(buff);
 
   nr = 0;
-  For(i,n) if(is_1[i]) { cond_mu[i] = cond_mu_norder[nr]; nr++; }
+  for(i=0;i<n;i++) if(is_1[i]) { cond_mu[i] = cond_mu_norder[nr]; nr++; }
 
   nr = nc = 0;
-  For(i,n) 
+  for(i=0;i<n;i++) 
     {
       if(is_1[i]) 
 	{ 
 	  nc = 0;
-	  For(j,n)
+	  for(j=0;j<n;j++)
 	    {
 	      if(is_1[j]) 
 		{		  
@@ -3646,7 +3645,7 @@ void Normal_Conditional(phydbl *mu, phydbl *cov, phydbl *a, int n, short int *is
 	}
     }
 
-/*   For(i,n1) */
+/*   for(i=0;i<n1;i++) */
 /*     { */
 /*       for(j=i;j<n1;j++) */
 /* 	if(FABS(cond_cov_norder[i*n1+j] - cond_cov_norder[j*n1+i]) > 1.E-3) */
@@ -3657,7 +3656,7 @@ void Normal_Conditional(phydbl *mu, phydbl *cov, phydbl *a, int n, short int *is
 /*     } */
 
 
-  For(i,n)
+  for(i=0;i<n;i++)
     {
       for(j=i+1;j<n;j++)
 	if(FABS(cond_cov[i*n+j] - cond_cov[j*n+i]) > 1.E-3)
@@ -3705,23 +3704,23 @@ void Normal_Conditional_Unsorted(phydbl *mu, phydbl *cov, phydbl *a, int n, shor
   ctrd_a          = (phydbl *)mCalloc(n2,   sizeof(phydbl)); 
 
   nr=0;
-  For(i,n) { if(!is_1[i]) { ctrd_a[nr] = a[i]-mu[i]; nr++; } }
+  for(i=0;i<n;i++) { if(!is_1[i]) { ctrd_a[nr] = a[i]-mu[i]; nr++; } }
 
   nr=0;
-  For(i,n) { if( is_1[i]) { mu1[nr] = mu[i]; nr++; } }
+  for(i=0;i<n;i++) { if( is_1[i]) { mu1[nr] = mu[i]; nr++; } }
 
   nr=0;
-  For(i,n) { if(!is_1[i]) { mu2[nr] = mu[i]; nr++; } }
+  for(i=0;i<n;i++) { if(!is_1[i]) { mu2[nr] = mu[i]; nr++; } }
 
   nr=0; nc=0;
-  For(i,n)
+  for(i=0;i<n;i++)
     {
       if(is_1[i])
 	{
 	  nc = nr;
  	  for(j=i;j<n;j++)
 /* 	  nc = 0; */
-/* 	  For(j,n) */
+/* 	  for(j=0;j<n;j++) */
 	    {
 	      if(is_1[j])
 		{
@@ -3736,14 +3735,14 @@ void Normal_Conditional_Unsorted(phydbl *mu, phydbl *cov, phydbl *a, int n, shor
 
 
   nr=0; nc=0;
-  For(i,n)
+  for(i=0;i<n;i++)
     {
       if(is_1[i])
 	{
 /* 	  nc = nr; */
 /*  	  for(j=i;j<n;j++) */
 	  nc = 0;
-	  For(j,n)
+	  for(j=0;j<n;j++)
 	    {
 	      if(!is_1[j])
 		{
@@ -3757,14 +3756,14 @@ void Normal_Conditional_Unsorted(phydbl *mu, phydbl *cov, phydbl *a, int n, shor
     }
 
   nr=0; nc=0;
-  For(i,n)
+  for(i=0;i<n;i++)
     {
       if(!is_1[i])
 	{
 /* 	  nc = nr; */
 /* 	  for(j=i;j<n;j++) */
 	  nc = 0;
-	  For(j,n)
+	  for(j=0;j<n;j++)
 	    {
 	      if(is_1[j])
 		{
@@ -3779,14 +3778,14 @@ void Normal_Conditional_Unsorted(phydbl *mu, phydbl *cov, phydbl *a, int n, shor
 
 
   nr=0; nc=0;
-  For(i,n)
+  for(i=0;i<n;i++)
     {
       if(!is_1[i])
 	{
 	  nc = nr;
 	  for(j=i;j<n;j++)
 /* 	  nc = 0; */
-/* 	  For(j,n) */
+/* 	  for(j=0;j<n;j++) */
 	    {
 	      if(!is_1[j])
 		{
@@ -3807,11 +3806,11 @@ void Normal_Conditional_Unsorted(phydbl *mu, phydbl *cov, phydbl *a, int n, shor
   sig12_invsig22 = Matrix_Mult(sig12,sig22,n1,n2,n2,n2);
 
   buff = Matrix_Mult(sig12_invsig22,ctrd_a,n1,n2,n2,1);
-  For(i,n1) cond_mu[i] = mu1[i]+buff[i];
+  for(i=0;i<n1;i++) cond_mu[i] = mu1[i]+buff[i];
   Free(buff);
 
   buff = Matrix_Mult(sig12_invsig22,sig21,n1,n2,n2,n1);
-  For(i,n1) For(j,n1) cond_cov[i*n1+j] = sig11[i*n1+j] - buff[i*n1+j];
+  for(i=0;i<n1;i++) for(j=0;j<n1;j++) cond_cov[i*n1+j] = sig11[i*n1+j] - buff[i*n1+j];
 
 
   Free(mu1);
@@ -3842,12 +3841,12 @@ void Get_Reg_Coeff(phydbl *mu, phydbl *cov, phydbl *a, int n, short int *is_1, i
   sig22 = (phydbl *)mCalloc(n2*n2,sizeof(phydbl));
 
   nr=0; nc=0;
-  For(i,n)
+  for(i=0;i<n;i++)
     {
       if(is_1[i])
 	{
 	  nc = 0;
-	  For(j,n)
+	  for(j=0;j<n;j++)
 	    {
 	      if(!is_1[j])
 		{
@@ -3861,7 +3860,7 @@ void Get_Reg_Coeff(phydbl *mu, phydbl *cov, phydbl *a, int n, short int *is_1, i
 
 
   nr=0; nc=0;
-  For(i,n)
+  for(i=0;i<n;i++)
     {
       if(!is_1[i])
 	{
@@ -3888,17 +3887,17 @@ void Get_Reg_Coeff(phydbl *mu, phydbl *cov, phydbl *a, int n, short int *is_1, i
   sig12_invsig22 = Matrix_Mult(sig12,sig22,n1,n2,n2,n2);
 
 
-  For(i,n) reg_coeff[i] = 0.0;
+  for(i=0;i<n;i++) reg_coeff[i] = 0.0;
 
 /*   nr = 0; */
-/*   For(i,n) if(!is_1[i]) { reg_coeff[i] = sig12_invsig22[nr]; nr++; } */
+/*   for(i=0;i<n;i++) if(!is_1[i]) { reg_coeff[i] = sig12_invsig22[nr]; nr++; } */
 
   nc = 0;
   nr = 0;
-  For(i,n1) 
+  for(i=0;i<n1;i++) 
     {
       nc = 0;
-      For(j,n)
+      for(j=0;j<n;j++)
 	if(!is_1[j]) 
 	  { 
 	    reg_coeff[i*n+j] = sig12_invsig22[nr*n2+nc]; 
@@ -4056,10 +4055,10 @@ void VarCov_Approx_Likelihood(t_tree *tree)
   fprintf(fp,"\n");
   fprintf(fp,"Run\t");
   fprintf(fp,"lnL\t");
-  For(i,dim) fprintf(fp,"Edge%d[%f]\t",i,tree->rates->u_ml_l[i]);
+  for(i=0;i<dim;i++) fprintf(fp,"Edge%d[%f]\t",i,tree->rates->u_ml_l[i]);
 
   
-  For(i,dim)     mean[i] = .0;
+  for(i=0;i<dim;i++)     mean[i] = .0;
   For(i,dim*dim) cov[i]  = .0;
 
   MCMC_Randomize_Branch_Lengths(tree);
@@ -4079,7 +4078,7 @@ void VarCov_Approx_Likelihood(t_tree *tree)
 
 
       max_diff_mean = 0.0;
-      For(i,dim)
+      for(i=0;i<dim;i++)
 	{
 	  cur_mean = mean[i];
 
@@ -4094,9 +4093,9 @@ void VarCov_Approx_Likelihood(t_tree *tree)
 	}
 
       max_diff_cov = 0.0;
-      For(i,dim)
+      for(i=0;i<dim;i++)
 	{
-	  For(j,dim)
+	  for(j=0;j<dim;j++)
 	    {
 	      cur_cov = cov[i*dim+j];
 
@@ -4121,16 +4120,16 @@ void VarCov_Approx_Likelihood(t_tree *tree)
 	  fprintf(fp,"\n");
 	  fprintf(fp,"%d\t",iter);
 	  fprintf(fp,"%f\t",tree->c_lnL);
- 	  For(i,dim) fprintf(fp,"%f\t",tree->a_edges[i]->l->v);
+ 	  for(i=0;i<dim;i++) fprintf(fp,"%f\t",tree->a_edges[i]->l->v);
 	  fflush(NULL);
 	}
 
     }while(iter < 5000);
 
 
-  For(i,dim)
+  for(i=0;i<dim;i++)
     {
-      For(j,dim)
+      for(j=0;j<dim;j++)
 	{
 	  cov[i*dim+j] = cov[i*dim+j] - mean[i]*mean[j];
 	  if(i == j && cov[i*dim+j] < MIN_VAR_BL) cov[i*dim+j] = MIN_VAR_BL;
@@ -4158,7 +4157,7 @@ phydbl Dorder_Unif(phydbl x, int r, int n, phydbl min, phydbl max)
     }
 
   cons = LnGamma(n+1) - LnGamma(r) - LnGamma(n-r+1);
-  cons = EXP(cons);
+  cons = exp(cons);
   cons = ROUND(cons);
 
   Fx = (x-min)/(max-min);
@@ -4181,15 +4180,15 @@ phydbl Covariance(phydbl *x, phydbl *y, int n)
   phydbl mean_x,mean_y,mean_xy;
 
   mean_x = .0;
-  For(i,n) mean_x += x[i];
+  for(i=0;i<n;i++) mean_x += x[i];
   mean_x /= (phydbl)n;
 
   mean_y = .0;
-  For(i,n) mean_y += y[i];
+  for(i=0;i<n;i++) mean_y += y[i];
   mean_y /= (phydbl)n;
 
   mean_xy = .0;
-  For(i,n) mean_xy += x[i]*y[i];
+  for(i=0;i<n;i++) mean_xy += x[i]*y[i];
   mean_xy /= (phydbl)n;
   
   return (mean_xy - mean_x*mean_y);
@@ -4235,7 +4234,7 @@ phydbl *Rnorm_Multid_Trunc_Constraint(phydbl *mu, phydbl *cov, phydbl *min, phyd
   do
     {
       sum = 0.0;
-      For(i,len)
+      for(i=0;i<len;i++)
 	{      
 	  if(i != cond)
 	    {
@@ -4248,7 +4247,7 @@ phydbl *Rnorm_Multid_Trunc_Constraint(phydbl *mu, phydbl *cov, phydbl *min, phyd
 	      
 	      /* alpha = k - \sum_{j != cond, j !=i} z_j */
 	      alpha = k;
-	      For(j,len) if(j != cond && j != i) alpha -= lambda[j] * x[j];
+	      for(j=0;j<len;j++) if(j != cond && j != i) alpha -= lambda[j] * x[j];
 	      
 	      cond_mean = mean_zi + (cov_zii + cov_zic) / (cov_zii + 2.*cov_zic + cov_zcc) * (alpha - mean_zi - mean_zc);
 	      cond_var  = cov_zii - POW(cov_zii + cov_zic,2)/(cov_zii + 2.*cov_zic + cov_zcc);
@@ -4321,7 +4320,7 @@ void Integrated_Brownian_Bridge_Moments(phydbl x_beg, phydbl x_end,
   /* y[0] = y_beg; */
   /* y[n_breaks+1] = y_end; */
 
-  /* For(i,n_rep) */
+  /* for(i=0;i<n_rep;i++) */
   /*   { */
   /*     for(j=1;j<n_breaks+1;j++) */
   /* 	{ */
@@ -4355,7 +4354,7 @@ void Integrated_Brownian_Bridge_Moments(phydbl x_beg, phydbl x_end,
   /*   } */
 
   /* sum = sumsum = 0.0; */
-  /* For(i,n_rep) */
+  /* for(i=0;i<n_rep;i++) */
   /*   { */
   /*     sum += y_mean[i]; */
   /*     sumsum += y_mean[i] * y_mean[i]; */
@@ -4387,7 +4386,7 @@ void Integrated_Brownian_Bridge_Moments(phydbl x_beg, phydbl x_end,
       six = SQRT(scaled_var*(x - x_beg)*(x_end - x)/(x_end - x_beg));
 
       sum += 
-	(2.*six)/SQRT(2.*PI)*EXP(-POW(mux,2)/(2.*POW(six,2))) + 
+	(2.*six)/SQRT(2.*PI)*exp(-POW(mux,2)/(2.*POW(six,2))) + 
 	2.*mux*Pnorm(mux/six,.0,1.) - mux;
     }
   sum += y_end;
@@ -4627,22 +4626,22 @@ phydbl t1369 = -0.71204290560e11 * t285 * u * T - 0.8638755840e10 * t75 * t70 *
  /* printf("\n. Taylor: %f",*mean); */
  
  /*  /\* C(int(exp((B-A)*s/T+(1/2)*u*(T-s)*s/T), s = 0 .. T)) *\/ */
- /*  /\* Correct but numerically unstable due to EXP(TOO BIG) *\/ */
+ /*  /\* Correct but numerically unstable due to exp(TOO BIG) *\/ */
 
  /* *mean = */
  /*   SQRT(0.2e1) * */
  /*   SQRT(0.3141592654e1) * */
- /*   EXP((double) ((4 * B * B - 8 * B * A + 4 * B * u * T + 4 * A * A - 4 * A * u * T + u * u * T * T) / u / T) / 0.8e1) * */
+ /*   exp((double) ((4 * B * B - 8 * B * A + 4 * B * u * T + 4 * A * A - 4 * A * u * T + u * u * T * T) / u / T) / 0.8e1) * */
  /*   (-erf(SQRT(0.2e1) * (double) (-2 * B + 2 * A - u * T) / (double) T * pow((double) (u / T), -0.1e1 / 0.2e1) / 0.4e1) */
  /*    +erf(SQRT(0.2e1) * (double) (u *  T - 2 * B + 2 * A) / (double) T * pow((double) (u / T), -0.1e1 / 0.2e1) / 0.4e1))* */
  /*   pow((double) (u / T), -0.1e1 / 0.2e1) / 0.2e1; */
  
  /* *mean /= T; */
- /* *mean *= EXP(A); */
+ /* *mean *= exp(A); */
 
  /* printf("\nErf: %f [%f %f %f]", */
  /*        *mean, */
- /*        EXP((double) ((4 * B * B - 8 * B * A + 4 * B * u * T + 4 * A * A - 4 * A * u * T + u * u * T * T) / u / T) / 0.8e1), */
+ /*        exp((double) ((4 * B * B - 8 * B * A + 4 * B * u * T + 4 * A * A - 4 * A * u * T + u * u * T * T) / u / T) / 0.8e1), */
  /*        (double) ((4 * B * B - 8 * B * A + 4 * B * u * T + 4 * A * A - 4 * A * u * T + u * u * T * T) / u / T) / 0.8e1, */
  /*        (-erf(SQRT(0.2e1) * (double) (-2 * B + 2 * A - u * T) / (double) T * pow((double) (u / T), -0.1e1 / 0.2e1) / 0.4e1) + erf(SQRT(0.2e1) * (double) (u * T - 2 * B + 2 * A) / (double) T * pow((double) (u / T), -0.1e1 / 0.2e1) / 0.4e1)) * pow((double) (u / T), -0.1e1 / 0.2e1) / 0.2e1); */
 
@@ -4856,8 +4855,8 @@ int Sample_i_With_Proba_pi(phydbl *pi, int len)
   cum_pi = (phydbl *)mCalloc(len,sizeof(phydbl));
 
   u = .0;
-  For(i,len) u += pi[i];  
-  For(i,len) cum_pi[i] = pi[i] / u;
+  for(i=0;i<len;i++) u += pi[i];  
+  for(i=0;i<len;i++) cum_pi[i] = pi[i] / u;
   for(i=1;i<len;i++) cum_pi[i] += cum_pi[i-1];
 
   if((cum_pi[i-1] > 1. + 1.E-10) || (cum_pi[i-1] < 1. - 1.E-10))
@@ -4869,11 +4868,11 @@ int Sample_i_With_Proba_pi(phydbl *pi, int len)
 
   i = 0;
   u = Uni();
-  For(i,len) if(cum_pi[i] > u) break;
+  for(i=0;i<len;i++) if(cum_pi[i] > u) break;
 
   if(i == len)
     {
-      For(i,len) printf("\n== idx:%d prob:%g",i,pi[i]);
+      for(i=0;i<len;i++) printf("\n== idx:%d prob:%g",i,pi[i]);
       PhyML_Printf("\n== Len = %d",len);
       PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__);
       Exit("\n");
@@ -4895,12 +4894,12 @@ phydbl Quantile(phydbl *x, int len, phydbl p)
   phydbl buff;
 
   y = (phydbl *)mCalloc(len,sizeof(phydbl));
-  For(i,len) y[i] = x[i];
+  for(i=0;i<len;i++) y[i] = x[i];
 
   do
     {
       swap = NO;
-      For(i,len-1) 
+      for(i=0;i<len-1;i++) 
         {
           if(y[i+1] < y[i])
             {
@@ -4933,7 +4932,7 @@ phydbl Prob(phydbl *x, int len, phydbl z)
   phydbl hit;
 
   hit = 0.;
-  For(i,len) if(x[i] < z) hit+=1.;
+  for(i=0;i<len;i++) if(x[i] < z) hit+=1.;
 
   return(hit/(phydbl)len);
 
@@ -4952,8 +4951,8 @@ phydbl Inverse_Truncated_Normal(phydbl y, phydbl mu, phydbl sigma, phydbl lim_in
   p_inf = Pnorm(lim_inf,mu,sigma);
   p_sup = Pnorm(lim_sup,mu,sigma);
 
-  /* return(mu + sigma * SQRT(-LOG( y * y * (p_sup - p_inf) * (p_sup - p_inf) * 2 * PI * sigma * sigma))); */
-  return(mu + sigma * SQRT(-LOG( y * y * (p_sup - p_inf) * (p_sup - p_inf) * 2. * PI * sigma * sigma)));
+  /* return(mu + sigma * SQRT(-log( y * y * (p_sup - p_inf) * (p_sup - p_inf) * 2 * PI * sigma * sigma))); */
+  return(mu + sigma * SQRT(-log( y * y * (p_sup - p_inf) * (p_sup - p_inf) * 2. * PI * sigma * sigma)));
 }
 
 //////////////////////////////////////////////////////////////
@@ -4968,9 +4967,9 @@ int *Permutate(int len)
 
   x = (int *)mCalloc(len,sizeof(int));
 
-  For(i,len) x[i] = i;
+  for(i=0;i<len;i++) x[i] = i;
 
-  For(i,len)
+  for(i=0;i<len;i++)
     {
       pos = Rand_Int(i,len-1);
       
@@ -5002,32 +5001,32 @@ phydbl Mantel(phydbl *x, phydbl *y, int nrow, int ncol)
   N = nrow*ncol;
 
   sumx = .0;
-  For(i,N) sumx += x[i];
+  for(i=0;i<N;i++) sumx += x[i];
 
   sumy = .0;
-  For(i,N) sumy += y[i];
+  for(i=0;i<N;i++) sumy += y[i];
 
   sumxx = .0;
-  For(i,N) sumxx += x[i]*x[i];
+  for(i=0;i<N;i++) sumxx += x[i]*x[i];
 
   sumyy = .0;
-  For(i,N) sumyy += y[i]*y[i];
+  for(i=0;i<N;i++) sumyy += y[i]*y[i];
 
   sumxy = .0;
-  For(i,N) sumxy += x[i]*y[i];
+  for(i=0;i<N;i++) sumxy += x[i]*y[i];
 
   obs_stat = (N * sumxy - sumx * sumy) / (SQRT((N-1)*sumxx - (sumx/N)*(sumx/N)) * SQRT((N-1)*sumyy - (sumy/N)*(sumy/N)));
   
   npermut = 1000;
   p_val   = 0.0;
-  For(k,npermut)
+  for(k=0;k<npermut;k++)
     {
       permut = Permutate(nrow);
 
       sumxy = .0;
-      For(i,nrow)
+      for(i=0;i<nrow;i++)
         {
-          For(j,ncol)
+          for(j=0;j<ncol;j++)
             {
               sumxy += x[i*ncol+j] * y[permut[i]*ncol+permut[j]];
             }
@@ -5052,10 +5051,10 @@ phydbl Weighted_Mean(phydbl *x, phydbl *w, int l)
   int i;
   phydbl wm;
   wm = .0;
-  if(w) For(i,l) wm += x[i]*w[i];
+  if(w) for(i=0;i<l;i++) wm += x[i]*w[i];
   else  
     {
-      For(i,l) wm += x[i];
+      for(i=0;i<l;i++) wm += x[i];
       wm /= (phydbl)l;
     }
   return(wm);
@@ -5071,7 +5070,7 @@ phydbl Variance(phydbl *x, int l)
 
   mean = Weighted_Mean(x,NULL,l);
   sum = 0.0;
-  For(i,l) sum += x[i]*x[i];
+  for(i=0;i<l;i++) sum += x[i]*x[i];
   
   return(sum/l - mean*mean);
 }
@@ -5091,7 +5090,7 @@ int Sum_Bits(int value, int range)
     }
 
   sum = 0;
-  For(i,range)
+  for(i=0;i<range;i++)
     {
       sum += (value >> i) & 1;
     }
@@ -5139,7 +5138,8 @@ void Runif_Disk(phydbl *sampled_x, phydbl *sampled_y, phydbl centrx, phydbl cent
 void Random_String(char *s, int len)
 {
   int i;
-  For(i,len) s[i] = Rand_Int(97,121);
+  for(i=0;i<len;i++) s[i] = Rand_Int(97,121);
+  s[i] = '\0';
 }
 
 //////////////////////////////////////////////////////////////
@@ -5159,9 +5159,9 @@ int *Random_Permut(int n)
     
   permut = (int *)mCalloc(n,sizeof(int));
 
-  For(i,n) permut[i] = i;
+  for(i=0;i<n;i++) permut[i] = i;
   
-  For(i,n-1)
+  for(i=0;i<n-1;i++)
     {
       j = Rand_Int(i,n-1);
       tmp = permut[i];
@@ -5184,7 +5184,7 @@ t_poly *Rpoly(int n)
   p = (t_poly *)Make_Poly(n);  
   p->n_poly_vert = n;
   
-  For(i,n)
+  for(i=0;i<n;i++)
     {
       p->poly_vert[i]->lonlat[0] = Uni();
       p->poly_vert[i]->lonlat[1] = Uni();
@@ -5196,9 +5196,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 +5210,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,13 +5231,16 @@ 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];
 
   j = poly->n_poly_vert-1;
   is_in = NO;
-  For(i,poly->n_poly_vert)
+  for(i=0;i<poly->n_poly_vert;i++)
     {
       /* Edge of polygon goes from (x1,y1) to (x2,y2) */
       x1 = poly->poly_vert[i]->lonlat[0];
@@ -5319,14 +5323,14 @@ phydbl Euclidean_Dist(t_geo_coord *x, t_geo_coord *y)
   if(x->dim != y->dim) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);    
   
   dist = 0.0;
-  For(i,x->dim) dist += POW(x->lonlat[i]-y->lonlat[i],2);
+  for(i=0;i<x->dim;i++) dist += POW(x->lonlat[i]-y->lonlat[i],2);
 
   return(SQRT(dist));
 }
 
 /*////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////*/
-/* Return the ranks of elements in x */
+/* Return a vector rk such that rk[i] gives the index of the i-th largest element in x */
 int *Ranks(phydbl *x, int len)
 {
   int *rk,tmp;
@@ -5334,14 +5338,14 @@ int *Ranks(phydbl *x, int len)
 
   rk = (int *)mCalloc(len,sizeof(int));
 
-  For(i,len) rk[i] = i;
+  for(i=0;i<len;i++) rk[i] = i;
 
   do
     {
       swap = NO;
-      For(i,len-1) 
+      for(i=0;i<len-1;i++) 
         {
-          if(x[rk[i]] > x[rk[i+1]])
+          if(x[rk[i]] < x[rk[i+1]])
             {
               swap  = YES; 
               tmp   = rk[i];
@@ -5365,12 +5369,12 @@ phydbl *Brownian_Bridge_Generate(phydbl start, phydbl end, phydbl var, phydbl be
 
   if(n_steps == 0) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
   if(beg_time > end_time) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
-  For(i,n_steps-1) if(!(time[i+1] > time[i])) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
+  for(i=0;i<n_steps-1;i++) if(!(time[i+1] > time[i])) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
 
   state = Brownian_Generate(var,n_steps,beg_time,time);
   end_brown = Rnorm(state[n_steps-1],SQRT((time[n_steps-1] - end_time)*var));
 
-  For(i,n_steps)
+  for(i=0;i<n_steps;i++)
     {
       state[i] = state[i] - (time[i]/end_time) * end_brown;
       state[i] = start + (end - start)/end_time * time[i] + state[i];
@@ -5416,7 +5420,7 @@ phydbl *Random_Walk_Bridged_Generate(phydbl start, phydbl end, phydbl var, int n
   state = Random_Walk_Generate(var,n_steps);
   end_walk = Rnorm(state[n_steps-1],SQRT(var));
 
-  For(i,n_steps)
+  for(i=0;i<n_steps;i++)
     {
       state[i] = state[i] - ((phydbl)(i+1.)/n_steps) * end_walk;
       state[i] = start + (end - start)/n_steps * (i+1.) + state[i];
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..418dccc 100644
--- a/src/times.c
+++ b/src/times.c
@@ -19,272 +19,6 @@ the GNU public licence. See http://www.opensource.org for details.
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-#ifdef PHYTIME
-
-int TIMES_main(int argc, char **argv)
-{
-  align **data;
-  calign *cdata;
-  option *io;
-  t_tree *tree;
-  int num_data_set;
-  int num_tree,num_rand_tree;
-  t_mod *mod;
-  time_t t_beg,t_end;
-  int r_seed;
-  char *most_likely_tree;
-  int i;
-  int user_lk_approx;
-  
-#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);
-  }
-  MPI_Comm_size(MPI_COMM_WORLD,&Global_numTask);
-  MPI_Comm_rank(MPI_COMM_WORLD,&Global_myRank);
-#endif
-
-#ifdef QUIET
-  setvbuf(stdout,NULL,_IOFBF,2048);
-#endif
-
-  tree             = NULL;
-  mod              = NULL;
-  data             = NULL;
-  most_likely_tree = NULL;
-
-  io = (option *)Get_Input(argc,argv);
-
-  r_seed = (io->r_seed < 0)?(time(NULL)):(io->r_seed);
-  io->r_seed = r_seed;
-  srand(r_seed); rand();
-  PhyML_Printf("\n. Seed: %d\n",r_seed);
-  PhyML_Printf("\n. Pid: %d\n",getpid());
-  Make_Model_Complete(io->mod);
-  mod = io->mod;
-  if(io->in_tree == 2) Test_Multiple_Data_Set_Format(io);
-  else io->n_trees = 1;
-  
-  if((io->n_data_sets > 1) && (io->n_trees > 1))
-    {
-      io->n_data_sets = MIN(io->n_trees,io->n_data_sets);
-      io->n_trees     = MIN(io->n_trees,io->n_data_sets);
-    }
-  
-
-  For(num_data_set,io->n_data_sets)
-    {
-      data = Get_Seq(io);
-
-      if(data)
-	{
-	  if(io->n_data_sets > 1) PhyML_Printf("\n. Data set [#%d]\n",num_data_set+1);
-	  PhyML_Printf("\n. Compressing sequences...\n");
-	  cdata = Compact_Data(data,io);
-	  Free_Seq(data,cdata->n_otu);
-	  Check_Ambiguities(cdata,io->mod->io->datatype,io->state_len);
-
-	  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;
-
-	      For(num_rand_tree,io->mod->s_opt->n_rand_starts)
-		{
-		  if((io->mod->s_opt->random_input_tree) && (io->mod->s_opt->topo_search != NNI_MOVE))
-		    PhyML_Printf("\n. [Random start %3d/%3d]\n",num_rand_tree+1,io->mod->s_opt->n_rand_starts);
-
-
-		  Init_Model(cdata,mod,io);
-
-		  if(io->mod->use_m4mod) M4_Init_Model(mod->m4mod,cdata,mod);
-
-		  /* A BioNJ tree is built here */
-		  if(!io->in_tree) tree = Dist_And_BioNJ(cdata,mod,io);
-		  /* A user-given tree is used here instead of BioNJ */
-		  else             tree = Read_User_Tree(cdata,mod,io);
-
-
- 		  if(io->fp_in_constraint_tree != NULL) 
-		    {
-		      io->cstr_tree        = Read_Tree_File_Phylip(io->fp_in_constraint_tree);		      
-		      io->cstr_tree->rates = RATES_Make_Rate_Struct(io->cstr_tree->n_otu);
-		      RATES_Init_Rate_Struct(io->cstr_tree->rates,io->rates,io->cstr_tree->n_otu);
-		    }
-
-		  if(!tree) continue;
-
-		  if(!tree->n_root) 
-		    {
-		      PhyML_Printf("\n== Sorry, PhyTime requires a rooted tree as input.");
-		      Exit("\n");      
-		    }
-
-		  time(&t_beg);
-		  time(&(tree->t_beg));
-		  tree->rates = RATES_Make_Rate_Struct(tree->n_otu);
-		  RATES_Init_Rate_Struct(tree->rates,io->rates,tree->n_otu);
-
-		  Update_Ancestors(tree->n_root,tree->n_root->v[2],tree);
-		  Update_Ancestors(tree->n_root,tree->n_root->v[1],tree);		  
-
-		  RATES_Fill_Lca_Table(tree);
-
-		  tree->mod         = mod;
-		  tree->io          = io;
-		  tree->data        = cdata;
-		  tree->n_pattern   = tree->data->crunch_len/tree->io->state_len;
-
-                  Set_Both_Sides(YES,tree);
-
-		  Prepare_Tree_For_Lk(tree);
-
-		  /* Read node age priors */
-		  Read_Clade_Priors(io->clade_list_file,tree);
-
-		  /* Set upper and lower bounds for all node ages */
-		  TIMES_Set_All_Node_Priors(tree);
-
-		  /* Count the number of time slices */
-		  TIMES_Get_Number_Of_Time_Slices(tree);
-		  
-                  TIMES_Label_Edges_With_Calibration_Intervals(tree);
-                  tree->write_br_lens = NO;
-                  PhyML_Printf("\n");
-                  PhyML_Printf("\n. Input tree with calibration information ('almost' compatible with MCMCtree).\n");
-                  PhyML_Printf("\n%s\n",Write_Tree(tree,YES));
-                  tree->write_br_lens = YES;
-
-
-		  /* Get_Edge_Binary_Coding_Number(tree); */
-		  /* Exit("\n"); */
-
-		  /* Print_CSeq_Select(stdout,NO,tree->data,tree); */
-		  /* Exit("\n"); */
-
-		  /* TIMES_Set_Root_Given_Tip_Dates(tree); */
-		  /* int i; */
-		  /* char *s; */
-		  /* FILE *fp; */
-		  /* For(i,2*tree->n_otu-2) tree->rates->cur_l[i] = 1.; */
-		  /* s = Write_Tree(tree,NO); */
-		  /* fp = fopen("rooted_tree","w"); */
-		  /* fprintf(fp,"%s\n",s); */
-		  /* fclose(fp); */
-		  /* Exit("\n"); */
-
-
-		  /* Work with log of branch lengths? */
-		  if(tree->mod->log_l == YES) Log_Br_Len(tree);
-
-		  if(io->mcmc->use_data == YES)
-		    {
-		      /* Force the exact likelihood score */
-		      user_lk_approx = tree->io->lk_approx;
-		      tree->io->lk_approx = EXACT;
-		                            
-                      /* printf("\n. Lk: %f",Lk(NULL,tree)); */
-                      /* Exit("\n"); */
-
-		      /* MLE for branch lengths */
-		      Round_Optimize(tree,tree->data,ROUND_MAX);
-		      
-		      /* Set vector of mean branch lengths for the Normal approximation
-			 of the likelihood */
-		      RATES_Set_Mean_L(tree);
-		      
-		      /* Estimate the matrix of covariance for the Normal approximation of
-			 the likelihood */
-		      PhyML_Printf("\n");
-		      PhyML_Printf("\n. Computing Hessian...");
-		      tree->rates->bl_from_rt = 0;
-		      Free(tree->rates->cov_l);
-		      tree->rates->cov_l = Hessian_Seo(tree);
-		      /* tree->rates->cov_l = Hessian_Log(tree); */
-		      For(i,(2*tree->n_otu-3)*(2*tree->n_otu-3)) tree->rates->cov_l[i] *= -1.0;
-		      if(!Iter_Matinv(tree->rates->cov_l,2*tree->n_otu-3,2*tree->n_otu-3,YES)) Exit("\n");
-		      tree->rates->covdet = Matrix_Det(tree->rates->cov_l,2*tree->n_otu-3,YES);
-		      For(i,(2*tree->n_otu-3)*(2*tree->n_otu-3)) tree->rates->invcov[i] = tree->rates->cov_l[i];
-		      if(!Iter_Matinv(tree->rates->invcov,2*tree->n_otu-3,2*tree->n_otu-3,YES)) Exit("\n");
-		      tree->rates->grad_l = Gradient(tree);
-		      
-		      
-		      /* Pre-calculation of conditional variances to speed up calculations */
-		      RATES_Bl_To_Ml(tree);
-		      RATES_Get_Conditional_Variances(tree);
-		      RATES_Get_All_Reg_Coeff(tree);
-		      RATES_Get_Trip_Conditional_Variances(tree);
-		      RATES_Get_All_Trip_Reg_Coeff(tree);
-		      
-		      Lk(NULL,tree);
-		      PhyML_Printf("\n");
-		      PhyML_Printf("\n. p(data|model) [exact ] ~ %.2f",tree->c_lnL);
-		      
-		      tree->io->lk_approx = NORMAL;
-		      For(i,2*tree->n_otu-3) tree->rates->u_cur_l[i] = tree->rates->mean_l[i] ;
-		      tree->c_lnL = Lk(NULL,tree);
-		      PhyML_Printf("\n. p(data|model) [approx] ~ %.2f",tree->c_lnL);
-
-		      tree->io->lk_approx = user_lk_approx;
-		    }
-
-		  tree->rates->model = io->rates->model;		  
-		  PhyML_Printf("\n. Selected model '%s'",RATES_Get_Model_Name(io->rates->model));
-		  if(tree->rates->model == GUINDON) tree->mod->gamma_mgf_bl = YES;
-		  
-		  tree->rates->bl_from_rt = YES;
-		  
-		  if(tree->io->cstr_tree) Find_Surviving_Edges_In_Small_Tree(tree,tree->io->cstr_tree);
-
-		  time(&t_beg);
-		  tree->mcmc = MCMC_Make_MCMC_Struct();
-		  MCMC_Copy_MCMC_Struct(tree->io->mcmc,tree->mcmc,"phytime");
-		  MCMC_Complete_MCMC(tree->mcmc,tree);
-		  tree->mcmc->is_burnin = NO;
-		  tree->mod->ras->sort_rate_classes = YES;
-                  MCMC(tree);
-		  MCMC_Close_MCMC(tree->mcmc);
-		  MCMC_Free_MCMC(tree->mcmc);
-                  Add_Root(tree->a_edges[0],tree);
-		  Free_Tree_Pars(tree);
-		  Free_Tree_Lk(tree);
-		  Free_Tree(tree);
-		}
-
-	      break;
-	    }
-	  Free_Cseq(cdata);
-	}
-    }
-
-  Free_Model(mod);
-
-  if(io->fp_in_align)   fclose(io->fp_in_align);
-  if(io->fp_in_tree)    fclose(io->fp_in_tree);
-  if(io->fp_out_lk)     fclose(io->fp_out_lk);
-  if(io->fp_out_tree)   fclose(io->fp_out_tree);
-  if(io->fp_out_trees)  fclose(io->fp_out_trees);
-  if(io->fp_out_stats)  fclose(io->fp_out_stats);
-
-  Free(most_likely_tree);
-  Free_Input(io);
-
-  time(&t_end);
-  Print_Time_Info(t_beg,t_end);
-
-#ifdef MPI
-  MPI_Finalize();
-#endif
-
-  return 0;
-}
-
-#endif
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
 
 
 void TIMES_Least_Square_Node_Times(t_edge *e_root, t_tree *tree)
@@ -329,10 +63,10 @@ void TIMES_Least_Square_Node_Times(t_edge *e_root, t_tree *tree)
       Exit("\n");      
     }
 
-  For(i,n) x[i] = .0;
-  For(i,n) For(j,n) x[i] += A[i*n+j] * b[j];
+  for(i=0;i<n;i++) x[i] = .0;
+  for(i=0;i<n;i++) for(j=0;j<n;j++) x[i] += A[i*n+j] * b[j];
 
-  For(i,n-1) { tree->rates->nd_t[tree->a_nodes[i]->num] = -x[i]; }
+  for(i=0;i<n-1;i++) { tree->rates->nd_t[tree->a_nodes[i]->num] = -x[i]; }
   tree->rates->nd_t[root->num] = -x[n-1];
   tree->n_root->l[2] = tree->rates->nd_t[root->v[2]->num] - tree->rates->nd_t[root->num];
   tree->n_root->l[1] = tree->rates->nd_t[root->v[1]->num] - tree->rates->nd_t[root->num];
@@ -391,13 +125,13 @@ void TIMES_Least_Square_Node_Times_Pre(t_node *a, t_node *d, phydbl *A, phydbl *
       int i;
       
  
-      For(i,3)
+      for(i=0;i<3;i++)
 	if((d->v[i] != a) && (d->b[i] != tree->e_root))
 	  TIMES_Least_Square_Node_Times_Pre(d,d->v[i],A,b,n,tree);
       
       A[d->num * n + d->num] = 1.;
       b[d->num] = .0;
-      For(i,3)
+      for(i=0;i<3;i++)
 	{
 	  A[d->num * n + d->v[i]->num] = -1./3.;
 	  if(d->v[i] != a) b[d->num] += d->b[i]->l->v;
@@ -439,14 +173,14 @@ void TIMES_Adjust_Node_Times_Pre(t_node *a, t_node *d, t_tree *tree)
       int i;
       phydbl min_height;
 
-      For(i,3)
+      for(i=0;i<3;i++)
 	if((d->v[i] != a) && (d->b[i] != tree->e_root))
 	  {
 	    TIMES_Adjust_Node_Times_Pre(d,d->v[i],tree);
 	  }
 
       min_height = 0.0;
-      For(i,3)
+      for(i=0;i<3;i++)
 	{
 	  if((d->v[i] != a) && (d->b[i] != tree->e_root))
 	    {
@@ -482,14 +216,13 @@ void TIMES_Mult_Time_Stamps(t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void TIMES_Print_Node_Times(t_node *a, t_node *d, t_tree *tree)
 {
   t_edge *b;
   int i;
   
   b = NULL;
-  For(i,3) if((d->v[i]) && (d->v[i] == a)) {b = d->b[i]; break;}
+  for(i=0;i<3;i++) if((d->v[i]) && (d->v[i] == a)) {b = d->b[i]; break;}
 
   PhyML_Printf("\n. (%3d %3d) a->t = %12f d->t = %12f (#=%12f) b->l->v = %12f [%12f;%12f]",
 	       a->num,d->num,
@@ -503,7 +236,7 @@ void TIMES_Print_Node_Times(t_node *a, t_node *d, t_tree *tree)
   else
     {
       int i;
-      For(i,3)
+      for(i=0;i<3;i++)
 	if((d->v[i] != a) && (d->b[i] != tree->e_root))
 	  TIMES_Print_Node_Times(d,d->v[i],tree);
     }
@@ -512,7 +245,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;
@@ -574,7 +306,7 @@ void TIMES_Set_All_Node_Priors_Bottom_Up(t_node *a, t_node *d, t_tree *tree)
     {
       t_node *v1, *v2; /* the two sons of d */
 
-      For(i,3)
+      for(i=0;i<3;i++)
 	{
 	  if((d->v[i] != a) && (d->b[i] != tree->e_root))
 	    {
@@ -583,7 +315,7 @@ void TIMES_Set_All_Node_Priors_Bottom_Up(t_node *a, t_node *d, t_tree *tree)
 	}
       
       v1 = v2 = NULL;
-      For(i,3) if((d->v[i] != a) && (d->b[i] != tree->e_root)) 
+      for(i=0;i<3;i++) if((d->v[i] != a) && (d->b[i] != tree->e_root)) 
 	{
 	  if(!v1) v1 = d->v[i]; 
 	  else    v2 = d->v[i];
@@ -631,9 +363,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");
 	    }
 	}
@@ -642,7 +374,7 @@ void TIMES_Set_All_Node_Priors_Top_Down(t_node *a, t_node *d, t_tree *tree)
 	  tree->rates->t_prior_min[d->num] = tree->rates->t_prior_min[a->num];
 	}
             
-      For(i,3)
+      for(i=0;i<3;i++)
 	{
 	  if((d->v[i] != a) && (d->b[i] != tree->e_root))
 	    {
@@ -682,7 +414,7 @@ void TIMES_Set_Floor_Post(t_node *a, t_node *d, t_tree *tree)
       t_node *v1,*v2;
 
       v1 = v2 = NULL;
-      For(i,3)
+      for(i=0;i<3;i++)
 	{
 	  if(d->v[i] != a && d->b[i] != tree->e_root)
 	    {
@@ -728,7 +460,7 @@ phydbl TIMES_Log_Conditional_Uniform_Density(t_tree *tree)
 	{
 	  max = tree->rates->t_floor[i];
 
-	  dens += LOG(Dorder_Unif(tree->rates->nd_t[i],
+	  dens += log(Dorder_Unif(tree->rates->nd_t[i],
 				  tree->a_nodes[i]->rank-1,
 				  tree->a_nodes[i]->rank_max-2,
 				  min,max));
@@ -766,7 +498,7 @@ phydbl TIMES_Lk_Yule_Root_Marginal(t_tree *tree)
 	n++;
     }
 
-  return LnGamma(n+1) + LOG(lbda) - 2.*lbda*T + (n-2.)*LOG(1. - EXP(-lbda*T));
+  return LnGamma(n+1) + log(lbda) - 2.*lbda*T + (n-2.)*log(1. - exp(-lbda*T));
 }
 
 //////////////////////////////////////////////////////////////
@@ -797,7 +529,7 @@ phydbl TIMES_Lk_Yule_Joint(t_tree *tree)
 
   TIMES_Update_Node_Ordering(tree);
 
-  For(j,tree->n_otu) interrupted[j] = NO;
+  for(j=0;j<tree->n_otu;j++) interrupted[j] = NO;
 
   loglk = .0;
 
@@ -806,7 +538,7 @@ phydbl TIMES_Lk_Yule_Joint(t_tree *tree)
   For(i,2*tree->n_otu-2) // t[tr[0]] is the time of the oldest node, t[tr[1]], the second oldest and so on...
     {
 
-      For(j,tree->n_otu)
+      for(j=0;j<tree->n_otu;j++)
 	if((t[j] < t[tr[i]]) && (interrupted[j] == NO)) 
 	  {
 	    interrupted[j] = YES;
@@ -826,14 +558,14 @@ phydbl TIMES_Lk_Yule_Joint(t_tree *tree)
 	  Exit("\n");
 	}
 
-      if(dt > 1.E-10) loglk += LOG((n+1)*lbda) - (n+1)*lbda*dt;
+      if(dt > 1.E-10) loglk += log((n+1)*lbda) - (n+1)*lbda*dt;
       n++;      
     }
 
   /* printf("\n. sumdt = %f th=%f",sumdt,tree->rates->nd_t[tree->n_root->num]); */
   /* printf("\n0 loglk = %f",loglk); */
 
-  For(i,tree->rates->n_time_slices-1)
+  for(i=0;i<tree->rates->n_time_slices-1;i++)
     {
       n = 0;
       dt = 0.;
@@ -847,7 +579,7 @@ phydbl TIMES_Lk_Yule_Joint(t_tree *tree)
   	    }
   	}
       dt -= ts[i];
-      loglk += LOG(n*lbda) - n*lbda*dt;
+      loglk += log(n*lbda) - n*lbda*dt;
     }
 
   /* printf("\n1 loglk = %f",loglk); */
@@ -879,7 +611,7 @@ phydbl TIMES_Lk_Yule_Order(t_tree *tree)
   tf = tree->rates->t_floor;
   t  = tree->rates->nd_t;
   n = NULL;
-  loglbda = LOG(tree->rates->birth_rate);
+  loglbda = log(tree->rates->birth_rate);
   lbda = tree->rates->birth_rate;
   lower_bound = -1.;
   upper_bound = -1.;
@@ -899,7 +631,7 @@ phydbl TIMES_Lk_Yule_Order(t_tree *tree)
   /*     if(n->tax == NO) */
   /*       { */
   /*         loglk  += (loglbda - lbda * FABS(t[j])); */
-  /*         /\* loglk -= LOG(EXP(-lbda*lower_bound) - EXP(-lbda*upper_bound)); // incorporate calibration boundaries here. *\/ */
+  /*         /\* loglk -= log(exp(-lbda*lower_bound) - exp(-lbda*upper_bound)); // incorporate calibration boundaries here. *\/ */
   /*       } */
   /*   } */
 
@@ -920,7 +652,7 @@ phydbl TIMES_Lk_Yule_Order(t_tree *tree)
       if(n->tax == NO)
         {
           loglk  += (loglbda - lbda * FABS(t[j]));
-          loglk -= LOG(EXP(-lbda*lower_bound) - EXP(-lbda*upper_bound)); // incorporate calibration boundaries here.    
+          loglk -= log(exp(-lbda*lower_bound) - exp(-lbda*upper_bound)); // incorporate calibration boundaries here.    
         }
       
       if(isinf(loglk) || isnan(loglk))
@@ -928,9 +660,9 @@ phydbl TIMES_Lk_Yule_Order(t_tree *tree)
           /* PhyML_Printf("\n. Lower bound: %f",lower_bound); */
           /* PhyML_Printf("\n. Upper bound: %f",upper_bound); */
           /* PhyML_Printf("\n. tf: %f tp_max: %f tp_min: %f ",tf[j],tp_max[j],tp_min[j]); */
-          /* PhyML_Printf("\n. exp1: %f",EXP(-lbda*lower_bound)); */
-          /* PhyML_Printf("\n. exp2: %f",EXP(-lbda*upper_bound)); */
-          /* PhyML_Printf("\n. diff: %f",EXP(-lbda*lower_bound) - EXP(-lbda*upper_bound)); */
+          /* PhyML_Printf("\n. exp1: %f",exp(-lbda*lower_bound)); */
+          /* PhyML_Printf("\n. exp2: %f",exp(-lbda*upper_bound)); */
+          /* PhyML_Printf("\n. diff: %f",exp(-lbda*lower_bound) - exp(-lbda*upper_bound)); */
           /* Exit("\n"); */
           return(-INFINITY);
         }      
@@ -938,17 +670,17 @@ phydbl TIMES_Lk_Yule_Order(t_tree *tree)
 
   lower_bound = MAX(FABS(tf[tree->n_root->num]),FABS(tp_max[tree->n_root->num]));
   upper_bound = FABS(tp_min[tree->n_root->num]);
-  loglk += LOG(2) + loglbda - 2.*lbda * FABS(t[tree->n_root->num]);
-  loglk -= LOG(EXP(-2.*lbda*lower_bound) - EXP(-2.*lbda*upper_bound));
+  loglk += log(2) + loglbda - 2.*lbda * FABS(t[tree->n_root->num]);
+  loglk -= log(exp(-2.*lbda*lower_bound) - exp(-2.*lbda*upper_bound));
 
   if(isinf(loglk) || isnan(loglk))
     {
       /* PhyML_Printf("\n. * Lower bound: %f",lower_bound); */
       /* PhyML_Printf("\n. * Upper bound: %f",upper_bound); */
       /* PhyML_Printf("\n. * tf: %f tp_max: %f tp_min: %f",tf[tree->n_root->num],tp_max[tree->n_root->num],tp_min[tree->n_root->num]); */
-      /* PhyML_Printf("\n. * exp1: %f",EXP(-2.*lbda*lower_bound)); */
-      /* PhyML_Printf("\n. * exp2: %f",EXP(-2.*lbda*upper_bound)); */
-      /* PhyML_Printf("\n. * diff: %f",EXP(-2.*lbda*lower_bound) - EXP(-2.*lbda*upper_bound)); */
+      /* PhyML_Printf("\n. * exp1: %f",exp(-2.*lbda*lower_bound)); */
+      /* PhyML_Printf("\n. * exp2: %f",exp(-2.*lbda*upper_bound)); */
+      /* PhyML_Printf("\n. * diff: %f",exp(-2.*lbda*lower_bound) - exp(-2.*lbda*upper_bound)); */
       /* Exit("\n"); */
       return(-INFINITY);
     }
@@ -960,24 +692,11 @@ phydbl TIMES_Lk_Yule_Order(t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-phydbl TIMES_Lk_Times(t_tree *tree)
+phydbl TIMES_Lk_Times(int verbose, t_tree *tree)
 {
-  
-  #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
-
+  DATE_Update_T_Prior_MinMax(tree);
+  tree->rates->c_lnL_times =  TIMES_Lk_Birth_Death(verbose,tree);
+  /* if(tree->rates->c_lnL_times > UNLIKELY) tree->rates->c_lnL_times  = -1.; */
   return(tree->rates->c_lnL_times);
 }
 
@@ -1010,13 +729,13 @@ void TIMES_Lk_Times_Trav(t_node *a, t_node *d, phydbl lim_inf, phydbl lim_sup, p
       lim_inf = tree->rates->nd_t[tree->n_root->num];
       lim_sup = tree->rates->t_floor[d->num];
       
-      *logdens = *logdens + LOG(lim_sup - lim_inf);   
+      *logdens = *logdens + log(lim_sup - lim_inf);   
     }
   
   if(d->tax == YES) return;
   else
     {      
-      For(i,3)
+      for(i=0;i<3;i++)
 	{
 	  if(d->v[i] != a && d->b[i] != tree->e_root)
 	    {
@@ -1050,7 +769,7 @@ phydbl TIMES_Log_Number_Of_Ranked_Labelled_Histories(t_node *root, int per_slice
     }
   else
     {
-      For(i,3)
+      for(i=0;i<3;i++)
 	{
 	  if(root->v[i] != root->anc && root->b[i] != tree->e_root)
 	    {
@@ -1103,7 +822,7 @@ void TIMES_Log_Number_Of_Ranked_Labelled_Histories_Post(t_node *a, t_node *d, in
       int i,n1,n2;
       t_node *v1, *v2;
 
-      For(i,3)
+      for(i=0;i<3;i++)
 	{
 	  if(d->v[i] != a && d->b[i] != tree->e_root)
 	    {
@@ -1112,7 +831,7 @@ void TIMES_Log_Number_Of_Ranked_Labelled_Histories_Post(t_node *a, t_node *d, in
 	}
 
       v1 = v2 = NULL;
-      For(i,3)
+      for(i=0;i<3;i++)
 	{
 	  if(d->v[i] != a && d->b[i] != tree->e_root)
 	    {
@@ -1156,7 +875,7 @@ void TIMES_Update_Curr_Slice(t_tree *tree)
 
   For(i,2*tree->n_otu-1)
     {
-      For(j,tree->rates->n_time_slices)
+      for(j=0;j<tree->rates->n_time_slices;j++)
 	{
 	  if(!(tree->rates->nd_t[i] > tree->rates->time_slice_lims[j])) break;
 	}
@@ -1182,16 +901,16 @@ phydbl TIMES_Lk_Uniform_Core(t_tree *tree)
 
   /* printf("\n. ^ %f %f %f", */
   /* 	 (phydbl)(tree->rates->n_tips_below[tree->n_root->num]-2.), */
-  /* 	 LOG(tree->rates->time_slice_lims[tree->rates->curr_slice[tree->n_root->num]] - */
+  /* 	 log(tree->rates->time_slice_lims[tree->rates->curr_slice[tree->n_root->num]] - */
   /* 	     tree->rates->nd_t[tree->n_root->num]), */
   /* 	 (phydbl)(tree->rates->n_tips_below[tree->n_root->num]-2.) * */
-  /* 	 LOG(tree->rates->time_slice_lims[tree->rates->curr_slice[tree->n_root->num]] - */
+  /* 	 log(tree->rates->time_slice_lims[tree->rates->curr_slice[tree->n_root->num]] - */
   /* 	     tree->rates->nd_t[tree->n_root->num])); */
 
   tree->rates->c_lnL_times +=
     Factln(tree->rates->n_tips_below[tree->n_root->num]-2.) -
     (phydbl)(tree->rates->n_tips_below[tree->n_root->num]-2.) *
-    LOG(tree->rates->time_slice_lims[tree->rates->curr_slice[tree->n_root->num]] -
+    log(tree->rates->time_slice_lims[tree->rates->curr_slice[tree->n_root->num]] -
   	tree->rates->nd_t[tree->n_root->num]);
   
   tree->rates->c_lnL_times -= logn;
@@ -1216,7 +935,7 @@ void TIMES_Get_Number_Of_Time_Slices(t_tree *tree)
     {
       PhyML_Printf("\n");
       PhyML_Printf("\n. Sequences were collected at %d different time points.",tree->rates->n_time_slices);
-      For(i,tree->rates->n_time_slices) printf("\n+ [%3d] time point @ %12f ",i+1,tree->rates->time_slice_lims[i]);
+      for(i=0;i<tree->rates->n_time_slices;i++) printf("\n+ [%3d] time point @ %12f ",i+1,tree->rates->time_slice_lims[i]);
     }
 }
 
@@ -1230,7 +949,7 @@ void TIMES_Get_Number_Of_Time_Slices_Post(t_node *a, t_node *d, t_tree *tree)
 
   if(d->tax == YES)
     {
-      For(i,tree->rates->n_time_slices) 
+      for(i=0;i<tree->rates->n_time_slices;i++) 
 	if(Are_Equal(tree->rates->t_floor[d->num],tree->rates->time_slice_lims[i],1.E-6)) break;
 
       if(i == tree->rates->n_time_slices) 
@@ -1242,7 +961,7 @@ void TIMES_Get_Number_Of_Time_Slices_Post(t_node *a, t_node *d, t_tree *tree)
     }
   else
     {
-      For(i,3)
+      for(i=0;i<3;i++)
 	if(d->v[i] != a && d->b[i] != tree->e_root)
 	  TIMES_Get_Number_Of_Time_Slices_Post(d,d->v[i],tree);
     }
@@ -1260,7 +979,7 @@ void TIMES_Get_N_Slice_Spans(t_tree *tree)
     {
       if(tree->a_nodes[i]->tax == NO)
 	{
-	  For(j,tree->rates->n_time_slices)
+	  for(j=0;j<tree->rates->n_time_slices;j++)
 	    {
 	      if(Are_Equal(tree->rates->t_floor[i],tree->rates->time_slice_lims[j],1.E-6))
 		{
@@ -1287,7 +1006,7 @@ void TIMES_Lk_Uniform_Post(t_node *a, t_node *d, t_tree *tree)
     {
       int i;
 
-      For(i,3)
+      for(i=0;i<3;i++)
 	{
 	  if(d->v[i] != a && d->b[i] != tree->e_root)
 	    {
@@ -1300,7 +1019,7 @@ void TIMES_Lk_Uniform_Post(t_node *a, t_node *d, t_tree *tree)
 	  tree->rates->c_lnL_times += 
 	    Factln(tree->rates->n_tips_below[d->num]-1.) - 
 	    (phydbl)(tree->rates->n_tips_below[d->num]-1.) *
-	    LOG(tree->rates->time_slice_lims[tree->rates->curr_slice[d->num]] -
+	    log(tree->rates->time_slice_lims[tree->rates->curr_slice[d->num]] -
 		tree->rates->nd_t[d->num]);
 	}
     }
@@ -1309,7 +1028,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.
 */
@@ -1396,12 +1114,12 @@ void Get_Survival_Duration_Post(t_node *a, t_node *d, t_tree *tree)
       int i;
       t_node *v1, *v2;
 
-      For(i,3)
+      for(i=0;i<3;i++)
 	if(d->v[i] != a && d->b[i] != tree->e_root)
 	  Get_Survival_Duration_Post(d,d->v[i],tree);
       
       v1 = v2 = NULL;
-      For(i,3)
+      for(i=0;i<3;i++)
 	{
 	  if(d->v[i] != a && d->b[i] != tree->e_root)
 	    {
@@ -1420,6 +1138,7 @@ void Get_Survival_Duration_Post(t_node *a, t_node *d, t_tree *tree)
 //////////////////////////////////////////////////////////////
 
 /* Update the ranking of node heights. Use bubble sort algorithm */
+/* t_rank[i] is the node number that has rank i */
 
 void TIMES_Update_Node_Ordering(t_tree *tree)
 {
@@ -1428,6 +1147,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 +1159,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 +1167,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 +1218,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 +1271,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;
@@ -1567,7 +1286,7 @@ phydbl TIMES_Lk_Yule_Order_Root_Cond(t_tree *tree)
   tf = tree->rates->t_floor;
   t  = tree->rates->nd_t;
   n = NULL;
-  loglbda = LOG(tree->rates->birth_rate);
+  loglbda = log(tree->rates->birth_rate);
   lbda = tree->rates->birth_rate;
   lower_bound = -1.;
   upper_bound = -1.;
@@ -1587,7 +1306,7 @@ phydbl TIMES_Lk_Yule_Order_Root_Cond(t_tree *tree)
   /*     if(n->tax == NO) */
   /*       { */
   /*         loglk  += (loglbda - lbda * FABS(t[j])); */
-  /*         /\* loglk -= LOG(EXP(-lbda*lower_bound) - EXP(-lbda*upper_bound)); // incorporate calibration boundaries here. *\/ */
+  /*         /\* loglk -= log(exp(-lbda*lower_bound) - exp(-lbda*upper_bound)); // incorporate calibration boundaries here. *\/ */
   /*       } */
   /*   } */
 
@@ -1608,7 +1327,7 @@ phydbl TIMES_Lk_Yule_Order_Root_Cond(t_tree *tree)
       if(n->tax == NO)
         {
           loglk  += (loglbda - lbda * FABS(t[j]));
-          loglk -= LOG(EXP(-lbda*lower_bound) - EXP(-lbda*upper_bound)); // incorporate calibration boundaries here.    
+          loglk -= log(exp(-lbda*lower_bound) - exp(-lbda*upper_bound)); // incorporate calibration boundaries here.    
         }
 
         if(isinf(loglk) || isnan(loglk))
@@ -1623,8 +1342,8 @@ phydbl TIMES_Lk_Yule_Order_Root_Cond(t_tree *tree)
 
   /* lower_bound = MAX(FABS(tf[tree->n_root->num]),FABS(tp_max[tree->n_root->num])); */
   /* upper_bound = FABS(tp_min[tree->n_root->num]); */
-  /* loglk += LOG(2) + loglbda - 2.*lbda * FABS(t[tree->n_root->num]); */
-  /* loglk -= LOG(EXP(-2.*lbda*lower_bound) - EXP(-2.*lbda*upper_bound)); */
+  /* loglk += log(2) + loglbda - 2.*lbda * FABS(t[tree->n_root->num]); */
+  /* loglk -= log(exp(-2.*lbda*lower_bound) - exp(-2.*lbda*upper_bound)); */
 
 
   return(loglk);
@@ -1632,4 +1351,588 @@ 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 incomplete sampling.
+phydbl TIMES_Lk_Birth_Death(int verbose, t_tree *tree)
+{
+  int i;
+  phydbl lnL;
+  phydbl t,b,d,bmd,logbmd,expmbmd,logb;
+  phydbl bmin,bmax;
+  phydbl dmin,dmax;
+
+  lnL     = 0.0;
+  b       = tree->rates->birth_rate;
+  d       = tree->rates->death_rate;
+  bmin    = tree->rates->birth_rate_min;
+  bmax    = tree->rates->birth_rate_max;
+  dmin    = tree->rates->death_rate_min;
+  dmax    = tree->rates->death_rate_max;
+  bmd     = b-d;
+  logbmd  = -1.;
+  expmbmd = -1.;
+  logb    = -1.;
+  t       = 0.0;
+
+  if(b < d)
+    {
+      if(verbose) printf("\n. b: %G d: %G",b,d);
+      return UNLIKELY;
+    }
+  
+  For(i,2*tree->n_otu-1)
+    if(tree->a_nodes[i]->tax == NO)
+      {
+        if(tree->rates->nd_t[i] < tree->rates->t_prior_min[i] ||
+           tree->rates->nd_t[i] > tree->rates->t_prior_max[i]) 
+          {
+            if(verbose) printf("\n== node %d @ time %f min: %f max: %f",i,tree->rates->nd_t[i],tree->rates->t_prior_min[i],tree->rates->t_prior_max[i]);
+            return UNLIKELY;
+          }
+      }
+  
+  if(b > bmin && d > dmin && Are_Equal(bmd,0.0,bmin/10.) == NO)
+    {
+      logbmd = log(bmd);
+      expmbmd = exp(d-b);
+
+      For(i,2*tree->n_otu-1)
+        if(tree->a_nodes[i]->tax == NO && tree->a_nodes[i] != tree->n_root)
+          {
+            t = FABS(tree->rates->nd_t[i]);            
+            // Equation 3.19 in Tanja Stadler's PhD thesis
+            lnL += 2*logbmd - bmd*t - 2.*log(b-d*POW(expmbmd,t));            
+          }
+
+      t = FABS(tree->rates->nd_t[tree->n_root->num]);
+      lnL += -bmd*t - log(b-d*POW(expmbmd,t));
+
+      lnL += log(bmd) + (tree->n_otu-1)*log(b) + LnGamma(tree->n_otu+1);
+    }
+  else if(b > bmin && d < dmin) // Yule process 
+    {
+      For(i,2*tree->n_otu-1)
+        if(tree->a_nodes[i]->tax == NO && tree->a_nodes[i] != tree->n_root)
+          {
+            t = FABS(tree->rates->nd_t[i]);            
+            // Equation 3.19 in Tanja Stadler's PhD thesis (Yule case)
+            lnL -= b*t;
+          }
+
+      t = FABS(tree->rates->nd_t[tree->n_root->num]);
+      lnL -= b*t;
+      
+      lnL += (tree->n_otu-1)*log(b) + LnGamma(tree->n_otu+1);
+    }
+  else if(b < bmin && d > dmin) 
+    {
+      if(verbose) printf("\n. b: %G bmin: %G d: %G dmin: %G",b,bmin,d,dmin);
+      return UNLIKELY;
+    }
+  else if(Are_Equal(bmd,0.0,bmin/10.) == YES) // Critical birth-death process
+    {
+      logb = log(b);
+
+      For(i,2*tree->n_otu-1)
+        if(tree->a_nodes[i]->tax == NO && tree->a_nodes[i] != tree->n_root)
+          {
+            t = FABS(tree->rates->nd_t[i]);            
+            // Equation 3.19 in Tanja Stadler's PhD thesis (Critical case)
+            lnL += logb - 2.*log(1.+b*t);
+          }
+
+      t = FABS(tree->rates->nd_t[tree->n_root->num]);
+      lnL -= log(b*t);
+
+      lnL += LnGamma(tree->n_otu+1);
+      
+    }
+  else if(b < bmin && d < dmin) // Birth and death rates are below their limits
+    {
+      if(verbose) printf("\n. b: %G bmin: %G d: %G dmin: %G",b,bmin,d,dmin);
+      return -INFINITY;
+    }
+  else if(b > bmax && d > dmax)
+    {
+      if(verbose) printf("\n. b: %G bmax: %G d: %G dmax: %G",b,bmax,d,dmax);
+      return -INFINITY;
+    }
+  else
+    {
+      assert(FALSE);
+    }
+
+  if(isnan(lnL) || isinf(FABS(lnL)))
+    {
+      if(verbose) printf("\n. lnL: %f",lnL);
+      tree->rates->c_lnL_times = UNLIKELY;
+      return UNLIKELY;
+    }
+
+  tree->rates->c_lnL_times = lnL;
+
+
+  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,up,lo;
+  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=0;i<list_size;i++)
+    {
+      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=0;i<list_size;i++)
+    {
+      n = tax_list[i];
+      while(n->v[0] != NULL) n = n->v[0];
+      for(j=0;j<n_anc;j++) 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=0;i<n_anc;i++) 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); */
+  permut = (int *)mCalloc(n_anc,sizeof(int));
+  for(i=0;i<n_anc;i++) permut[i] = i;
+  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;
+      up                     = MIN(times[new_mrca->v[1]->num],times[new_mrca->v[2]->num]);
+      lo                     = up - (up - t_mrca)/10.;
+      times[new_mrca->num]   = Uni()*(up - lo) + lo;
+
+      /* times[new_mrca->num]   = t_upper_bound - ((phydbl)(i+1.)/n_anc)*(t_upper_bound - t_lower_bound); */
+
+
+      /* printf("\n. new_mrca->num: %d time: %f [%f %f] t_mrca: %f %d connect to %d %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[0] ? new_mrca->v[0]->num : -1, */
+      /*        new_mrca->v[1] ? new_mrca->v[1]->num : -1, */
+      /*        new_mrca->v[2] ? new_mrca->v[2]->num : -1, */
+      /*        times[new_mrca->v[1]->num], */
+      /*        times[new_mrca->v[2]->num] */
+      /*        ); */
+      /* fflush(NULL); */
+
+      anc[permut[i+1]] = new_mrca;
+      i++;
+      (*nd_num) += 1;
+      if(n_anc == i+1) { times[new_mrca->num] = t_mrca; break; }
+    }
+  while(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,nd_num,*cal_ordering,n_cal,swap,list_size,tmp,orig_is_mixt_tree,repeat,n_max_repeats,tip_num,*no_cal_tip_num,n_no_cal_tip_num,*permut;
+  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;
+
+  // List node indices that are not in any calibration set
+  no_cal_tip_num = NULL;
+  n_no_cal_tip_num = 0;
+  for(i=0;i<mixt_tree->n_otu;i++)
+    {
+      cal = cal_list;
+      while(cal != NULL)
+        {
+          for(j=0;j<cal->n_target_tax;j++)
+            if(cal->target_tip[j] == mixt_tree->a_nodes[i])
+              break;
+          if(j != cal->n_target_tax) break;
+          cal = cal->next;
+        }
+      if(cal == NULL)
+        {
+          if(n_no_cal_tip_num == 0) no_cal_tip_num = (int *)mCalloc(1,sizeof(int));
+          else no_cal_tip_num = (int *)mRealloc(no_cal_tip_num,n_no_cal_tip_num+1,sizeof(int));
+          no_cal_tip_num[n_no_cal_tip_num] = i;
+          n_no_cal_tip_num++;
+        }
+    }
+  
+  for(repeat=0;repeat<n_max_repeats;repeat++)
+    {
+      nd_num = mixt_tree->n_otu;
+  
+      /* PhyML_Printf("\n\n. Repeat %d",repeat); */
+
+      for(i=0;i<mixt_tree->n_otu;i++) tips[i] = mixt_tree->a_nodes[i];
+      for(i=0;i<mixt_tree->n_otu;i++) 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=0;i<n_cal;i++) cal_ordering[i] = i;
+      
+      // Sort calibration times from youngest to oldest
+      do
+        {
+          swap = NO;
+          for(i=0;i<n_cal-1;i++) 
+            {
+              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=0;i<n_cal-1;i++) assert(cal_times[cal_ordering[i]] > cal_times[cal_ordering[i+1]]);
+              
+      // Connect taxa that appear in every primary calibrations
+      for(i=0;i<n_cal;i++)
+        {
+          cal = cal_list;
+          j = 0;
+          while(j != cal_ordering[i]) 
+            { 
+              if(cal->is_primary == YES) j++; 
+              cal = cal->next; 
+              assert(cal); 
+            }
+          
+          list_size = 0;
+
+
+          // Add some taxa that are not in any calibration set
+          permut = Permutate(n_no_cal_tip_num);
+          j = 0;
+          do
+            {
+              tip_num = no_cal_tip_num[permut[j]];
+              if(tips[tip_num]->v[0] == NULL)
+                {
+                  nd_list[list_size] = tips[tip_num];
+                  /* PhyML_Printf("\n# %s",tips[tip_num]->name); */
+                  list_size++;
+                }
+            }
+          while(j++ < MIN(n_no_cal_tip_num-1,(int)(2*n_no_cal_tip_num/(n_cal))));
+          Free(permut);
+
+          
+
+          // Add all the taxa that are  in the calibration set of cal
+          // This should be done here so that the last node in nd_list
+          // belongs to the taxa in the calibration
+          for(j=0;j<cal->n_target_tax;j++) 
+            {
+              nd_list[list_size] = tips[cal->target_tip[j]->num];
+              /* PhyML_Printf("\n> %s",tips[cal->target_tip[j]->num]->name); */
+              list_size++;
+            }
+                    
+          /* for(j=0;j<n_cal;j++) */
+          /*   { */
+          /*     printf("\n. %d -> %f", */
+          /*            cal_ordering[j], */
+          /*            cal_times[cal_ordering[j]]); */
+          /*     fflush(NULL); */
+          /*   } */
+
+          /* for(j=0;j<list_size;j++) PhyML_Printf("\n. %s [%d]",nd_list[j]->name,nd_list[j]->num); */
+          /* PhyML_Printf("\n. Time: %f [%f %f]\n", */
+          /*              cal_times[cal_ordering[i]], */
+          /*              cal->lower, */
+          /*              cal->upper); */
+          
+          /* for(k=0;k<list_size;k++) printf("\n@ %s",nd_list[k]->name); */
+          /* printf("\n"); */
+
+          TIMES_Connect_List_Of_Taxa(nd_list, 
+                                     list_size,
+                                     cal_times[cal_ordering[i]], 
+                                     times, 
+                                     &nd_num,
+                                     mixt_tree);
+
+        }
+      
+      Free(cal_times);
+      Free(cal_ordering);
+      
+      
+      // Connect all remaining taxa
+      for(i=0;i<mixt_tree->n_otu;i++) nd_list[i] = NULL;
+      list_size = 0;
+      for(i=0;i<mixt_tree->n_otu;i++) 
+        {
+          if(tips[i]->v[0] == NULL) // Tip is not connected yet
+            {
+              nd_list[list_size] = tips[i];
+              list_size++;
+            }
+        }
+
+      cal = cal_list;
+      do
+        {
+          nd_list[list_size] = cal->target_tip[0];
+          list_size++;
+          cal = cal->next;
+        }
+      while(cal);
+
+      /* for(i=0;i<list_size;i++) printf("\n# To connect: %d lower: %f",nd_list[i]->num,time_oldest_cal); */
+      
+      TIMES_Connect_List_Of_Taxa(nd_list,
+                                 list_size,
+                                 1.5*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);
+      
+      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); */
+      /*   fflush(NULL); */
+
+      /*   int i; */
+      /*   for(i=0;i<mixt_tree->rates->n_cal;i++) */
+      /*     { */
+      /*       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))
+        {
+          /* PhyML_Printf("\n. Could not generate tree (DATE_Check_Calibration_Constraints)\n\n"); */
+        }
+      else if(!DATE_Check_Time_Constraints(mixt_tree))
+        {
+          /* PhyML_Printf("\n. Could not generate tree (DATE_Check_Time_Constraints)\n\n"); */
+        }
+      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=0;j<mixt_tree->n_otu;j++) 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);
+          Add_Root(tree->a_edges[tree->prev->e_root->num],tree);
+          Reorganize_Edges_Given_Lk_Struct(tree);
+          Init_Partial_Lk_Tips_Int(tree);
+                   
+          tree = tree->next;
+        }
+      while(tree);
+    }
+  
+  Free(tips);
+  Free(nd_list);
+  Free(no_cal_tip_num);
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+int TIMES_Check_Node_Height_Ordering(t_tree *tree)
+{
+  if(!TIMES_Check_Node_Height_Ordering_Post(tree->n_root,tree->n_root->v[1],tree)) return NO;
+  if(!TIMES_Check_Node_Height_Ordering_Post(tree->n_root,tree->n_root->v[2],tree)) return NO;
+  return YES;
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+int TIMES_Check_Node_Height_Ordering_Post(t_node *a, t_node *d, t_tree *tree)
+{
+
+  if(d->anc != a)
+    {
+      PhyML_Printf("\n== d=%d d->anc=%d a=%d root=%d",d->num,d->anc->num,a->num,tree->n_root->num);
+      return NO;
+    }
+  if(tree->rates->nd_t[d->num] < tree->rates->nd_t[a->num])
+    {
+      PhyML_Printf("\n== a->t = %f [num:%d] d->t %f [num:%d]",
+                   tree->rates->nd_t[a->num],
+                   a->num,
+                   tree->rates->nd_t[d->num],
+                   d->num);
+      return NO;
+    }
+  if(d->tax == YES) return YES;
+  else
+    {
+      int i;
+      for(i=0;i<3;i++)
+        {
+          if(d->v[i] != a && d->b[i] != tree->e_root)
+            if(!TIMES_Check_Node_Height_Ordering_Post(d,d->v[i],tree))
+              return NO;
+        }
+    }
+  return YES;
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
diff --git a/src/times.h b/src/times.h
index 1cd5457..8d5cb3f 100644
--- a/src/times.h
+++ b/src/times.h
@@ -47,7 +47,7 @@ void TIMES_Set_Floor(t_tree *tree);
 void TIMES_Set_Floor_Post(t_node *a, t_node *d, t_tree *tree);
 phydbl TIMES_Log_Conditional_Uniform_Density(t_tree *tree);
 phydbl TIMES_Log_Yule(t_tree *tree);
-phydbl TIMES_Lk_Times(t_tree *tree);
+phydbl TIMES_Lk_Times(int verbose, t_tree *tree);
 void TIMES_Lk_Times_Trav(t_node *a, t_node *d, phydbl lim_inf, phydbl lim_sup, phydbl *logdens, t_tree *tree);
 phydbl TIMES_Log_Number_Of_Ranked_Labelled_Histories(t_node *root, int per_slice, t_tree *tree);
 void TIMES_Log_Number_Of_Ranked_Labelled_Histories_Post(t_node *a, t_node *d, int per_slice, phydbl *logn, t_tree *tree);
@@ -70,5 +70,11 @@ 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(int verbose, t_tree *tree);
+int TIMES_Check_Node_Height_Ordering(t_tree *tree);
+int TIMES_Check_Node_Height_Ordering_Post(t_node *a, t_node *d, t_tree *tree);
+phydbl TIMES_Lk_Birth_Death_One_Node(phydbl t, phydbl min, phydbl max, t_tree *tree);
 
 #endif
diff --git a/src/tiporder.c b/src/tiporder.c
index 1359ddf..da9bf33 100644
--- a/src/tiporder.c
+++ b/src/tiporder.c
@@ -1,7 +1,7 @@
 /*
 
-PhyML:  a program that  computes maximum likelihood phyLOGenies from
-DNA or AA homoLOGous sequences.
+PhyML:  a program that  computes maximum likelihood phylogenies from
+DNA or AA homologous sequences.
 
 Copyright (C) Stephane Guindon. Oct 2003 onward.
 
@@ -69,10 +69,10 @@ the GNU public licence. See http://www.opensource.org for details.
 /*   n_trees = list_io->treelist->list_size; */
 /*   PhyML_Printf("\n. Read %d trees\n",n_trees); */
 
-/*   For(i,n_trees) list_tree[i]->io = list_io; */
+/*   for(i=0;i<n_trees;i++) list_tree[i]->io = list_io; */
 
 /*   name_table = (char **)mCalloc(ref_tree->n_otu,sizeof(char **)); */
-/*   For(i,ref_tree->n_otu) name_table[i] = (char *)mCalloc(T_MAX_NAME,sizeof(char)); */
+/*   for(i=0;i<ref_tree->n_otu;i++) name_table[i] = (char *)mCalloc(T_MAX_NAME,sizeof(char)); */
 
 
 /*   /\* Sort translation table such that tree->a_nodes[i]->name == tree->io->short_tax_name[i] for all i *\/ */
@@ -82,18 +82,18 @@ the GNU public licence. See http://www.opensource.org for details.
 
 /* /\*   TIPO_Read_Taxa_Zscores(fp_coord,ref_tree); *\/ */
 
-/*   For(i,ref_tree->n_otu) ref_tree->io->z_scores[i] = TIPO_Read_One_Taxon_Zscore(fp_coord,ref_tree->a_nodes[i]->name,ref_tree); */
+/*   for(i=0;i<ref_tree->n_otu;i++) ref_tree->io->z_scores[i] = TIPO_Read_One_Taxon_Zscore(fp_coord,ref_tree->a_nodes[i]->name,ref_tree); */
 
 /*   TIPO_Normalize_Zscores(ref_tree); */
 
 /*   /\* Find matching tips *\/ */
-/*   For(i,n_trees) */
+/*   for(i=0;i<n_trees;i++) */
 /*     { */
 /*       TIPO_Sort_Translation_Table(list_tree[i]); */
 
-/*       For(j,ref_tree->n_otu)  */
+/*       for(j=0;j<ref_tree->n_otu;j++)  */
 /* 	{ */
-/* 	  For(k,ref_tree->n_otu)  */
+/* 	  for(k=0;k<ref_tree->n_otu;k++)  */
 /* 	    { */
 /* 	      if(!strcmp(ref_io->long_tax_names[j],list_io->long_tax_names[k])) */
 /* 		{ */
@@ -114,7 +114,7 @@ the GNU public licence. See http://www.opensource.org for details.
 /*   Update_Ancestors(ref_tree->n_root,ref_tree->n_root->v[2],ref_tree); */
 /*   Update_Ancestors(ref_tree->n_root,ref_tree->n_root->v[1],ref_tree); */
 
-/*   For(i,n_trees)    */
+/*   for(i=0;i<n_trees;i++)    */
 /*     { */
 /*       Update_Ancestors(list_tree[i]->n_root,list_tree[i]->n_root->v[2],list_tree[i]); */
 /*       Update_Ancestors(list_tree[i]->n_root,list_tree[i]->n_root->v[1],list_tree[i]); */
@@ -129,7 +129,7 @@ the GNU public licence. See http://www.opensource.org for details.
 /* 	  ref_tree->a_nodes[0]->v[0], */
 /* 	  ref_tree); */
 
-/*   For(i,n_trees)  */
+/*   for(i=0;i<n_trees;i++)  */
 /*     { */
 /*       if(!(i%10)) */
 /*       PhyML_Printf("\n. Getting bipartition for tree %d",i); */
@@ -167,7 +167,7 @@ the GNU public licence. See http://www.opensource.org for details.
 
 /*   ref_tree->ps_tree = DR_Make_Tdraw_Struct(ref_tree); */
 /*   DR_Get_Tree_Coord(ref_tree); */
-/*   For(j,ref_tree->n_otu)  */
+/*   for(j=0;j<ref_tree->n_otu;j++)  */
 /*     { */
 /*       ref_tree->ps_tree->ycoord[j] =  */
 /* 	(ref_tree->a_nodes[j]->y_rank/ref_tree->n_otu)* */
@@ -180,7 +180,7 @@ the GNU public licence. See http://www.opensource.org for details.
 /*   list_io->z_scores = (phydbl *)mCalloc(ref_tree->n_otu,sizeof(phydbl)); */
 
 /*   DR_Print_Postscript_Header(1,ps_tree); */
-/*   For(i,n_trees) */
+/*   for(i=0;i<n_trees;i++) */
 /*     { */
 /*       tree = list_tree[i]; */
 
@@ -197,13 +197,13 @@ the GNU public licence. See http://www.opensource.org for details.
 /*       Dist_To_Root(tree->n_root,tree); */
 /*       tree->ps_tree->max_dist_to_root = DR_Get_Max_Dist_To_Root(tree); */
  
-/*       For(j,ref_tree->n_otu) tree->io->z_scores[j] = ref_tree->io->z_scores[tree->a_nodes[j]->ext_node->num]; */
+/*       for(j=0;j<ref_tree->n_otu;j++) tree->io->z_scores[j] = ref_tree->io->z_scores[tree->a_nodes[j]->ext_node->num]; */
 /*       TIPO_Get_Tips_Y_Rank_From_Zscores(tree); */
 /*       TIPO_Untangle_Tree(tree); */
-/*       For(j,ref_tree->n_otu) tree->ps_tree->ycoord[j] =  (tree->a_nodes[j]->y_rank/tree->n_otu)*tree->ps_tree->page_height; */
+/*       for(j=0;j<ref_tree->n_otu;j++) tree->ps_tree->ycoord[j] =  (tree->a_nodes[j]->y_rank/tree->n_otu)*tree->ps_tree->page_height; */
 
-/* /\*       For(j,ref_tree->n_otu) tree->ps_tree->ycoord[j] = ref_tree->ps_tree->ycoord[tree->a_nodes[j]->ext_node->num]; *\/ */
-/*       For(j,ref_tree->n_otu) list_io->z_scores[j] = ref_io->z_scores[tree->a_nodes[j]->ext_node->num]; */
+/* /\*       for(j=0;j<ref_tree->n_otu;j++) tree->ps_tree->ycoord[j] = ref_tree->ps_tree->ycoord[tree->a_nodes[j]->ext_node->num]; *\/ */
+/*       for(j=0;j<ref_tree->n_otu;j++) list_io->z_scores[j] = ref_io->z_scores[tree->a_nodes[j]->ext_node->num]; */
 
 /*       DR_Get_Y_Coord(YES,tree->ps_tree,tree); */
 /*       DR_Get_X_Coord( NO,tree->ps_tree,tree); */
@@ -231,7 +231,7 @@ the GNU public licence. See http://www.opensource.org for details.
   
 /*   TIPO_Get_Tips_Y_Rank_From_Zscores(tree); */
 /* /\*   TIPO_Untangle_Tree(tree); *\/ */
-/*   For(j,tree->n_otu) tree->ps_tree->ycoord[j] =  (tree->a_nodes[j]->y_rank/tree->n_otu)*tree->ps_tree->page_height; */
+/*   for(j=0;j<tree->n_otu;j++) tree->ps_tree->ycoord[j] =  (tree->a_nodes[j]->y_rank/tree->n_otu)*tree->ps_tree->page_height; */
 
 /*   DR_Get_Y_Coord(YES,tree->ps_tree,tree); */
 /*   DR_Get_X_Coord( NO,tree->ps_tree,tree); */
@@ -272,7 +272,7 @@ int TIPO_main(int argc, char **argv)
 
   tree->io->z_scores = (phydbl *)mCalloc(tree->n_otu,sizeof(phydbl));
 
-  For(i,tree->n_otu) tree->io->z_scores[i] = TIPO_Read_One_Taxon_Zscore(fp_coord_file,tree->a_nodes[i]->name,1,tree);
+  for(i=0;i<tree->n_otu;i++) tree->io->z_scores[i] = TIPO_Read_One_Taxon_Zscore(fp_coord_file,tree->a_nodes[i]->name,1,tree);
   /* TIPO_Normalize_Zscores(tree); */
   Free_Bip(tree);
   Alloc_Bip(tree);
@@ -351,7 +351,7 @@ void TIPO_Get_Tips_Y_Rank_Pre(t_node *a, t_node *d, phydbl *curr_rank, t_tree *t
   else
     {
       int i;
-      For(i,3)
+      for(i=0;i<3;i++)
 	{
 	  if(d->v[i] != a && d->b[i] != tree->e_root)
 	    {
@@ -394,7 +394,7 @@ void TIPO_Get_All_Y_Rank_Pre(t_node *a, t_node *d, t_tree *tree)
       int dir1,dir2;
       phydbl v1,v2;
 
-      For(i,3)
+      for(i=0;i<3;i++)
 	{
 	  if(d->v[i] != a && d->b[i] != tree->e_root)
 	    {
@@ -403,7 +403,7 @@ void TIPO_Get_All_Y_Rank_Pre(t_node *a, t_node *d, t_tree *tree)
 	}
 
       dir1 = dir2 = -1;
-      For(i,3)
+      for(i=0;i<3;i++)
 	{
 	  if(d->v[i] != a && d->b[i] != tree->e_root)
 	    {
@@ -440,7 +440,7 @@ void TIPO_Swap_One_Node(t_node *d, t_tree *tree)
       if(d != tree->n_root)
 	{
 	  dir1 = dir2 = -1;
-	  For(i,3)
+	  for(i=0;i<3;i++)
 	    {
 	      if((d->v[i] != d->anc) && (d->b[i] != tree->e_root))
 		{
@@ -515,9 +515,9 @@ void TIPO_Minimize_Tip_Order_Score(int n_trees, t_tree **list_tree, t_tree *ref_
   node_table = (t_node **)mCalloc(ref_tree->n_otu,sizeof(t_node *));
 
 
-  For(i,ref_tree->n_otu)
+  for(i=0;i<ref_tree->n_otu;i++)
     {
-      For(j,ref_tree->n_otu)
+      for(j=0;j<ref_tree->n_otu;j++)
 	{
 	  if(!strcmp(ref_tree->io->short_tax_names[i],ref_tree->a_nodes[j]->name))
 	    {
@@ -529,13 +529,13 @@ void TIPO_Minimize_Tip_Order_Score(int n_trees, t_tree **list_tree, t_tree *ref_
 	}
     }
 
-  For(i,ref_tree->n_otu) node_table[i] = ref_tree->a_nodes[i];
+  for(i=0;i<ref_tree->n_otu;i++) node_table[i] = ref_tree->a_nodes[i];
 
 /*       bubble sort of conflict nodes according to their y_rank */
   do
     {
       swapped = NO;
-      For(i,ref_tree->n_otu-1)
+      for(i=0;i<ref_tree->n_otu-1;i++)
 	{
 	  if(node_table[i]->y_rank > node_table[i+1]->y_rank)
 	    {
@@ -547,7 +547,7 @@ void TIPO_Minimize_Tip_Order_Score(int n_trees, t_tree **list_tree, t_tree *ref_
 	}
     }while(swapped == YES);
 
-  For(i,ref_tree->n_otu)
+  for(i=0;i<ref_tree->n_otu;i++)
     {
       PhyML_Printf("\n%s",node_table[i]->name,node_table[i]->y_rank);
     }
@@ -584,7 +584,7 @@ void TIPO_Print_Tip_Ordered_Pre(t_node *a, t_node *d, t_tree *tree)
       int i,dir1,dir2;
 
       dir1 = dir2 = -1;
-      For(i,3)
+      for(i=0;i<3;i++)
 	{
 	  if((d->v[i] != a) && (d->b[i] != tree->e_root))
 	    {
@@ -615,10 +615,10 @@ int TIPO_Untangle_Tree_List(int n_trees, t_tree **list_tree, t_tree *ref_tree)
   int tree_score,score;
 
   score = 0;
-  For(i,n_trees) 
+  for(i=0;i<n_trees;i++) 
     {
 /*       PhyML_Printf("\n. Untangling tree %3d",i); */
-      For(j,ref_tree->n_otu) list_tree[i]->a_nodes[j]->y_rank = list_tree[i]->a_nodes[j]->ext_node->y_rank;
+      for(j=0;j<ref_tree->n_otu;j++) list_tree[i]->a_nodes[j]->y_rank = list_tree[i]->a_nodes[j]->ext_node->y_rank;
       tree_score = TIPO_Untangle_Tree(list_tree[i]);
 /*       PhyML_Printf(" score = %3d",tree_score); */
       score += tree_score;
@@ -645,15 +645,15 @@ phydbl TIPO_Untangle_Tree(t_tree *tree)
 
   node_table = (t_node **)mCalloc(tree->n_otu,sizeof(t_node *));
 
-  For(i,tree->n_otu) node_table[i] = tree->a_nodes[i];
-  For(i,tree->n_otu) tree->a_nodes[i]->y_rank_ori = tree->a_nodes[i]->y_rank;
+  for(i=0;i<tree->n_otu;i++) node_table[i] = tree->a_nodes[i];
+  for(i=0;i<tree->n_otu;i++) tree->a_nodes[i]->y_rank_ori = tree->a_nodes[i]->y_rank;
 
 
 /* bubble sort of nodes according to their y_rank */
   do
     {
       swapped = NO;
-      For(i,tree->n_otu-1)
+      for(i=0;i<tree->n_otu-1;i++)
 	{
 	  if(node_table[i]->y_rank > node_table[i+1]->y_rank)
 	    {
@@ -703,7 +703,7 @@ phydbl TIPO_Untangle_Tree(t_tree *tree)
 	  DR_Get_Tree_Box_Width(tree->ps_tree,tree);
 	  Dist_To_Root(tree->n_root,tree);
 	  tree->ps_tree->max_dist_to_root = DR_Get_Max_Dist_To_Root(tree);
-	  For(i,tree->n_otu) tree->ps_tree->ycoord[i] = tree->a_nodes[i]->y_rank * (int)(tree->ps_tree->page_height / (tree->n_otu));
+	  for(i=0;i<tree->n_otu;i++) tree->ps_tree->ycoord[i] = tree->a_nodes[i]->y_rank * (int)(tree->ps_tree->page_height / (tree->n_otu));
 	  DR_Get_X_Coord(NO,tree->ps_tree,tree);
 	  DR_Get_Y_Coord(YES,tree->ps_tree,tree);
 	  DR_Print_Tree_Postscript(1,NO,ps_tree,tree);
@@ -743,7 +743,7 @@ void TIPO_Untangle_Node(t_node *a, t_node *d, t_node **node_table, int *conflict
       d_a = -1;
 
       /* It is a post order traversal */
-      For(i,3)
+      for(i=0;i<3;i++)
 	{
 	  if((d->v[i] != d->anc) && (d->b[i] != tree->e_root))
 	    {
@@ -756,7 +756,7 @@ void TIPO_Untangle_Node(t_node *a, t_node *d, t_node **node_table, int *conflict
       eps = 1.E-10;
 
       /* Find direction fron node d ((d)escendant) to a ((a)ncestor) */
-      For(i,3)
+      for(i=0;i<3;i++)
 	{
 	  if((d->v[i] == d->anc) || (d->b[i] == tree->e_root))
 	    {
@@ -773,7 +773,7 @@ void TIPO_Untangle_Node(t_node *a, t_node *d, t_node **node_table, int *conflict
 
       /* Get the list of tip nodes which ranks are between d->y_rank_min and d->y_rank_max */
       n_conflicts = 0;
-      For(i,tree->n_otu)
+      for(i=0;i<tree->n_otu;i++)
 	{
 	  if((node_table[i]->y_rank > min - eps) && (node_table[i]->y_rank < max + eps))
 	    {
@@ -782,7 +782,7 @@ void TIPO_Untangle_Node(t_node *a, t_node *d, t_node **node_table, int *conflict
 	}
       
       conflict_tips = NULL;
-      For(i,tree->n_otu)
+      for(i=0;i<tree->n_otu;i++)
 	{
 	  if(node_table[i]->y_rank > min - eps)
 	    {
@@ -845,7 +845,7 @@ void TIPO_Untangle_Node(t_node *a, t_node *d, t_node **node_table, int *conflict
 		    }
 		  
 		  /* Have you found lca previously ? */
-		  For(j,n_anc_conflicts) if(anc_conflict[j] == lca) break;
+		  for(j=0;j<n_anc_conflicts;j++) if(anc_conflict[j] == lca) break;
 		  if(j == n_anc_conflicts) /* if no, then update the tree score and the list of ancestral nodes at the origin of conflicts */
 		    {
 		      /* tree->tip_order_score+=1.; */
@@ -920,7 +920,7 @@ void TIPO_Untangle_Node(t_node *a, t_node *d, t_node **node_table, int *conflict
 		    }
 
 /* 		  printf("\n"); */
-/* 		  For(j,n_conflicts) printf("%.0f ",conflict_tips[j]->y_rank); */
+/* 		  for(j=0;j<n_conflicts;j++) printf("%.0f ",conflict_tips[j]->y_rank); */
 /* 		  printf("\n. min=%f max=%f",min,max); */
 /* 		  printf("\n. Node %d has now rank %f",c_node->num,c_node->y_rank); */
 
@@ -934,7 +934,7 @@ void TIPO_Untangle_Node(t_node *a, t_node *d, t_node **node_table, int *conflict
 	}while(n_moved + d->bip_size[d_a] != n_conflicts);
 
 
-      For(i,tree->n_otu)
+      for(i=0;i<tree->n_otu;i++)
 	{
 	  if((tree->a_nodes[i]->y_rank > min - eps) && (tree->a_nodes[i]->y_rank < max + eps))
 	    {
@@ -968,7 +968,7 @@ int TIPO_Check_Tip_Ranks(t_tree *tree)
 
   eps = 1.E-6;
 
-  For(i,tree->n_otu-1)
+  for(i=0;i<tree->n_otu-1;i++)
     {
       for(j=i+1;j<tree->n_otu;j++)
 	{
@@ -1007,7 +1007,7 @@ void TIPO_Read_Taxa_Zscores(FILE *fp_coord, t_tree *tree)
       if(fscanf(fp_coord,"%s\t%lf\n",name,&z) == EOF) break;
       PhyML_Printf("\n. Read %s. Z-score: %f",name,z);
 
-      For(i,tree->n_otu) if(!strcmp(tree->io->long_tax_names[i],name)) break;
+      for(i=0;i<tree->n_otu;i++) if(!strcmp(tree->io->long_tax_names[i],name)) break;
       
       if(i == tree->n_otu)
 	{
@@ -1051,7 +1051,7 @@ void TIPO_Read_Taxa_Coordinates(FILE *fp_coord, t_tree *tree)
       if(fscanf(fp_coord,"%s\t%lf\t%lf\n",name,&lat,&lon) == EOF) break;
       PhyML_Printf("\n. Read %s %f %f",name,lat,lon);
 
-      For(i,tree->n_otu) if(!strcmp(tree->io->long_tax_names[i],name)) break;
+      for(i=0;i<tree->n_otu;i++) if(!strcmp(tree->io->long_tax_names[i],name)) break;
       
       if(i == tree->n_otu)
 	{
@@ -1076,16 +1076,16 @@ void TIPO_Get_Tips_Y_Rank_From_Zscores(t_tree *tree)
 {
   int i;
 
-  For(i,tree->n_otu) tree->a_nodes[i]->y_rank = .0;
+  for(i=0;i<tree->n_otu;i++) tree->a_nodes[i]->y_rank = .0;
 
   /* Randomization in order to avoid ties */
-  For(i,tree->n_otu) tree->io->z_scores[i] += Rnorm(0.0,0.001);
+  for(i=0;i<tree->n_otu;i++) tree->io->z_scores[i] += Rnorm(0.0,0.001);
 
-  For(i,tree->n_otu) tree->a_nodes[i]->y_rank = tree->io->z_scores[i];
+  for(i=0;i<tree->n_otu;i++) tree->a_nodes[i]->y_rank = tree->io->z_scores[i];
 
-/*   For(i,tree->n_otu) tree->a_nodes[i]->y_rank = .0; */
+/*   for(i=0;i<tree->n_otu;i++) tree->a_nodes[i]->y_rank = .0; */
 
-/*   For(i,tree->n_otu-1) */
+/*   for(i=0;i<tree->n_otu-1;i++) */
 /*     { */
 /*       for(j=i+1;j<tree->n_otu;j++) */
 /* 	{ */
@@ -1107,7 +1107,7 @@ void TIPO_Get_Tips_Y_Rank_From_Zscores(t_tree *tree)
 /* 	} */
 /*     } */
 
-/*   For(i,tree->n_otu) printf("- %f\n",tree->a_nodes[i]->y_rank); */
+/*   for(i=0;i<tree->n_otu;i++) printf("- %f\n",tree->a_nodes[i]->y_rank); */
 
 }
 
@@ -1123,7 +1123,7 @@ void  TIPO_Sort_Translation_Table(t_tree *tree)
 
   Test_Node_Table_Consistency(tree);
 
-  For(i,tree->n_otu-1)
+  for(i=0;i<tree->n_otu-1;i++)
     {
       for(j=i+1;j<tree->n_otu;j++)
 	{
@@ -1154,9 +1154,9 @@ void TIPO_Randomize_Tip_Y_Ranks(t_tree *tree)
   phydbl rk_tmp;
   int rnd_node_num;
   
-  For(i,tree->n_otu) tree->a_nodes[i]->y_rank_ori = tree->a_nodes[i]->y_rank;
+  for(i=0;i<tree->n_otu;i++) tree->a_nodes[i]->y_rank_ori = tree->a_nodes[i]->y_rank;
 
-  For(i,tree->n_otu)
+  for(i=0;i<tree->n_otu;i++)
     {
       rnd_node_num = Rand_Int(0,tree->n_otu-1);
 
@@ -1230,7 +1230,7 @@ void TIPO_Normalize_Zscores(t_tree *tree)
   eps = 1.E-10;
 
   min_z = FLT_MAX;
-  For(i,tree->n_otu)
+  for(i=0;i<tree->n_otu;i++)
     {
       if(tree->io->z_scores[i] < min_z)
 	{
@@ -1239,7 +1239,7 @@ void TIPO_Normalize_Zscores(t_tree *tree)
     }
   
   max_z = -FLT_MAX;
-  For(i,tree->n_otu)
+  for(i=0;i<tree->n_otu;i++)
     {
       if(tree->io->z_scores[i] > max_z)
 	{
@@ -1247,7 +1247,7 @@ void TIPO_Normalize_Zscores(t_tree *tree)
 	}
     }
 
-  For(i,tree->n_otu) tree->io->z_scores[i] = (tree->io->z_scores[i] - min_z)/(max_z-min_z+eps); 
+  for(i=0;i<tree->n_otu;i++) tree->io->z_scores[i] = (tree->io->z_scores[i] - min_z)/(max_z-min_z+eps); 
 
 }
 
@@ -1274,7 +1274,7 @@ phydbl TIPO_Lk_Post(t_node *a, t_node *d, t_tree *tree)
     {
       int i;
 
-      For(i,3)
+      for(i=0;i<3;i++)
 	{
 	  if(d->v[i] != a && d->b[i] != tree->e_root)
 	    {
@@ -1314,7 +1314,7 @@ phydbl TIPO_Lk_Core(t_node *a, t_node *d, t_tree *tree)
   else
     {
       d_v1 = d_v2 = -1;
-      For(i,3)
+      for(i=0;i<3;i++)
 	{
 	  if(d->v[i] != a && d->b[i] != tree->e_root)
 	    {
@@ -1330,7 +1330,7 @@ phydbl TIPO_Lk_Core(t_node *a, t_node *d, t_tree *tree)
   v1_d = v2_d = -1;
   if(d == tree->n_root)
     {
-      For(i,3)
+      for(i=0;i<3;i++)
 	{
 	  if(v1->b[i] == tree->e_root) v1_d = i;
 	  if(v2->b[i] == tree->e_root) v2_d = i;
@@ -1338,7 +1338,7 @@ phydbl TIPO_Lk_Core(t_node *a, t_node *d, t_tree *tree)
     }
   else
     {
-      For(i,3)
+      for(i=0;i<3;i++)
 	{
 	  if(v1->v[i] == d) v1_d = i;
 	  if(v2->v[i] == d) v2_d = i;
@@ -1369,7 +1369,7 @@ phydbl TIPO_Lk_Core(t_node *a, t_node *d, t_tree *tree)
   /* 	 min_dist,Dnorm(dist,0.0,tree->geo_mig_sd)); */
 
   /* dens = Dnorm(min_dist,0.0,tree->geo_mig_sd); */
-  tree->geo_lnL += LOG(dens);
+  tree->geo_lnL += log(dens);
 
   return tree->geo_lnL;
 }
diff --git a/src/utilities.c b/src/utilities.c
index 7ea9267..688ec0d 100644
--- a/src/utilities.c
+++ b/src/utilities.c
@@ -20,6 +20,7 @@ the GNU public licence. See http://www.opensource.org for details.
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
+
 phydbl String_To_Dbl(char *string)
 {
   phydbl buff;
@@ -49,24 +50,24 @@ void Unroot_Tree(char **subtrees)
   char **tmp_sub;
   int degree,i,j;
 
-  PhyML_Printf("\n. Removing the root...\n");
+  PhyML_Printf("\n\u2022 Removing the root...\n");
 
   tmp_sub = Sub_Trees(subtrees[0],&degree);
   if(degree >= 2)
     {
       strcpy(subtrees[2],subtrees[1]);
       Clean_Multifurcation(tmp_sub,degree,2);
-      For(j,2) strcpy(subtrees[j],tmp_sub[j]);
+      for(j=0;j<2;j++) strcpy(subtrees[j],tmp_sub[j]);
     }
   else
     {
       tmp_sub = Sub_Trees(subtrees[1],&degree);
       strcpy(subtrees[2],subtrees[0]);
       Clean_Multifurcation(tmp_sub,degree,2);
-      For(j,2) strcpy(subtrees[j],tmp_sub[j]);
+      for(j=0;j<2;j++) strcpy(subtrees[j],tmp_sub[j]);
     }
 
-  For(i,degree) Free(tmp_sub[i]);
+  for(i=0;i<degree;i++) Free(tmp_sub[i]);
   Free(tmp_sub);
 }
 
@@ -79,18 +80,18 @@ void Set_Edge_Dirs(t_edge *b, t_node *a, t_node *d, t_tree *tree)
 
   if(a == b->rght)
     {
-      PhyML_Printf("\n== a->num = %3d ; d->num = %3d",a->num,d->num);
+      PhyML_Printf("\n== a->num = %d ; d->num = %d",a->num,d->num);
       Generic_Exit(__FILE__,__LINE__,__FUNCTION__);    
     }
 
   if(d == b->left)
     {
-      PhyML_Printf("\n== a->num = %3d ; d->num = %3d",a->num,d->num);
+      PhyML_Printf("\n== a->num = %d ; d->num = %d",a->num,d->num);
       Generic_Exit(__FILE__,__LINE__,__FUNCTION__);    
     }
 
   b->l_r = b->r_l = -1;
-  For(i,3)
+  for(i=0;i<3;i++)
     {
       /* if((a->v[i]) && ((a->v[i] == d) || (e_root && a->b[i] == e_root))) */
       if((a->v[i]) && ((a->v[i] == d)))
@@ -101,15 +102,15 @@ void Set_Edge_Dirs(t_edge *b, t_node *a, t_node *d, t_tree *tree)
       /* if((d->v[i]) && ((d->v[i] == a) || (e_root && d->b[i] == e_root))) */
       if((d->v[i]) && ((d->v[i] == a)))
         {
-          b->r_l  = i; /* we consider here that 'd' is on the right handside of 'b'*/
+          b->r_l = i; /* we consider here that 'd' is on the right handside of 'b'*/
           d->b[i] = b;
         }
     }
 
-  if(a->tax) {b->r_l = 0; For(i,3) if(d->v[i]==a) {b->l_r = i; break;}}
+  if(a->tax) {b->r_l = 0; for(i=0;i<3;i++) if(d->v[i]==a) {b->l_r = i; break;}}
 
   b->l_v1 = b->l_v2 = b->r_v1 = b->r_v2 = -1;
-  For(i,3)
+  for(i=0;i<3;i++)
     {
       if(b->left->v[i] != b->rght)
         {
@@ -128,12 +129,6 @@ void Set_Edge_Dirs(t_edge *b, t_node *a, t_node *d, t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
 
 void Restrict_To_Coding_Position(align **data, option *io)
 {
@@ -141,7 +136,7 @@ void Restrict_To_Coding_Position(align **data, option *io)
 
   if(io->codpos != -1)
     {
-      For(i,io->n_otu)
+      for(i=0;i<io->n_otu;i++)
     {
       curr_pos = 0;
       for(j=io->codpos-1;j<data[i]->len;j+=3)
@@ -179,28 +174,33 @@ 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;
   which_patt = 0;
 
   sp_names = (char **)mCalloc(n_otu,sizeof(char *));
-  For(i,n_otu)
+  for(i=0;i<n_otu;i++)
     {
       sp_names[i] = (char *)mCalloc(T_MAX_NAME,sizeof(char));
       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);
 
-  For(i,n_otu) Free(sp_names[i]);
+  proot = (pnode *)Create_Pnode(T_MAX_ALPHABET);
+
+  for(i=0;i<n_otu;i++) Free(sp_names[i]);
   Free(sp_names);
 
   if(data[0]->len%io->state_len)
@@ -209,24 +209,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;
-          For(j,n_otu) if(Is_Ambigu(data[j]->state+site,io->datatype,io->state_len)) break;
+          is_ambigu = NO;
+          for(j=0;j<n_otu;j++) 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++;
             }
         }
@@ -255,14 +276,14 @@ calign *Compact_Data(align **data, option *io)
           
           if(k == n_patt) /* add a new site pattern */
             {
-              For(j,n_otu)
+              for(j=0;j<n_otu;j++)
                 Copy_One_State(data[j]->state+site,
                                cdata_tmp->c_seq[j]->state+n_patt*io->state_len,
                                io->state_len);
               
-              For(i,n_otu)
+              for(i=0;i<n_otu;i++)
                 {
-                  For(j,n_otu)
+                  for(j=0;j<n_otu;j++)
                     {
                       if(!(Are_Compatible(cdata_tmp->c_seq[i]->state+n_patt*io->state_len,
                                           cdata_tmp->c_seq[j]->state+n_patt*io->state_len,
@@ -275,7 +296,7 @@ calign *Compact_Data(align **data, option *io)
               if((j == n_otu) && (i == n_otu)) /* all characters at that site are compatible with one another:
                                                   the site may be invariant */
                 {
-                  For(j,n_otu)
+                  for(j=0;j<n_otu;j++)
                     {
                       cdata_tmp->invar[n_patt] = Assign_State(cdata_tmp->c_seq[j]->state+n_patt*io->state_len,
                                                               io->datatype,
@@ -287,13 +308,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;
             }
         }
     }
@@ -302,49 +323,43 @@ calign *Compact_Data(align **data, option *io)
   
   cdata_tmp->init_len                   = data[0]->len;
   cdata_tmp->crunch_len                 = n_patt;
-  For(i,n_otu) cdata_tmp->c_seq[i]->len = n_patt;
+  for(i=0;i<n_otu;i++) cdata_tmp->c_seq[i]->len = n_patt;
+  for(i=0;i<n_otu;i++) cdata_tmp->c_seq[i]->num = i;
   
-  if(!io->quiet) PhyML_Printf("\n. %d patterns found (out of a total of %d sites). \n",n_patt,data[0]->len);
+  if(!io->quiet) PhyML_Printf("\n\u2022 %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\u2022 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=0;i<cdata_tmp->crunch_len;i++) 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\u2022 %d sites without polymorphism (%.2f%c).\n",(int)n_invar,100.*(phydbl)n_invar/len,'%');
+      else
+        PhyML_Printf("\n\u2022 %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,13 +379,13 @@ 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));
 
   cdata->crunch_len = cdata->init_len = -1;
-  For(j,n_otu)
+  for(j=0;j<n_otu;j++)
     {
       cdata->c_seq[j]            = (align *)mCalloc(1,sizeof(align));
       cdata->c_seq[j]->name      = (char *)mCalloc(T_MAX_NAME,sizeof(char));
@@ -383,13 +398,13 @@ calign *Compact_Cdata(calign *data, option *io)
 
   n_patt = which_patt =  0;
 
-  For(site,data->crunch_len)
+  for(site=0;site<data->crunch_len;site++)
     {
-      if(data->wght[site])
+      if(data->wght[site] > 0.0)
         {
-          For(k,n_patt)
+          for(k=0;k<n_patt;k++)
             {
-              For(j,n_otu)
+              for(j=0;j<n_otu;j++)
                 {
                   if(strncmp(cdata->c_seq[j]->state+k*io->state_len,
                              data->c_seq[j]->state+site*io->state_len,
@@ -403,19 +418,16 @@ 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,
+              for(j=0;j<n_otu;j++) Copy_One_State(data->c_seq[j]->state+site*io->state_len,
                                           cdata->c_seq[j]->state+n_patt*io->state_len,
                                           io->state_len);
               
-              For(i,n_otu)
+              for(i=0;i<n_otu;i++)
                 {
-                  For(j,n_otu)
+                  for(j=0;j<n_otu;j++)
                     {
                       if(!(Are_Compatible(cdata->c_seq[i]->state+n_patt*io->state_len,
                                           cdata->c_seq[j]->state+n_patt*io->state_len,
@@ -427,7 +439,7 @@ calign *Compact_Cdata(calign *data, option *io)
               
               if((j == n_otu) && (i == n_otu))
                 {
-                  For(j,n_otu)
+                  for(j=0;j<n_otu;j++)
                     {
                       cdata->invar[n_patt] = Assign_State(cdata->c_seq[j]->state+n_patt*io->state_len,
                                                           io->datatype,
@@ -449,7 +461,7 @@ calign *Compact_Cdata(calign *data, option *io)
   
   cdata->init_len   = data->crunch_len;
   cdata->crunch_len = n_patt;
-  For(i,n_otu) cdata->c_seq[i]->len = n_patt;
+  for(i=0;i<n_otu;i++) cdata->c_seq[i]->len = n_patt;
 
   if(io->datatype == NT)      Get_Base_Freqs(cdata);
   else if(io->datatype == AA) Get_AA_Freqs(cdata);
@@ -499,7 +511,7 @@ pnode *Create_Pnode(int size)
 
   n = (pnode *)mCalloc(1,sizeof(pnode ));
   n->next = (pnode **)mCalloc(size,sizeof(pnode *));
-  For(i,size) n->next[i] = NULL;
+  for(i=0;i<size;i++) n->next[i] = NULL;
   n->weight = 0;
   n->num = -1;
   return n;
@@ -510,71 +522,70 @@ 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;
 
-  For(k,8)
+  for(k=0;k<8;k++)
     {
       A = C = G = T = .0;
-      For(i,data->n_otu)
-    {
-      For(j,data->crunch_len)
+      for(i=0;i<data->n_otu;i++)
         {
-          w = data->wght[j];
-          if(w)
-        {
-          switch(data->c_seq[i]->state[j])
+          for(j=0;j<data->crunch_len;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;
+              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;
@@ -584,7 +595,6 @@ void Get_Base_Freqs(calign *data)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Get_AA_Freqs(calign *data)
 {
   int i,j,k;
@@ -596,68 +606,68 @@ void Get_AA_Freqs(calign *data)
   fA = fC = fD = fE = fF = fG = fH = fI = fK = fL =
   fM = fN = fP = fQ = fR = fS = fT = fV = fW = fY = 1./20.;
 
-  For(k,8)
+  for(k=0;k<8;k++)
     {
       A = C = D = E = F = G = H = I = K = L =
-      M = N = P = Q = R = S = T = V = W = Y = .0;
-
-      For(i,data->n_otu)
-    {
-      For(j,data->crunch_len)
-        {
-          w = data->wght[j];
-          if(w)
+        M = N = P = Q = R = S = T = V = W = Y = .0;
+      
+      for(i=0;i<data->n_otu;i++)
         {
-          switch(data->c_seq[i]->state[j])
+          for(j=0;j<data->crunch_len;j++)
             {
-            case 'A' : A+=w;		break;
-            case 'C' : C+=w;		break;
-            case 'D' : D+=w;		break;
-            case 'E' : E+=w;		break;
-            case 'F' : F+=w;		break;
-            case 'G' : G+=w;		break;
-            case 'H' : H+=w;		break;
-            case 'I' : I+=w;		break;
-            case 'K' : K+=w;		break;
-            case 'L' : L+=w;		break;
-            case 'M' : M+=w;		break;
-            case 'N' : N+=w;		break;
-            case 'P' : P+=w;		break;
-            case 'Q' : Q+=w;		break;
-            case 'R' : R+=w;		break;
-            case 'S' : S+=w;		break;
-            case 'T' : T+=w;		break;
-            case 'V' : V+=w;		break;
-            case 'W' : W+=w;		break;
-            case 'Y' : Y+=w;		break;
-            case 'Z' : Q+=w;		break;
-            case 'X' : case '?' : case 'O' : case '-' :
-              A+=w*fA;
-              C+=w*fC;
-              D+=w*fD;
-              E+=w*fE;
-              F+=w*fF;
-              G+=w*fG;
-              H+=w*fH;
-              I+=w*fI;
-              K+=w*fK;
-              L+=w*fL;
-              M+=w*fM;
-              N+=w*fN;
-              P+=w*fP;
-              Q+=w*fQ;
-              R+=w*fR;
-              S+=w*fS;
-              T+=w*fT;
-              V+=w*fV;
-              W+=w*fW;
-              Y+=w*fY;
-              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 'D' : D+=w;		break;
+                    case 'E' : E+=w;		break;
+                    case 'F' : F+=w;		break;
+                    case 'G' : G+=w;		break;
+                    case 'H' : H+=w;		break;
+                    case 'I' : I+=w;		break;
+                    case 'K' : K+=w;		break;
+                    case 'L' : L+=w;		break;
+                    case 'M' : M+=w;		break;
+                    case 'N' : N+=w;		break;
+                    case 'P' : P+=w;		break;
+                    case 'Q' : Q+=w;		break;
+                    case 'R' : R+=w;		break;
+                    case 'S' : S+=w;		break;
+                    case 'T' : T+=w;		break;
+                    case 'V' : V+=w;		break;
+                    case 'W' : W+=w;		break;
+                    case 'Y' : Y+=w;		break;
+                    case 'Z' : Q+=w;		break;
+                    case 'X' : case '?' : case 'O' : case '-' :
+                      A+=w*fA;
+                      C+=w*fC;
+                      D+=w*fD;
+                      E+=w*fE;
+                      F+=w*fF;
+                      G+=w*fG;
+                      H+=w*fH;
+                      I+=w*fI;
+                      K+=w*fK;
+                      L+=w*fL;
+                      M+=w*fM;
+                      N+=w*fN;
+                      P+=w*fP;
+                      Q+=w*fQ;
+                      R+=w*fR;
+                      S+=w*fS;
+                      T+=w*fT;
+                      V+=w*fV;
+                      W+=w*fW;
+                      Y+=w*fY;
+                      break;
+                    default : break;
+                    }
+                }
             }
         }
-        }
-    }
       sum = (A+C+D+E+F+G+H+I+K+L+M+N+P+Q+R+S+T+V+W+Y);
       fA = A/sum;      fC = C/sum;      fD = D/sum;      fE = E/sum;
       fF = F/sum;      fG = G/sum;      fH = H/sum;      fI = I/sum;
@@ -665,19 +675,17 @@ void Get_AA_Freqs(calign *data)
       fP = P/sum;      fQ = Q/sum;      fR = R/sum;      fS = S/sum;
       fT = T/sum;      fV = V/sum;      fW = W/sum;      fY = Y/sum;
     }
-
+  
   data->b_frq[0]  = fA;  data->b_frq[1]  = fR;  data->b_frq[2]  = fN;  data->b_frq[3]  = fD;
   data->b_frq[4]  = fC;  data->b_frq[5]  = fQ;  data->b_frq[6]  = fE;  data->b_frq[7]  = fG;
   data->b_frq[8]  = fH;  data->b_frq[9]  = fI;  data->b_frq[10] = fL;  data->b_frq[11] = fK;
   data->b_frq[12] = fM;  data->b_frq[13] = fF;  data->b_frq[14] = fP;  data->b_frq[15] = fS;
-  data->b_frq[16] = fT;  data->b_frq[17] = fW;  data->b_frq[18] = fY;  data->b_frq[19] = fV;
-
+  data->b_frq[16] = fT;  data->b_frq[17] = fW;  data->b_frq[18] = fY;  data->b_frq[19] = fV; 
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 // 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
@@ -692,7 +700,7 @@ void Swap_Nodes_On_Edges(t_edge *e1, t_edge *e2, int swap, t_tree *tree)
   e2->left->l[e2->l_r] = e2->l->v;
   e2->rght->l[e2->r_l] = e2->l->v;
 
-  printf("\n. Swap edge %d (%d %d) with %d (%d %d)",e1->num,e1->left->num,e1->rght->num,e2->num,e2->left->num,e2->rght->num);
+  printf("\n\u2022 Swap edge %d (%d %d) with %d (%d %d)",e1->num,e1->left->num,e1->rght->num,e2->num,e2->left->num,e2->rght->num);
 
   if(swap == NO)
     {
@@ -723,18 +731,18 @@ 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)
 {
   int i,j;
 
   /* Reset */
-  For(i,2*tree->n_otu-1) For(j,3) tree->a_nodes[i]->b[j] = NULL;
+  For(i,2*tree->n_otu-1) for(j=0;j<3;j++) tree->a_nodes[i]->b[j] = NULL;
 
   tree->num_curr_branch_available = 0;
   
-  For(i,tree->n_otu)
+  for(i=0;i<tree->n_otu;i++)
     {
       if(!tree->a_nodes[i]->tax) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
 
@@ -749,7 +757,7 @@ void Connect_Edges_To_Nodes_Serial(t_tree *tree)
     {
       if(tree->a_nodes[i] == tree->n_root) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
 
-      For(j,3) 
+      for(j=0;j<3;j++) 
         if(!tree->a_nodes[i]->b[j])
           Connect_One_Edge_To_Two_Nodes(tree->a_nodes[i],
                                         tree->a_nodes[i]->v[j],
@@ -769,7 +777,7 @@ void Connect_Edges_To_Nodes_Recur(t_node *a, t_node *d, t_tree *tree)
 
   if(d->tax) return;
   else 
-    For(i,3) 
+    for(i=0;i<3;i++) 
       if(d->v[i] != a) /* Don't add d->b[i] != tree->e_root condition here since tree is not wired yet... */ 
         Connect_Edges_To_Nodes_Recur(d,d->v[i],tree);
 }
@@ -781,11 +789,17 @@ void Connect_One_Edge_To_Two_Nodes(t_node *a, t_node *d, t_edge *b, t_tree *tree
 {
   int i,dir_a_d,dir_d_a;
     
+  if(a == NULL || d == NULL) 
+    {
+      PhyML_Printf("\n\u2022 a: %d d: %d",a?a->num:-1,d?d->num:-1);
+      Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
+    }
+
   dir_a_d = -1;
-  For(i,3) if(a->v[i] == d) {dir_a_d = i; break;}
+  for(i=0;i<3;i++) if(a->v[i] == d) { dir_a_d = i; break; }
 
   dir_d_a = -1;
-  For(i,3) if(d->v[i] == a) {dir_d_a = i; break;}
+  for(i=0;i<3;i++) if(d->v[i] == a) { dir_d_a = i; break; }
 
   if(dir_a_d == -1) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); 
   if(dir_d_a == -1) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);    
@@ -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;
@@ -1134,7 +1147,7 @@ char *Add_Taxa_To_Constraint_Tree(FILE *fp, calign *cdata)
 {
   char *line,*long_line;
   t_tree *tree;
-  int i,j;
+  int i,j,open;
 
   rewind(fp);
 
@@ -1143,12 +1156,20 @@ char *Add_Taxa_To_Constraint_Tree(FILE *fp, calign *cdata)
 
   long_line = (char *)mCalloc(T_MAX_LINE,sizeof(char));
   strcpy(long_line,line);
-
-  long_line[strlen(line)-1] = '\0';
-
-  For(i,cdata->n_otu)
+  i = 1;
+  open = 1;
+  while(open)
+    {
+      if(line[i]=='(') open++;
+      if(line[i]==')') open--;      
+      if(i > T_MAX_LINE) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
+      i++;
+    }
+  long_line[i-1] = '\0';
+  
+  for(i=0;i<cdata->n_otu;i++)
     {
-      For(j,tree->n_otu)
+      for(j=0;j<tree->n_otu;j++)
         {
           if(!strcmp(tree->a_nodes[j]->name,cdata->c_seq[i]->name))
             break;
@@ -1181,9 +1202,9 @@ void Check_Constraint_Tree_Taxa_Names(t_tree *tree, calign *cdata)
   n_otu_tree  = tree->n_otu;
   n_otu_cdata = cdata->n_otu;
 
-  For(i,n_otu_tree)
+  for(i=0;i<n_otu_tree;i++)
     {
-      For(j,n_otu_cdata)
+      for(j=0;j<n_otu_cdata;j++)
     {
       if(!strcmp(tree->a_nodes[i]->name,cdata->c_seq[j]->name))
         break;
@@ -1191,7 +1212,7 @@ void Check_Constraint_Tree_Taxa_Names(t_tree *tree, calign *cdata)
 
       if(j==n_otu_cdata)
     {
-      PhyML_Printf("\n. '%s' was not found in sequence data set\n",tree->a_nodes[i]->name);
+      PhyML_Printf("\n\u2022 '%s' was not found in sequence data set\n",tree->a_nodes[i]->name);
       Warn_And_Exit("");
     }
     }
@@ -1204,7 +1225,7 @@ void Copy_Tax_Names_To_Tip_Labels(t_tree *tree, calign *data)
 {
   int i;
 
-  For(i,tree->n_otu)
+  for(i=0;i<tree->n_otu;i++)
     {
       tree->a_nodes[i]->name = (char *)mCalloc((int)strlen(data->c_seq[i]->name)+1,sizeof(char));
       tree->a_nodes[i]->ori_name = tree->a_nodes[i]->name;
@@ -1232,13 +1253,18 @@ void Share_Lk_Struct(t_tree *t_full, t_tree *t_empt)
   t_empt->log_lks_aLRT         = t_full->log_lks_aLRT;
   t_empt->site_lk_cat          = t_full->site_lk_cat;
   t_empt->fact_sum_scale       = t_full->fact_sum_scale;
+  t_empt->eigen_lr_left        = t_full->eigen_lr_left;
+  t_empt->eigen_lr_rght        = t_full->eigen_lr_rght;
+  t_empt->dot_prod             = t_full->dot_prod;
+  t_empt->expl                 = t_full->expl;
 
   For(i,2*n_otu-3)
     {
       b_f = t_full->a_edges[i];
       b_e = t_empt->a_edges[i];
 
-      b_e->Pij_rr = b_f->Pij_rr;
+      b_e->Pij_rr  = b_f->Pij_rr;
+      b_e->tPij_rr = b_f->tPij_rr;
 
       b_e->nni = b_f->nni;
     }
@@ -1249,7 +1275,7 @@ void Share_Lk_Struct(t_tree *t_full, t_tree *t_empt)
       n_f = t_full->a_nodes[i];
       n_e = t_empt->a_nodes[i];
 
-      For(j,3)
+      for(j=0;j<3;j++)
     {
       if(n_f->b[j]->left == n_f)
         {
@@ -1296,7 +1322,7 @@ void Share_Lk_Struct(t_tree *t_full, t_tree *t_empt)
     }
     }
 
-  For(i,n_otu)
+  for(i=0;i<n_otu;i++)
     {
       n_f = t_full->a_nodes[i];
       n_e = t_empt->a_nodes[i];
@@ -1330,7 +1356,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,25 +1379,30 @@ 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;
+  int i,j,done;
   t_edge *buff;
 
-  For(i,n_elem-1)
-    {
-      for(j=i+1;j<n_elem;j++)
+  do
     {
-      if(sorted_edges[j]->nni->score  < sorted_edges[i]->nni->score)
+      done = YES;
+      for(i=0;i<n_elem-1;i++)
         {
-          buff = sorted_edges[j];
-          sorted_edges[j] = sorted_edges[i];
-          sorted_edges[i] = buff;
+          for(j=i+1;j<n_elem;j++)
+            {
+              if(sorted_edges[j]->nni->score  < sorted_edges[i]->nni->score)
+                {
+                  done = NO;
+                  buff = sorted_edges[j];
+                  sorted_edges[j] = sorted_edges[i];
+                  sorted_edges[i] = buff;
+                }
+            }
         }
     }
-    }
+  while(done == NO);
+
   return 1;
 }
 
@@ -1387,13 +1417,13 @@ int Sort_Edges_Depth(t_tree *tree, t_edge **sorted_edges, int n_elem)
 
   depth = (phydbl *)mCalloc(n_elem,sizeof(phydbl));
 
-  For(i,n_elem)
+  for(i=0;i<n_elem;i++)
     depth[i] =
     sorted_edges[i]->left->bip_size[sorted_edges[i]->l_r] *
     sorted_edges[i]->rght->bip_size[sorted_edges[i]->r_l] ;
 
 
-  For(i,n_elem-1)
+  for(i=0;i<n_elem-1;i++)
     {
       for(j=i+1;j<n_elem;j++)
     {
@@ -1423,35 +1453,34 @@ 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];
-  v3                     = b_fcus->rght->v[b_fcus->r_v1];
-  v4                     = b_fcus->rght->v[b_fcus->r_v2];
+  v1 = b_fcus->left->v[b_fcus->l_v1];
+  v2 = b_fcus->left->v[b_fcus->l_v2];
+  v3 = b_fcus->rght->v[b_fcus->r_v1];
+  v4 = b_fcus->rght->v[b_fcus->r_v2];
 
   Record_Br_Len(tree);
 
-  if(v1->num < v2->num) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);    
+  if(v1->num < v2->num) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
   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);
 
@@ -1459,17 +1488,20 @@ void NNI(t_tree *tree, t_edge *b_fcus, int do_swap)
   lk1_init = Update_Lk_At_Given_Edge(b_fcus,tree);
   MIXT_Set_Alias_Subpatt(NO,tree);
 
-  l_infa = 10.;
-  l_infb = tree->mod->l_min/b_fcus->l->v;
+  l_infa = 1.;
+  l_infb = 1.E-4;
+  lk1    = lk1_init;
 
-  if(tree->mod->s_opt->fast_nni)
+  if(tree->mod->s_opt->nni_br_len_opt == YES)
     {
-      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(tree->mod->s_opt->fast_nni)
+        {
+          lk1 = Fast_Br_Len(b_fcus,tree,YES);
+        }
+      else 
+        {
+          lk1 = Br_Len_Brent(b_fcus,tree);
+        }
     }
 
   if(lk1 < lk1_init - tree->mod->s_opt->min_diff_lk_local)
@@ -1479,13 +1511,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);
@@ -1494,17 +1526,21 @@ void NNI(t_tree *tree, t_edge *b_fcus, int do_swap)
   lk2_init = Update_Lk_At_Given_Edge(b_fcus,tree);
   MIXT_Set_Alias_Subpatt(NO,tree);
 
-  l_infa = 10.;
-  l_infb = tree->mod->l_min/b_fcus->l->v;
+  l_infa = 1.;
+  l_infb = 1.E-4;
+ 
+  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)
+        {
+          lk2 = Fast_Br_Len(b_fcus,tree,YES);
+        }
+      else 
+        {
+          lk2 = Br_Len_Brent(b_fcus,tree);
+        }
     }
 
   if(lk2 < lk2_init - tree->mod->s_opt->min_diff_lk_local)
@@ -1514,14 +1550,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 +1565,32 @@ 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;
+  l_infa = 1.;
+  l_infb = 1.E-4;
+  lk0    = lk0_init;
 
-  if(tree->mod->s_opt->fast_nni)
+  if(tree->mod->s_opt->nni_br_len_opt == YES)
     {
-      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(tree->mod->s_opt->fast_nni)
+        {
+          lk0 = Fast_Br_Len(b_fcus,tree,YES);
+        }
+      else 
+        {
+          lk0 = Br_Len_Brent(b_fcus,tree);
+        }
     }
 
   if(lk0 < lk_init - tree->mod->s_opt->min_diff_lk_local)
@@ -1561,25 +1601,31 @@ 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_fcus->nni->score = lk0 - MAX(lk1,lk2);
 
@@ -1598,18 +1644,12 @@ 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);
     }
   else if(lk1 > MAX(lk0,lk2))
     {
@@ -1618,18 +1658,12 @@ 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);
     }
   else if(lk2 > MAX(lk0,lk1))
     {
@@ -1639,18 +1673,11 @@ 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);
     }
   else
     {
@@ -1661,61 +1688,41 @@ 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);
     }
 
-  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);
-
-          Set_Both_Sides(YES,tree);
-      Lk(NULL,tree);
-    }
-      else
-    {
-      tree->best_lnL = lk2;
-      Swap(v2,b_fcus->left,b_fcus->rght,v4,tree);
+          tree->n_swap++;
 
-      b = b_fcus;
-      i = 0;
-      do
-        {
-          b->l->v = l2[i];
-              b = b->next;
-          i++;
+          if(lk1 > lk2)
+            {
+              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);
+            }
+          else
+            {
+              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);
+            }
         }
-      while(b);
-
-          Set_Both_Sides(YES,tree);
-      Lk(NULL,tree);
-    }
     }
   else
     {
@@ -1724,9 +1731,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);
+
 }
 
 //////////////////////////////////////////////////////////////
@@ -1777,10 +1788,10 @@ void NNI_Pars(t_tree *tree, t_edge *b_fcus, int do_swap)
 
   if(pars0 != pars_init)
      {
-       PhyML_Printf("\n. pars_init = %d; pars0 = %d\n",
+       PhyML_Printf("\n\u2022 pars_init = %d; pars0 = %d\n",
           pars_init,
           pars0);
-       Warn_And_Exit("\n. Err. in NNI (3)\n");
+       Warn_And_Exit("\n\u2022 Err. in NNI (3)\n");
      }
    /***********/
 
@@ -1834,138 +1845,107 @@ 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
    */
 
   if(!tree) return;
 
-#ifdef DEBUG
   if(!a || !b || !c || !d) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);    
-#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
+  
+  for(i=0;i<3;i++) if(a->v[i] == b) { ab = i; break; }
+  for(i=0;i<3;i++) if(b->v[i] == a) { ba = i; break; }
+  for(i=0;i<3;i++) if(c->v[i] == d) { cd = i; break; }
+  for(i=0;i<3;i++) if(d->v[i] == c) { dc = i; break; }
+  for(i=0;i<3;i++) if(b->v[i] == c) { bc = i; break; }
+  
   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== ab=%d ba=%d cd=%d dc=%d bc=%d",ab,ba,cd,dc,bc);
+      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;
   b->v[ba] = d;
   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);
-
-  For(i,3)
+    (d->b[dc]->left = b):
+    (d->b[dc]->rght = b);
+  
+  for(i=0;i<3;i++)
     {
       if(a->b[ab]->left->v[i] == a->b[ab]->rght) a->b[ab]->l_r = i;
       if(a->b[ab]->rght->v[i] == a->b[ab]->left) a->b[ab]->r_l = i;
       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;
-
-  For(i,3)
+  
+  for(i=0;i<3;i++)
     {
       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->next)
-    Swap(a->next,b->next,c->next,d->next,tree->next);
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-void Update_All_Partial_Lk(t_edge *b_fcus, t_tree *tree)
-{
-
-  Update_SubTree_Partial_Lk(b_fcus->left->b[b_fcus->l_v1],
-                b_fcus->left,
-                b_fcus->left->v[b_fcus->l_v1],
-                tree);
-
-  Update_SubTree_Partial_Lk(b_fcus->left->b[b_fcus->l_v2],
-                b_fcus->left,
-                b_fcus->left->v[b_fcus->l_v2],
-                tree);
-
-  Update_SubTree_Partial_Lk(b_fcus->rght->b[b_fcus->r_v1],
-                b_fcus->rght,
-                b_fcus->rght->v[b_fcus->r_v1],
-                tree);
-
-  Update_SubTree_Partial_Lk(b_fcus->rght->b[b_fcus->r_v2],
-                b_fcus->rght,
-                b_fcus->rght->v[b_fcus->r_v2],
-                tree);
-
-  tree->c_lnL = Lk(b_fcus,tree);
 
+  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) Update_All_Partial_Lk(tree->next->a_edges[b_fcus->num],
-                       tree->next);
+  if(tree->next)
+    Swap(a->next,b->next,c->next,d->next,tree->next);
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Update_SubTree_Partial_Lk(t_edge *b_fcus, t_node *a, t_node *d, t_tree *tree)
 {
   int i;
-
-  Update_P_Lk(tree,b_fcus,a);
+  Update_Partial_Lk(tree,b_fcus,a);
   if(d->tax) return;
-  else For(i,3) if(d->v[i] != a)
-    Update_SubTree_Partial_Lk(d->b[i],d,d->v[i],tree);
+  else for(i=0;i<3;++i) if(d->v[i] != a) Update_SubTree_Partial_Lk(d->b[i],d,d->v[i],tree);
 }
 
 //////////////////////////////////////////////////////////////
@@ -1974,10 +1954,7 @@ void Update_SubTree_Partial_Lk(t_edge *b_fcus, t_node *a, t_node *d, t_tree *tre
 void Copy_Seq_Names_To_Tip_Labels(t_tree *tree, calign *data)
 {
   int i;
-  For(i,tree->n_otu)
-    {
-      strcpy(tree->a_nodes[i]->name,data->c_seq[i]->name);
-    }
+  for(i=0;i<tree->n_otu;++i) strcpy(tree->a_nodes[i]->name,data->c_seq[i]->name);
 }
 
 //////////////////////////////////////////////////////////////
@@ -1992,25 +1969,27 @@ 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)
+  for(i=0;i<n_otu;i++)
     {
       sp_names[i] = (char *)mCalloc(strlen(ori->c_seq[i]->name)+1,sizeof(char));
       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;
 
-  For(i,ori->init_len) new->sitepatt[i] = ori->sitepatt[i];
+  for(i=0;i<n_otu;i++) new->c_seq[i]->num = ori->c_seq[i]->num;
 
-  For(j,ori->crunch_len)
+  for(i=0;i<ori->init_len;i++) new->sitepatt[i] = ori->sitepatt[i];
+
+  for(j=0;j<ori->crunch_len;j++)
     {
-      For(i,ori->n_otu)
+      for(i=0;i<ori->n_otu;i++)
         {
-          For(k,io->state_len)
+          for(k=0;k<io->state_len;k++)
             {
               new->c_seq[i]->state[j*io->state_len+k] =
                 ori->c_seq[i]->state[j*io->state_len+k];
@@ -2023,15 +2002,15 @@ calign *Copy_Cseq(calign *ori, option *io)
       new->invar[j]  = ori->invar[j];
     }
   
-  For(i,ori->n_otu)
+  for(i=0;i<ori->n_otu;i++)
     {
       new->c_seq[i]->len = ori->c_seq[i]->len;
       strcpy(new->c_seq[i]->name,ori->c_seq[i]->name);
     }
   
-  For(i,ori->n_otu) new->c_seq[i]->state[c_len*io->state_len] = '\0';
+  for(i=0;i<ori->n_otu;i++) new->c_seq[i]->state[c_len*io->state_len] = '\0';
 
-  For(i,T_MAX_ALPHABET) new->b_frq[i] = ori->b_frq[i];
+  for(i=0;i<T_MAX_ALPHABET;i++) new->b_frq[i] = ori->b_frq[i];
 
   new->init_len           = ori->init_len;
   new->clean_len          = ori->clean_len;
@@ -2039,7 +2018,7 @@ calign *Copy_Cseq(calign *ori, option *io)
   new->n_otu              = ori->n_otu;
   new->io                 = ori->io;
 
-  For(i,n_otu) Free(sp_names[i]);
+  for(i=0;i<n_otu;i++) Free(sp_names[i]);
   Free(sp_names);
 
   return new;
@@ -2071,7 +2050,7 @@ matrix *K80_dist(calign *data, phydbl g_shape)
   phydbl **len;
 
   len = (phydbl **)mCalloc(data->n_otu,sizeof(phydbl *));
-  For(i,data->n_otu)
+  for(i=0;i<data->n_otu;i++)
     len[i] = (phydbl *)mCalloc(data->n_otu,sizeof(phydbl));
 
   mat = Make_Mat(data->n_otu);
@@ -2082,7 +2061,7 @@ matrix *K80_dist(calign *data, phydbl g_shape)
   
   For(i,data->c_seq[0]->len)
     {
-      For(j,data->n_otu-1)
+      for(j=0;j<data->n_otu-1;j++)
         {
           for(k=j+1;k<data->n_otu;k++)
             {
@@ -2126,7 +2105,7 @@ matrix *K80_dist(calign *data, phydbl g_shape)
     }
   
   
-  For(i,data->n_otu-1)
+  for(i=0;i<data->n_otu-1;i++)
     for(j=i+1;j<data->n_otu;j++)
       {
     if(len[i][j] > .0)
@@ -2160,7 +2139,7 @@ matrix *K80_dist(calign *data, phydbl g_shape)
     mat->dist[j][i] = mat->dist[i][j];
       }
 
-  For(i,data->n_otu) free(len[i]);
+  for(i=0;i<data->n_otu;i++) free(len[i]);
   free(len);
   return mat;
 }
@@ -2178,7 +2157,7 @@ matrix *JC69_Dist(calign *data, t_mod *mod)
 
 
   len = (phydbl **)mCalloc(data->n_otu,sizeof(phydbl *));
-  For(i,data->n_otu)
+  for(i=0;i<data->n_otu;i++)
     len[i] = (phydbl *)mCalloc(data->n_otu,sizeof(phydbl));
 
   mat = Make_Mat(data->n_otu);
@@ -2188,7 +2167,7 @@ matrix *JC69_Dist(calign *data, t_mod *mod)
 
   For(site,data->c_seq[0]->len)
     {
-      For(j,data->n_otu-1)
+      for(j=0;j<data->n_otu-1;j++)
     {
       for(k=j+1;k<data->n_otu;k++)
         {
@@ -2212,7 +2191,7 @@ matrix *JC69_Dist(calign *data, t_mod *mod)
     }
 
 
-  For(i,data->n_otu-1)
+  for(i=0;i<data->n_otu-1;i++)
     for(j=i+1;j<data->n_otu;j++)
       {
     if(len[i][j] > .0) mat->P[i][j] /= len[i][j];
@@ -2222,9 +2201,9 @@ matrix *JC69_Dist(calign *data, t_mod *mod)
 
     if((1.-(mod->ns)/(mod->ns-1.)*mat->P[i][j]) < .0) mat->dist[i][j] = -1.;
     else
-      mat->dist[i][j] = -(mod->ns-1.)/(mod->ns)*(phydbl)LOG(1.-(mod->ns)/(mod->ns-1.)*mat->P[i][j]);
+      mat->dist[i][j] = -(mod->ns-1.)/(mod->ns)*(phydbl)log(1.-(mod->ns)/(mod->ns-1.)*mat->P[i][j]);
 
-/* 	PhyML_Printf("\n. Incorrect JC distances"); */
+/* 	PhyML_Printf("\n\u2022 Incorrect JC distances"); */
 /* 	mat->dist[i][j] = len[i][j]; */
 
     if(mat->dist[i][j] > DIST_MAX) mat->dist[i][j] = DIST_MAX;
@@ -2232,7 +2211,7 @@ matrix *JC69_Dist(calign *data, t_mod *mod)
     mat->dist[j][i] = mat->dist[i][j];
       }
 
-  For(i,data->n_otu) free(len[i]);
+  for(i=0;i<data->n_otu;i++) free(len[i]);
   free(len);
 
   return mat;
@@ -2250,7 +2229,7 @@ matrix *Hamming_Dist(calign *data, t_mod *mod)
   int datatype;
 
   len = (phydbl **)mCalloc(data->n_otu,sizeof(phydbl *));
-  For(i,data->n_otu)
+  for(i=0;i<data->n_otu;i++)
     len[i] = (phydbl *)mCalloc(data->n_otu,sizeof(phydbl));
 
   mat = Make_Mat(data->n_otu);
@@ -2258,9 +2237,9 @@ matrix *Hamming_Dist(calign *data, t_mod *mod)
 
   datatype = mod->io->datatype;
 
-  For(i,data->crunch_len)
+  for(i=0;i<data->crunch_len;i++)
     {
-      For(j,data->n_otu-1)
+      for(j=0;j<data->n_otu-1;j++)
     {
       for(k=j+1;k<data->n_otu;k++)
         {
@@ -2282,7 +2261,7 @@ matrix *Hamming_Dist(calign *data, t_mod *mod)
     }
     }
 
-  For(i,data->n_otu-1)
+  for(i=0;i<data->n_otu-1;i++)
     for(j=i+1;j<data->n_otu;j++)
       {
     if(len[i][j] > .0)
@@ -2306,7 +2285,7 @@ matrix *Hamming_Dist(calign *data, t_mod *mod)
     mat->dist[j][i] = mat->dist[i][j];
       }
 
-  For(i,data->n_otu) free(len[i]);
+  for(i=0;i<data->n_otu;i++) free(len[i]);
   free(len);
 
   return mat;
@@ -2321,9 +2300,9 @@ int Is_Invar(int patt_num, int stepsize, int datatype, calign *data)
 {
   int i, j;
 
-  For(i,data->n_otu)
+  for(i=0;i<data->n_otu;i++)
     {
-      For(j,data->n_otu)
+      for(j=0;j<data->n_otu;j++)
     {
       if(!(Are_Compatible(data->c_seq[i]->state+patt_num,
                   data->c_seq[j]->state+patt_num,
@@ -2344,7 +2323,6 @@ int Is_Invar(int patt_num, int stepsize, int datatype, calign *data)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 int Is_Ambigu(char *state, int datatype, int stepsize)
 {
   int val,i;
@@ -2352,7 +2330,7 @@ int Is_Ambigu(char *state, int datatype, int stepsize)
   val = -1;
   if(datatype == NT)
     {
-      For(i,stepsize)
+      for(i=0;i<stepsize;i++)
         {
           switch(state[i])
             {
@@ -2373,7 +2351,7 @@ int Is_Ambigu(char *state, int datatype, int stepsize)
   else if(datatype == GENERIC)
     {
       int i;
-      For(i,stepsize) if(!isdigit(state[i])) break;
+      for(i=0;i<stepsize;i++) if(!isdigit(state[i])) break;
       if(i == stepsize) val = NO;
       else              val = YES;
     }
@@ -2388,15 +2366,15 @@ void Check_Ambiguities(calign *data, int datatype, int stepsize)
 {
   int i,j;
 
-  For(j,data->crunch_len)
+  for(j=0;j<data->crunch_len;j++)
     {
       data->ambigu[j] = NO;
-      For(i,data->n_otu)
+      for(i=0;i<data->n_otu;i++)
         {
           data->c_seq[i]->is_ambigu[j] = NO;
         }
       
-      For(i,data->n_otu)
+      for(i=0;i<data->n_otu;i++)
         {
           if(Is_Ambigu(data->c_seq[i]->state+j*stepsize,
                        datatype,
@@ -2416,9 +2394,9 @@ void Set_D_States(calign *data, int datatype, int stepsize)
 {
   int i,j;
 
-  For(j,data->crunch_len)
+  for(j=0;j<data->crunch_len;j++)
     {
-      For(i,data->n_otu)
+      for(i=0;i<data->n_otu;i++)
         {
           if(data->c_seq[i]->is_ambigu[j] == NO)
             {
@@ -2445,8 +2423,8 @@ int Get_State_From_Ui(int ui, int datatype)
     case 8 : {return 3; break;}
     default :
       {
-        PhyML_Printf("\n. ui=%d",ui);
-        PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__);
+        PhyML_Printf("\n\u2022 ui=%d",ui);
+        PhyML_Printf("\n\u2022 Err in file %s at line %d\n",__FILE__,__LINE__);
         Warn_And_Exit("");
         break;
       }
@@ -2478,8 +2456,8 @@ int Get_State_From_Ui(int ui, int datatype)
     case 524288 : {return 19; break;}
     default :
       {
-        PhyML_Printf("\n. ui=%d",ui);
-        PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__);
+        PhyML_Printf("\n\u2022 ui=%d",ui);
+        PhyML_Printf("\n\u2022 Err in file %s at line %d\n",__FILE__,__LINE__);
         Warn_And_Exit("");
       }
     }
@@ -2500,7 +2478,7 @@ int Assign_State(char *c, int datatype, int stepsize)
   state[0] = state[1] = state[2] = -1;
   if(datatype == NT)
     {
-      For(i,stepsize)
+      for(i=0;i<stepsize;i++)
         {
           switch(c[i])
             {
@@ -2580,8 +2558,8 @@ char Reciproc_Assign_State(int i_state, int datatype)
         case 3 :   {return 'T';  break;}
         default  :
           {
-            PhyML_Printf("\n. i_state = %d",i_state);
-            PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__);
+            PhyML_Printf("\n\u2022 i_state = %d",i_state);
+            PhyML_Printf("\n\u2022 Err in file %s at line %d\n",__FILE__,__LINE__);
             Warn_And_Exit("");
             break;
           }
@@ -2639,7 +2617,7 @@ int Assign_State_With_Ambiguity(char *c, int datatype, int stepsize)
   state[0] = state[1] = state[2] = -1;
   if(datatype == NT)
     {
-      For(i,stepsize)
+      for(i=0;i<stepsize;i++)
         {
           switch(c[i])
             {
@@ -2728,7 +2706,6 @@ int Assign_State_With_Ambiguity(char *c, int datatype, int stepsize)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Clean_Tree_Connections(t_tree *tree)
 {
 
@@ -2747,7 +2724,6 @@ void Clean_Tree_Connections(t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Bootstrap(t_tree *tree)
 {
   int *site_num, n_site;
@@ -2760,6 +2736,13 @@ void Bootstrap(t_tree *tree)
   char *s;
 /*   phydbl rf; */
 
+
+  if(tree->is_mixt_tree == YES)
+    {
+      PhyML_Printf("\n== Bootstrap option not yet available for partition/mixture analysis.");
+      Generic_Exit(__FILE__,__LINE__,__FUNCTION__);    
+    }
+
   tree->print_boot_val = 1;
   tree->print_alrt_val = 0;
   boot_tree            = NULL;
@@ -2771,7 +2754,7 @@ void Bootstrap(t_tree *tree)
   Get_Bip(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree);
 
   n_site = 0;
-  For(j,tree->data->crunch_len) For(k,tree->data->wght[j])
+  for(j=0;j<tree->data->crunch_len;j++) For(k,tree->data->wght[j])
     {
       site_num[n_site] = j;
       n_site++;
@@ -2779,15 +2762,15 @@ void Bootstrap(t_tree *tree)
 
   boot_data = Copy_Cseq(tree->data,tree->io);
 
-  PhyML_Printf("\n\n. Non parametric bootstrap analysis \n\n");
+  PhyML_Printf("\n\n\u2022 Non parametric bootstrap analysis \n\n");
   PhyML_Printf("  [");
 
-  For(replicate,tree->mod->bootstrap)
+  for(replicate=0;replicate<tree->mod->bootstrap;replicate++)
     {
-      For(j,boot_data->crunch_len) boot_data->wght[j] = 0;
+      for(j=0;j<boot_data->crunch_len;j++) boot_data->wght[j] = 0;
 
       init_len = 0;
-      For(j,boot_data->init_len)
+      for(j=0;j<boot_data->init_len;j++)
         {
           position = Rand_Int(0,(int)(tree->data->init_len-1.0));
           boot_data->wght[site_num[position]] += 1;
@@ -2797,7 +2780,7 @@ void Bootstrap(t_tree *tree)
       if(init_len != tree->data->init_len) Exit("\n== Pb. when copying sequences\n");
 
       init_len = 0;
-      For(j,boot_data->crunch_len) init_len += boot_data->wght[j];
+      for(j=0;j<boot_data->crunch_len;j++) init_len += boot_data->wght[j];
 
       if(init_len != tree->data->init_len) Exit("\n== Pb. when copying sequences\n");
 
@@ -2834,34 +2817,32 @@ 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->verbose              = VL0;
+      /* boot_tree->verbose              = VL3; */
+      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);
 
       if((boot_tree->mod->s_opt->random_input_tree) && (boot_tree->mod->s_opt->topo_search == SPR_MOVE)) Random_Tree(boot_tree);
 
       Connect_CSeqs_To_Nodes(boot_data,tree->io,boot_tree);
-
       Check_Br_Lens(boot_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);
-      else                         Init_P_Lk_Tips_Int(boot_tree);
+      Init_Partial_Lk_Tips_Double(boot_tree);
       Init_Ui_Tips(boot_tree);
-      Init_P_Pars_Tips(boot_tree);
+      Init_Partial_Pars_Tips(boot_tree);
       Br_Len_Not_Involving_Invar(boot_tree);
 
       if(boot_tree->io->do_alias_subpatt)
@@ -2870,8 +2851,11 @@ void Bootstrap(t_tree *tree)
           Lk(NULL,boot_tree);
           MIXT_Set_Alias_Subpatt(NO,boot_tree);
         }
-      
-      
+
+      Switch_Eigen(YES,boot_tree->mod);                 
+      Lk(NULL,boot_tree);
+      Switch_Eigen(NO,boot_tree->mod);
+
       if(boot_tree->mod->s_opt->opt_topo)
         {
           if(boot_tree->mod->s_opt->topo_search == NNI_MOVE)
@@ -2887,7 +2871,7 @@ void Bootstrap(t_tree *tree)
       else
         {
           if(boot_tree->mod->s_opt->opt_subst_param || boot_tree->mod->s_opt->opt_bl)
-            Round_Optimize(boot_tree,boot_tree->data,ROUND_MAX);
+            Round_Optimize(boot_tree,ROUND_MAX);
           else
             Lk(NULL,boot_tree);
         }
@@ -2899,8 +2883,8 @@ void Bootstrap(t_tree *tree)
       Match_Tip_Numbers(tree,boot_tree);
 
       Get_Bip(boot_tree->a_nodes[0],
-          boot_tree->a_nodes[0]->v[0],
-          boot_tree);
+              boot_tree->a_nodes[0]->v[0],
+              boot_tree);
 
       Compare_Bip(tree,boot_tree,NO);
 
@@ -2920,7 +2904,7 @@ void Bootstrap(t_tree *tree)
       /* 	rf += tree->a_edges[j]->bip_score; */
 
 
-      PhyML_Printf(".");
+      PhyML_Printf("\u2022");
 #ifndef QUIET
       fflush(stdout);
 #endif
@@ -2944,7 +2928,7 @@ void Bootstrap(t_tree *tree)
       fclose(tree->io->fp_out_boot_stats);
     }
 
-  Free_Cseq(boot_data);
+  Free_Calign(boot_data);
   Free(site_num);
 }
 
@@ -3005,7 +2989,7 @@ phydbl Num_Derivatives_One_Param(phydbl (*func)(t_tree *tree), t_tree *tree,
   sign = (phydbl *)mCalloc(n_param,sizeof(phydbl));
 
   a = (phydbl **)mCalloc(11,sizeof(phydbl *));
-  For(i,11) a[i] = (phydbl *)mCalloc(11,sizeof(phydbl));
+  for(i=0;i<11;i++) a[i] = (phydbl *)mCalloc(11,sizeof(phydbl));
 
   n_iter = 10; /* */
 
@@ -3019,14 +3003,14 @@ phydbl Num_Derivatives_One_Param(phydbl (*func)(t_tree *tree), t_tree *tree,
     {
       param[which]   = param[which]+hh;
 
-      if(logt == YES) For(i,n_param) param[i] = EXP(MIN(1.E+2,param[i]));
-      For(i,n_param) sign[i] = param[i] > .0 ? 1. : -1.;
-      if(is_positive == YES) For(i,n_param) param[i] = FABS(param[i]);
+      if(logt == YES) for(i=0;i<n_param;i++) param[i] = exp(MIN(1.E+2,param[i]));
+      for(i=0;i<n_param;i++) sign[i] = param[i] > .0 ? 1. : -1.;
+      if(is_positive == YES) for(i=0;i<n_param;i++) param[i] = FABS(param[i]);
       a[0][0]  = (*func)(tree);
-      if(is_positive == YES) For(i,n_param) param[i] *= sign[i];
-      if(logt == YES) For(i,n_param) param[i] = LOG(param[i]);
+      if(is_positive == YES) for(i=0;i<n_param;i++) param[i] *= sign[i];
+      if(logt == YES) for(i=0;i<n_param;i++) param[i] = log(param[i]);
 
-      /* printf("\n. f0=%f f1=%f hh=%G %f",f0,a[0][0],hh,param[which]); */
+      /* printf("\n\u2022 f0=%f f1=%f hh=%G %f",f0,a[0][0],hh,param[which]); */
 
       a[0][0]  -= f0;
       a[0][0]  /= hh;
@@ -3038,12 +3022,12 @@ phydbl Num_Derivatives_One_Param(phydbl (*func)(t_tree *tree), t_tree *tree,
     {
       param[which]   = param[which]+hh;
 
-      if(logt == YES) For(i,n_param) param[i] = EXP(MIN(1.E+2,param[i]));
-      For(i,n_param) sign[i] = param[i] > .0 ? 1. : -1.;
-      if(is_positive == YES) For(i,n_param) param[i] = FABS(param[i]);
+      if(logt == YES) for(i=0;i<n_param;i++) param[i] = exp(MIN(1.E+2,param[i]));
+      for(i=0;i<n_param;i++) sign[i] = param[i] > .0 ? 1. : -1.;
+      if(is_positive == YES) for(i=0;i<n_param;i++) param[i] = FABS(param[i]);
       a[0][0]  = (*func)(tree);
-      if(is_positive == YES) For(i,n_param) param[i] *= sign[i];
-      if(logt == YES) For(i,n_param) param[i] = LOG(param[i]);
+      if(is_positive == YES) for(i=0;i<n_param;i++) param[i] *= sign[i];
+      if(logt == YES) for(i=0;i<n_param;i++) param[i] = log(param[i]);
 
       /*   param[which]   = param[which]-2*hh; */
       /*   a[0][0] -= (*func)(tree); */
@@ -3067,12 +3051,12 @@ phydbl Num_Derivatives_One_Param(phydbl (*func)(t_tree *tree), t_tree *tree,
           
           param[which]   = param[which]+hh;
           
-          if(logt == YES) For(j,n_param) param[j] = EXP(MIN(1.E+2,param[j]));
-          For(i,n_param) sign[i] = param[i] > .0 ? 1. : -1.;
-          if(is_positive == YES) For(i,n_param) param[i] = FABS(param[i]);
+          if(logt == YES) for(j=0;j<n_param;j++) param[j] = exp(MIN(1.E+2,param[j]));
+          for(i=0;i<n_param;i++) sign[i] = param[i] > .0 ? 1. : -1.;
+          if(is_positive == YES) for(i=0;i<n_param;i++) param[i] = FABS(param[i]);
           a[0][i]  = (*func)(tree);
-          if(is_positive == YES) For(i,n_param) param[i] *= sign[i];
-          if(logt == YES) For(j,n_param) param[j] = LOG(param[j]);
+          if(is_positive == YES) for(i=0;i<n_param;i++) param[i] *= sign[i];
+          if(logt == YES) for(j=0;j<n_param;j++) param[j] = log(param[j]);
           
           /*   param[which]   = param[which]-2*hh; */
           /*   a[0][i] -= (*func)(tree); */
@@ -3101,7 +3085,7 @@ phydbl Num_Derivatives_One_Param(phydbl (*func)(t_tree *tree), t_tree *tree,
           if(FABS(a[i][i]-a[i-1][i-1]) >= 2.0*(*err)) break;
         }
     }
-  For(i,11) Free(a[i]);
+  for(i=0;i<11;i++) Free(a[i]);
   Free(a);
   Free(sign);
   
@@ -3122,7 +3106,7 @@ phydbl Num_Derivatives_One_Param_Nonaligned(phydbl (*func)(t_tree *tree), t_tree
   sign = (phydbl *)mCalloc(n_param,sizeof(phydbl));
 
   a = (phydbl **)mCalloc(11,sizeof(phydbl *));
-  For(i,11) a[i] = (phydbl *)mCalloc(11,sizeof(phydbl));
+  for(i=0;i<11;i++) a[i] = (phydbl *)mCalloc(11,sizeof(phydbl));
 
   n_iter = 10; /* */
 
@@ -3136,14 +3120,14 @@ phydbl Num_Derivatives_One_Param_Nonaligned(phydbl (*func)(t_tree *tree), t_tree
     {
       *(param[which])   = *(param[which])+hh;
 
-      if(logt == YES) For(i,n_param) *(param[i]) = EXP(MIN(1.E+2,*(param[i])));
-      For(i,n_param) sign[i] = (*(param[i])) > .0 ? 1. : -1.;
-      if(is_positive == YES) For(i,n_param) (*(param[i])) = FABS(*(param[i]));
+      if(logt == YES) for(i=0;i<n_param;i++) *(param[i]) = exp(MIN(1.E+2,*(param[i])));
+      for(i=0;i<n_param;i++) sign[i] = (*(param[i])) > .0 ? 1. : -1.;
+      if(is_positive == YES) for(i=0;i<n_param;i++) (*(param[i])) = FABS(*(param[i]));
       a[0][0]  = (*func)(tree);
-      if(is_positive == YES) For(i,n_param) (*(param[i])) *= sign[i];
-      if(logt == YES) For(i,n_param) *(param[i]) = LOG(*(param[i]));
+      if(is_positive == YES) for(i=0;i<n_param;i++) (*(param[i])) *= sign[i];
+      if(logt == YES) for(i=0;i<n_param;i++) *(param[i]) = log(*(param[i]));
 
-      /* printf("\n. f0=%f f1=%f hh=%G %f",f0,a[0][0],hh,*(param[which])); */
+      /* printf("\n\u2022 f0=%f f1=%f hh=%G %f",f0,a[0][0],hh,*(param[which])); */
 
       a[0][0]  -= f0;
       a[0][0]  /= hh;
@@ -3155,12 +3139,12 @@ phydbl Num_Derivatives_One_Param_Nonaligned(phydbl (*func)(t_tree *tree), t_tree
     {
       *(param[which])   = *(param[which])+hh;
 
-      if(logt == YES) For(i,n_param) *(param[i]) = EXP(MIN(1.E+2,*(param[i])));
-      For(i,n_param) sign[i] = (*(param[i])) > .0 ? 1. : -1.;
-      if(is_positive == YES) For(i,n_param) (*(param[i])) = FABS(*(param[i]));
+      if(logt == YES) for(i=0;i<n_param;i++) *(param[i]) = exp(MIN(1.E+2,*(param[i])));
+      for(i=0;i<n_param;i++) sign[i] = (*(param[i])) > .0 ? 1. : -1.;
+      if(is_positive == YES) for(i=0;i<n_param;i++) (*(param[i])) = FABS(*(param[i]));
       a[0][0]  = (*func)(tree);
-      if(is_positive == YES) For(i,n_param) (*(param[i])) *= sign[i];
-      if(logt == YES) For(i,n_param) *(param[i]) = LOG(*(param[i]));
+      if(is_positive == YES) for(i=0;i<n_param;i++) (*(param[i])) *= sign[i];
+      if(logt == YES) for(i=0;i<n_param;i++) *(param[i]) = log(*(param[i]));
 
       /*   *(param[which]   = *(param[which]-2*hh; */
       /*   a[0][0] -= (*func)(tree); */
@@ -3184,12 +3168,12 @@ phydbl Num_Derivatives_One_Param_Nonaligned(phydbl (*func)(t_tree *tree), t_tree
 
       *(param[which])   = *(param[which])+hh;
 
-          if(logt == YES) For(j,n_param) *(param[j]) = EXP(MIN(1.E+2,*(param[j])));
-          For(i,n_param) sign[i] = (*(param[i])) > .0 ? 1. : -1.;
-          if(is_positive == YES) For(i,n_param) (*(param[i])) = FABS(*(param[i]));
+          if(logt == YES) for(j=0;j<n_param;j++) *(param[j]) = exp(MIN(1.E+2,*(param[j])));
+          for(i=0;i<n_param;i++) sign[i] = (*(param[i])) > .0 ? 1. : -1.;
+          if(is_positive == YES) for(i=0;i<n_param;i++) (*(param[i])) = FABS(*(param[i]));
       a[0][i]  = (*func)(tree);
-          if(is_positive == YES) For(i,n_param) (*(param[i])) *= sign[i];
-          if(logt == YES) For(j,n_param) *(param[j]) = LOG(*(param[j]));
+          if(is_positive == YES) for(i=0;i<n_param;i++) (*(param[i])) *= sign[i];
+          if(logt == YES) for(j=0;j<n_param;j++) *(param[j]) = log(*(param[j]));
 
       /*   *(param[which]   = *(param[which]-2*hh; */
       /*   a[0][i] -= (*func)(tree); */
@@ -3218,7 +3202,7 @@ phydbl Num_Derivatives_One_Param_Nonaligned(phydbl (*func)(t_tree *tree), t_tree
       if(FABS(a[i][i]-a[i-1][i-1]) >= 2.0*(*err)) break;
     }
     }
-  For(i,11) Free(a[i]);
+  for(i=0;i<11;i++) Free(a[i]);
   Free(a);
   Free(sign);
   return ans;
@@ -3235,16 +3219,16 @@ int Num_Derivative_Several_Param(t_tree *tree, phydbl *param, int n_param, phydb
 
   sign = (phydbl *)mCalloc(n_param,sizeof(phydbl));
 
-  if(logt == YES)   For(i,n_param) param[i] = EXP(MIN(1.E+2,param[i]));
-  For(i,n_param) sign[i] = (param[i]) > .0 ? 1. : -1.;
-  if(is_positive == YES) For(i,n_param) param[i] = FABS(param[i]);
+  if(logt == YES)   for(i=0;i<n_param;i++) param[i] = exp(MIN(1.E+2,param[i]));
+  for(i=0;i<n_param;i++) sign[i] = (param[i]) > .0 ? 1. : -1.;
+  if(is_positive == YES) for(i=0;i<n_param;i++) param[i] = FABS(param[i]);
   f0 = (*func)(tree);
-  if(is_positive == YES) For(i,n_param) param[i] *= sign[i];
-  if(logt == YES)   For(i,n_param) param[i] = LOG(param[i]);
+  if(is_positive == YES) for(i=0;i<n_param;i++) param[i] *= sign[i];
+  if(logt == YES)   for(i=0;i<n_param;i++) param[i] = log(param[i]);
 
-  For(i,n_param)
+  for(i=0;i<n_param;i++)
     {
-      /* For(j,tree->mod->r_mat->n_diff_rr) PhyML_Printf("\n. 00%d %f",i,tree->mod->r_mat->rr_val->v[j]); */
+      /* for(j=0;j<tree->mod->r_mat->n_diff_rr;j++) PhyML_Printf("\n\u2022 00%d %f",i,tree->mod->r_mat->rr_val->v[j]); */
       derivatives[i] = Num_Derivatives_One_Param(func,
                                                  tree,
                                                  f0,
@@ -3275,15 +3259,15 @@ int Num_Derivative_Several_Param_Nonaligned(t_tree *tree, phydbl **param, int n_
 
   sign = (phydbl *)mCalloc(n_param,sizeof(phydbl));
 
-  if(logt == YES)   For(i,n_param) (*(param[i])) = EXP(MIN(1.E+2,*(param[i])));
-  For(i,n_param) sign[i] = (*(param[i])) > .0 ? 1. : -1.;
-  if(is_positive == YES) For(i,n_param) *(param[i]) = FABS(*(param[i]));
+  if(logt == YES)   for(i=0;i<n_param;i++) (*(param[i])) = exp(MIN(1.E+2,*(param[i])));
+  for(i=0;i<n_param;i++) sign[i] = (*(param[i])) > .0 ? 1. : -1.;
+  if(is_positive == YES) for(i=0;i<n_param;i++) *(param[i]) = FABS(*(param[i]));
   f0 = (*func)(tree);
-  if(is_positive == YES) For(i,n_param) *(param[i]) *= sign[i];
-  if(logt == YES)   For(i,n_param) (*(param[i])) = LOG(*(param[i]));
+  if(is_positive == YES) for(i=0;i<n_param;i++) *(param[i]) *= sign[i];
+  if(logt == YES)   for(i=0;i<n_param;i++) (*(param[i])) = log(*(param[i]));
 
 
-  For(i,n_param)
+  for(i=0;i<n_param;i++)
     {
 
       derivatives[i] = Num_Derivatives_One_Param_Nonaligned(func,
@@ -3316,7 +3300,7 @@ int Compare_Two_States(char *state1, char *state2, int state_size)
   /* 0 the two states are different */
   int i;
 
-  For(i,state_size) if(state1[i] != state2[i]) break;
+  for(i=0;i<state_size;i++) if(state1[i] != state2[i]) break;
 
   return (i==state_size)?(1):(0);
 }
@@ -3328,7 +3312,7 @@ int Compare_Two_States(char *state1, char *state2, int state_size)
 void Copy_One_State(char *from, char *to, int state_size)
 {
   int i;
-  For(i,state_size) to[i] = from[i];
+  for(i=0;i<state_size;i++) to[i] = from[i];
 }
 
 //////////////////////////////////////////////////////////////
@@ -3337,7 +3321,7 @@ void Copy_One_State(char *from, char *to, int state_size)
 void Copy_Dist(phydbl **cpy, phydbl **orig, int n)
 {
   int i,j;
-  For(i,n) For(j,n) cpy[i][j] = orig[i][j];
+  for(i=0;i<n;i++) for(j=0;j<n;j++) cpy[i][j] = orig[i][j];
 }
 
 //////////////////////////////////////////////////////////////
@@ -3410,16 +3394,16 @@ void Record_Model(t_mod *ori, t_mod *cpy)
         }
     }
   
-  For(i,cpy->ns)
+  for(i=0;i<cpy->ns;i++)
     {
       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];
   
-  For(i,cpy->ras->n_catg)
+  for(i=0;i<cpy->ras->n_catg;i++)
     {
       cpy->ras->gamma_r_proba->v[i]          = ori->ras->gamma_r_proba->v[i];
       cpy->ras->gamma_rr->v[i]               = ori->ras->gamma_rr->v[i];
@@ -3432,8 +3416,8 @@ void Record_Model(t_mod *ori, t_mod *cpy)
   cpy->eigen->size = ori->eigen->size;
   For(i,2*ori->ns)       cpy->eigen->space[i]       = ori->eigen->space[i];
   For(i,2*ori->ns)       cpy->eigen->space_int[i]   = ori->eigen->space_int[i];
-  For(i,ori->ns)         cpy->eigen->e_val[i]       = ori->eigen->e_val[i];
-  For(i,ori->ns)         cpy->eigen->e_val_im[i]    = ori->eigen->e_val_im[i];
+  for(i=0;i<ori->ns;i++)         cpy->eigen->e_val[i]       = ori->eigen->e_val[i];
+  for(i=0;i<ori->ns;i++)         cpy->eigen->e_val_im[i]    = ori->eigen->e_val_im[i];
   For(i,ori->ns*ori->ns) cpy->eigen->r_e_vect[i]    = ori->eigen->r_e_vect[i];
   For(i,ori->ns*ori->ns) cpy->eigen->r_e_vect[i]    = ori->eigen->r_e_vect[i];
   For(i,ori->ns*ori->ns) cpy->eigen->r_e_vect_im[i] = ori->eigen->r_e_vect_im[i];
@@ -3453,9 +3437,6 @@ void Record_Model(t_mod *ori, t_mod *cpy)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
-
-
 void Test_Node_Table_Consistency(t_tree *tree)
 {
   int i;
@@ -3473,7 +3454,6 @@ void Test_Node_Table_Consistency(t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Get_Bip(t_node *a, t_node *d, t_tree *tree)
 {
   int i,j;
@@ -3497,12 +3477,12 @@ void Get_Bip(t_node *a, t_node *d, t_tree *tree)
           d->bip_size[1]    = -1;
           d->bip_size[2]    = -1;
           
-          For(i,3)
+          for(i=0;i<3;i++)
             {
               if(a->v[i] == d)
                 {
                   a->bip_size[i] = 0;
-                  For(j,tree->n_otu)
+                  for(j=0;j<tree->n_otu;j++)
                     {
                       if(strcmp(tree->a_nodes[j]->name,d->name))
                         {
@@ -3543,17 +3523,17 @@ void Get_Bip(t_node *a, t_node *d, t_tree *tree)
       
       d_a = -1;
       
-      For(i,3)
+      for(i=0;i<3;i++)
         {
           if(d->v[i] != a) Get_Bip(d,d->v[i],tree);
           else if(d->v[i] == a) d_a = i;
         }
       
       d->bip_size[d_a] = 0;
-      For(i,3)
+      for(i=0;i<3;i++)
         if(d->v[i] != a)
           {
-            For(j,3)
+            for(j=0;j<3;j++)
               {
                 if(d->v[i]->v[j] == d)
                   {
@@ -3584,11 +3564,11 @@ void Get_Bip(t_node *a, t_node *d, t_tree *tree)
         }while(swapped == YES);
       
       
-      For(i,3)
+      for(i=0;i<3;i++)
         if(a->v[i] == d)
           {
             a->bip_size[i] = 0;
-            For(j,tree->n_otu)
+            for(j=0;j<tree->n_otu;j++)
               {
                 For(k,d->bip_size[d_a])
                   {
@@ -3622,7 +3602,7 @@ void Get_Bip(t_node *a, t_node *d, t_tree *tree)
             if(a->bip_size[i] != tree->n_otu - d->bip_size[d_a])
               {
                 PhyML_Printf("%d %d \n",a->bip_size[i],tree->n_otu - d->bip_size[d_a]);
-                Warn_And_Exit("\n. Problem in counting bipartitions \n");
+                Warn_And_Exit("\n\u2022 Problem in counting bipartitions \n");
               }
             break;
           }
@@ -3632,7 +3612,6 @@ void Get_Bip(t_node *a, t_node *d, t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Alloc_Bip(t_tree *tree)
 {
   int i;
@@ -3645,18 +3624,12 @@ void Alloc_Bip(t_tree *tree)
     {
       tree->a_nodes[i]->bip_size = (int *)mCalloc(3,sizeof(int));
       tree->a_nodes[i]->bip_node = (t_node ***)mCalloc(3,sizeof(t_node **));
-
-/*       For(j,3) */
-/* 	{ */
-/* 	  tree->a_nodes[i]->bip_node[j] = (t_node **)mCalloc(tree->n_otu,sizeof(t_node *)); */
-/* 	} */
     }
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 int Sort_Phydbl_Increase(const void *a, const void *b)
 {
   if((*(phydbl *)(a)) <= (*(phydbl *)(b))) return -1;
@@ -3666,7 +3639,6 @@ int Sort_Phydbl_Increase(const void *a, const void *b)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 int Sort_String(const void *a, const void *b)
 {
   return(strcmp((*(const char **)(a)), (*(const char **)(b))));
@@ -3774,9 +3746,9 @@ int Compare_Bip(t_tree *tree1, t_tree *tree2, int on_existing_edges_only)
                           bip2 = b2->rght->bip_node[b2->r_l];
                         }
                       
-                      if(bip_size == 1) Warn_And_Exit("\n. Problem in Compare_Bip\n");
+                      if(bip_size == 1) Warn_And_Exit("\n\u2022 Problem in Compare_Bip\n");
                       
-                      For(k,bip_size)
+                      for(k=0;k<bip_size;k++)
                         {
                           /* 			  if(strcmp(bip1[k],bip2[k])) break; */
                           if(bip1[k]->num != bip2[k]->num) break;
@@ -3824,9 +3796,9 @@ void Match_Tip_Numbers(t_tree *tree1, t_tree *tree2)
       Generic_Exit(__FILE__,__LINE__,__FUNCTION__);    
     }
 
-  For(i,tree1->n_otu)
+  for(i=0;i<tree1->n_otu;i++)
     {
-      For(j,tree2->n_otu)
+      for(j=0;j<tree2->n_otu;j++)
     {
       if(!strcmp(tree1->a_nodes[i]->name,tree2->a_nodes[j]->name))
         {
@@ -3854,7 +3826,7 @@ void Test_Multiple_Data_Set_Format(option *io)
   Free(line);
 
   if((io->mod->bootstrap > 1) && (io->n_trees > 1))
-    Warn_And_Exit("\n. Bootstrap option is not allowed with multiple input trees !\n");
+    Warn_And_Exit("\n\u2022 Bootstrap option is not allowed with multiple input trees !\n");
 
   rewind(io->fp_in_tree);
 
@@ -3872,10 +3844,10 @@ int Are_Compatible(char *statea, char *stateb, int stepsize, int datatype)
 
   if(datatype == NT)
     {
-      For(i,stepsize)
+      for(i=0;i<stepsize;i++)
         {
           a = statea[i];
-          For(j,stepsize)
+          for(j=0;j<stepsize;j++)
             {
               b = stateb[j];
               
@@ -4467,7 +4439,7 @@ int Are_Compatible(char *statea, char *stateb, int stepsize, int datatype)
               Warn_And_Exit("");
             }
           
-          /* 	  PhyML_Printf("\n. %s %d a=%d b=%d ",__FILE__,__LINE__,a,b);  */
+          /* 	  PhyML_Printf("\n\u2022 %s %d a=%d b=%d ",__FILE__,__LINE__,a,b);  */
           
           if(a == b) return 1;
         }
@@ -4484,7 +4456,7 @@ int Are_Compatible(char *statea, char *stateb, int stepsize, int datatype)
 void Hide_Ambiguities(calign *data)
 {
   int i;
-  For(i,data->crunch_len) if(data->ambigu[i]) data->wght[i] = 0;
+  for(i=0;i<data->crunch_len;i++) if(data->ambigu[i]) data->wght[i] = 0;
 }
 
 //////////////////////////////////////////////////////////////
@@ -4494,9 +4466,9 @@ void Copy_Tree(t_tree *ori, t_tree *cpy)
 {
   int i,j;
 
-  For(i,2*ori->n_otu-2)
+  for(i=0;i<2*ori->n_otu-2;++i)
     {
-      For(j,3)
+      for(j=0;j<3;++j)
         {
           if(ori->a_nodes[i]->v[j])
             {
@@ -4512,14 +4484,14 @@ void Copy_Tree(t_tree *ori, t_tree *cpy)
         }
     }
 
-  For(i,2*ori->n_otu-3)
+  for(i=0;i<2*ori->n_otu-3;++i)
     {
       cpy->a_edges[i]->l->v             = ori->a_edges[i]->l->v;
       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;
@@ -4527,6 +4499,7 @@ void Copy_Tree(t_tree *ori, t_tree *cpy)
       cpy->a_edges[i]->l_r              = ori->a_edges[i]->l_r;
       cpy->a_edges[i]->r_l              = ori->a_edges[i]->r_l;
       cpy->a_edges[i]->does_exist       = ori->a_edges[i]->does_exist;
+
 #ifdef BEAGLE
       cpy->a_edges[i]->p_lk_left_idx    = ori->a_edges[i]->p_lk_left_idx;
       cpy->a_edges[i]->p_lk_rght_idx    = ori->a_edges[i]->p_lk_rght_idx;
@@ -4535,9 +4508,7 @@ void Copy_Tree(t_tree *ori, t_tree *cpy)
     }
 
 
-
-
-  For(i,ori->n_otu)
+  for(i=0;i<ori->n_otu;++i)
     {
       cpy->a_nodes[i]->tax = YES;
 
@@ -4567,16 +4538,16 @@ void Copy_Tree(t_tree *ori, t_tree *cpy)
       cpy->a_edges[2*cpy->n_otu-2]->l_var_old->v   = ori->a_edges[2*cpy->n_otu-2]->l_var_old->v;
     }
 
-
   cpy->num_curr_branch_available = 0;
-  cpy->t_beg = ori->t_beg;
+  cpy->t_beg                     = ori->t_beg;
+  cpy->verbose                   = ori->verbose;
 
-/*   Connect_Edges_To_Nodes_Recur(cpy->a_nodes[0],cpy->a_nodes[0]->v[0],cpy); */
-/*   Update_Dirs(cpy); */
 
 #ifdef BEAGLE
   cpy->b_inst = ori->b_inst;
 #endif
+
+  if(cpy->next) Copy_Tree(cpy,cpy->next);
 }
 
 //////////////////////////////////////////////////////////////
@@ -4584,22 +4555,38 @@ void Copy_Tree(t_tree *ori, t_tree *cpy)
 
 void Prune_Subtree(t_node *a, t_node *d, t_edge **target, t_edge **residual, t_tree *tree)
 {
-
-  t_node *v1, *v2;
+  t_node *v1, *v2, *buff_nd;
   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;
-  unsigned int *buff_ui;
-  short int *buff_p_lk_tip;
+  int *buff_p_pars;
+  int *buff_pars;
+  int *buff_p_lk_loc, *buff_patt_id;
+  int *buff_ui;
+  phydbl *buff_p_lk_tip;
+
+  assert(a);
+  assert(d);
+  assert(tree);
+
+  
+  if(tree->n_root && a == tree->n_root) 
+    {
+      if(d == tree->e_root->left) a = tree->e_root->rght;
+      else if(d == tree->e_root->rght) a = tree->e_root->left;
+      else
+        {
+          PhyML_Printf("\n== left: %d right: %d",tree->e_root->left->num,tree->e_root->rght->num);
+          assert(false);
+        }
+    }
 
   if(a->tax) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
 
   dir_v1 = dir_v2 = -1;
-  For(i,3)
+  for(i=0;i<3;i++)
     {
       if(a->v[i] != d)
         {
@@ -4608,6 +4595,15 @@ void Prune_Subtree(t_node *a, t_node *d, t_edge **target, t_edge **residual, t_t
         }
     }
 
+  assert(dir_v1 > -1);
+  assert(dir_v2 > -1);
+
+  assert(a->v[dir_v1] != NULL);
+  assert(a->v[dir_v2] != NULL);
+  
+  if(a->v[dir_v1] == a->anc) a->v[dir_v2]->anc = a->v[dir_v1];
+  else                       a->v[dir_v1]->anc = a->v[dir_v2];
+
   if(a->v[dir_v1]->num < a->v[dir_v2]->num)
     {
       v1 = a->v[dir_v1];
@@ -4622,9 +4618,13 @@ 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"); */
+  if(target)   (*target)   = b1;
+  if(residual) (*residual) = b2;
+
 
   a->v[dir_v1] = NULL;
   a->v[dir_v2] = NULL;
@@ -4641,88 +4641,92 @@ 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;
-
+              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
@@ -4731,94 +4735,99 @@ 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_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;
+            }
         }
     }
 
-  For(i,3)
+  for(i=0;i<3;i++)
     if(v2->v[i] == a)
       {
         v2->v[i] = v1;
@@ -4834,11 +4843,11 @@ void Prune_Subtree(t_node *a, t_node *d, t_edge **target, t_edge **residual, t_t
     }
 #endif
 
-  For(i,3)
+  for(i=0;i<3;i++)
     if(v1->v[i] == a)
       {
-    v1->v[i] = v2;
-    break;
+        v1->v[i] = v2;
+        break;
       }
 
 #ifdef DEBUG
@@ -4851,64 +4860,112 @@ 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     = (b1->l->v + b2->l->v);
+      b1->l_var->v = (b1->l_var->v + b2->l_var->v);
     }
 
+
   (v1 == b1->left)?
     (Set_Edge_Dirs(b1,v1,v2,tree)):
     (Set_Edge_Dirs(b1,v2,v1,tree));
 
-  if(target)   (*target)   = b1;
-  if(residual) (*residual) = b2;
-
 
-  if(tree->n_root)
+  if(tree->n_root != NULL)
     {
-      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;
-    }
+      // Pruning one of the subtree below n_root->v[2], v2 below a
+      if(tree->n_root->v[1] == v1 && tree->n_root->v[2] == a) tree->n_root->v[2] = v2;
 
-  /* 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; */
-  /*   } */
+      // Pruning one of the subtree below n_root->v[1], v2 below a
+      else if(tree->n_root->v[2] == v1 && tree->n_root->v[1] == a) tree->n_root->v[1] = v2;
+  
+      // Pruning one of the subtree below n_root->v[1], v1 below a
+      else if((tree->n_root->v[1] == v2 && tree->n_root->v[2] == a) || 
+              (tree->n_root->v[2] == v2 && tree->n_root->v[1] == a))
+        {
+          tree->e_root = b1;
+          if(tree->n_root->v[1] == v2) tree->n_root->v[2] = v1;
+          if(tree->n_root->v[2] == v2) tree->n_root->v[1] = v1;
+        }
+      
+      // Prune subtree to the left or to the right of the root node
+      else if((tree->n_root->v[1] == a && tree->n_root->v[2] == d) ||
+              (tree->n_root->v[1] == d && tree->n_root->v[2] == a))
+        {
+          tree->e_root = b1;
+          tree->n_root->v[1] = v2;
+          tree->n_root->v[2] = v1;
+        }
+
+
+      if(tree->n_root->v[1] == tree->e_root->rght)
+        {
+          buff_nd = tree->n_root->v[1];
+          tree->n_root->v[1] = tree->n_root->v[2];
+          tree->n_root->v[2] = buff_nd;
+        }
+
+      Update_Ancestors(tree->n_root,tree->n_root->v[1],tree);
+      Update_Ancestors(tree->n_root,tree->n_root->v[2],tree);
+      tree->n_root->anc = NULL;
+    }
 
 #ifdef DEBUG
   if(b1->left->tax == YES && b1->rght->tax == NO)
     {
+      PhyML_Printf("\n== root: %d root->v1: %d root->v2: %d eroot: %d b1: %d b2: %d v1: %d v2: %d",
+                   tree->n_root->num,
+                   tree->n_root->v[1]->num,
+                   tree->n_root->v[2]->num,
+                   tree->e_root->num,
+                   b1->num,b2->num,v1->num,v2->num);
       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== b1->rght->num = %d",b1->rght->num);
+      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);
-
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-void Graft_Subtree(t_edge *target, t_node *link, t_edge *residual, t_tree *tree)
+void Graft_Subtree(t_edge *target, t_node *link, t_node *link_daughter, t_edge *residual, t_node *target_nd, t_tree *tree)
 {
   t_node *v1, *v2;
   int i, dir_v1, dir_v2;
   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;
+  int *buff_p_pars, *buff_pars;
+  int *buff_p_lk_loc, *buff_patt_id;
+  phydbl *buff_p_lk_tip;
+  int *buff_ui;
   t_edge *b_up;
 
+  assert(link);
+  assert(tree);
+  assert(target);
+    
+  if(link == tree->n_root)
+    {
+      assert(link_daughter);
+      if(link_daughter == tree->n_root->v[1]) link = tree->n_root->v[2];
+      else if(link_daughter == tree->n_root->v[2]) link = tree->n_root->v[1];
+      else
+        {
+          PhyML_Printf("\n== link: %d link_daughter: %d",
+                       link->num,
+                       link_daughter ? link_daughter->num : -1);
+          assert(false);
+        }
+    }
 
   dir_v1 = dir_v2 = -1;
   b_up = NULL;
-  For(i,3)
+  for(i=0;i<3;i++)
     {
-      if(!link->v[i])
+      if(link->v[i] == NULL)
         {
           if(dir_v1 < 0) dir_v1 = i;
           else           dir_v2 = i;
@@ -4916,6 +4973,24 @@ void Graft_Subtree(t_edge *target, t_node *link, t_edge *residual, t_tree *tree)
       else b_up = link->b[i];
     }
   
+  if(dir_v1 < 0 || dir_v2 < 0)
+    {
+      PhyML_Printf("\n== link: %d was not pruned in a clean manner...\n",link->num);
+      assert(FALSE);
+    }
+
+
+  if(target->left == target->rght->anc)
+    {
+      link->anc = target->left;
+      target->rght->anc = link;
+    }
+  else
+    {
+      link->anc = target->rght;
+      target->left->anc = link;
+    }
+    
 
 #ifdef BEAGLE
   int temp;
@@ -4923,101 +4998,112 @@ void Graft_Subtree(t_edge *target, t_node *link, t_edge *residual, t_tree *tree)
 
   if(target->left->num < target->rght->num)
     {
-      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;
+      v1 = target->left;
+      v2 = target->rght;
 
+      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;
+      v1 = target->rght;
+      v2 = target->left;
 
+      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)
+  for(i=0;i<3;i++)
     if(v2->b[i] == target)
       {
         v2->v[i] = link;
@@ -5031,16 +5117,14 @@ void Graft_Subtree(t_edge *target, t_node *link, t_edge *residual, t_tree *tree)
   residual->left  = link;
   residual->rght  = v2;
 
-
-  if(v1 == target->left)
-    target->rght = link;
-  else 
-    target->left = link;
+  if(v1 == target->left) target->rght = link;
+  else                   target->left = link;
 
   link->v[dir_v1] = v1;
   link->b[dir_v1] = target;
 
-  For(i,3)
+
+  for(i=0;i<3;i++)
     if(v1->v[i] == v2)
       {
         v1->v[i] = link;
@@ -5048,32 +5132,52 @@ 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.0;
+      target->l_var->v /= 2.0;
+    }
 
   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; */
-  /*   } */
+  /* printf("\n here %p target: %d [%p] eroot: %d [%p] target_nd: %d [%p] root: %d [%p]", */
+  /*        tree, */
+  /*        target?target->num:-1,target, */
+  /*        tree->e_root?tree->e_root->num:-1,tree->e_root, */
+  /*        target_nd?target_nd->num:-1,target_nd, */
+  /*        tree->n_root?tree->n_root->num:-1,tree->n_root); */
+  /* fflush(NULL); */
 
+  if(tree->n_root != NULL)
+    {
+      if(target == tree->e_root)
+        {
+          if(target_nd == v1)                tree->e_root = residual;
+          else if(target_nd == v2)           tree->e_root = target;
+          else if(target_nd == tree->n_root) tree->e_root = b_up;
 
-  if(tree->is_mixt_tree == YES) MIXT_Graft_Subtree(target,link,residual,tree);
+          tree->n_root->v[1] = tree->e_root->left;
+          tree->n_root->v[2] = tree->e_root->rght;
+        }
+      
+      Update_Ancestors(tree->n_root,tree->n_root->v[1],tree);
+      Update_Ancestors(tree->n_root,tree->n_root->v[2],tree);
+      tree->n_root->anc = NULL;
+    }
 
+  if(tree->is_mixt_tree == YES) MIXT_Graft_Subtree(target,link,link_daughter,residual,target_nd,tree);
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Reassign_Node_Nums(t_node *a, t_node *d, int *curr_ext_node, int *curr_int_node, t_tree *tree)
 {
   t_node *buff;
@@ -5109,7 +5213,7 @@ void Reassign_Node_Nums(t_node *a, t_node *d, int *curr_ext_node, int *curr_int_
       (*curr_int_node)++;
     }
 
-  For(i,3)
+  for(i=0;i<3;i++)
     {
       if(d->v[i] != a)
         Reassign_Node_Nums(d,d->v[i],curr_ext_node,curr_int_node,tree);
@@ -5125,14 +5229,14 @@ void Reassign_Edge_Nums(t_node *a, t_node *d, int *curr_br, t_tree *tree)
   t_edge *buff;
   int i,j;
 
-  For(i,3)
+  for(i=0;i<3;i++)
     if(a->v[i] == d)
       {
         buff = tree->a_edges[*curr_br];
         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];
@@ -5145,7 +5249,7 @@ void Reassign_Edge_Nums(t_node *a, t_node *d, int *curr_br, t_tree *tree)
   if(d->tax) return;
   else
     {
-      For(i,3)
+      for(i=0;i<3;i++)
         if(d->v[i] != a)
           Reassign_Edge_Nums(d,d->v[i],curr_br,tree);
     }
@@ -5154,18 +5258,17 @@ 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;
 
 
-  For(i,3)
+  for(i=0;i<3;i++)
     {
-      For(j,3)
+      for(j=0;j<3;j++)
     {
       scores[i][j] = 0;
 
@@ -5183,9 +5286,9 @@ void Find_Mutual_Direction(t_node *n1, t_node *n2, short int *dir_n1_to_n2, shor
     }
     }
 
-  For(i,3)
+  for(i=0;i<3;i++)
     {
-      For(j,3)
+      for(j=0;j<3;j++)
     {
       if(!scores[i][j])
         {
@@ -5196,16 +5299,16 @@ void Find_Mutual_Direction(t_node *n1, t_node *n2, short int *dir_n1_to_n2, shor
     }
     }
 
-  PhyML_Printf("\n. n1=%d n2=%d",n1->num,n2->num);
-  PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__);
+  PhyML_Printf("\n== n1=%d n2=%d",n1->num,n2->num);
+  PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__);
   Warn_And_Exit("");
 
 
 
-/*   For(i,3) */
+/*   for(i=0;i<3;i++) */
 /*     { */
 /*       n_zero_line = 0; */
-/*       For(j,3) */
+/*       for(j=0;j<3;j++) */
 /* 	{ */
 /* 	  if(!scores[i][j]) n_zero_line++; */
 /* 	} */
@@ -5213,10 +5316,10 @@ void Find_Mutual_Direction(t_node *n1, t_node *n2, short int *dir_n1_to_n2, shor
 /*     } */
 
 
-/*   For(i,3) */
+/*   for(i=0;i<3;i++) */
 /*     { */
 /*       n_zero_col = 0; */
-/*       For(j,3) */
+/*       for(j=0;j<3;j++) */
 /* 	{ */
 /* 	  if(!scores[j][i]) n_zero_col++; */
 /* 	} */
@@ -5228,7 +5331,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 +5341,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)
+  
+  for(i=0;i<3;i++)
     {
       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=0;j<tree->n_otu;j++) inout[j] = 1;
+          For(k,a->bip_size[i]) inout[a->bip_node[i][k]->num] = 0;
+          for(j=0;j<tree->n_otu;j++) 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;
-    }
-
-      For(j,tree->n_otu) inout[j] = 1;
+      
+      for(i=0;i<3;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=0;j<tree->n_otu;j++) 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;
+      for(j=0;j<tree->n_otu;j++) 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 +5386,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)
 {
@@ -5319,7 +5407,7 @@ int Get_Subtree_Size(t_node *a, t_node *d)
   else
     {
       size = 0;
-      For(i,3)
+      for(i=0;i<3;i++)
     if(d->v[i] != a)
       size += Get_Subtree_Size(d,d->v[i]);
     }
@@ -5329,91 +5417,18 @@ int Get_Subtree_Size(t_node *a, t_node *d)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-void Fast_Br_Len(t_edge *b, t_tree *tree, int approx)
+phydbl 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; */
+  phydbl init_min_diff_lk_local = tree->mod->s_opt->min_diff_lk_local;
 
-  if(tree->is_mixt_tree)
-    {
-      if(approx == NO)
-        MIXT_Br_Len_Brent(0.001,100.,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 = 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]; */
-
-  /* } */
+  tree->mod->s_opt->min_diff_lk_local = 1.E-1;      
 
-  /* Free(v_rght); */
+  if(tree->is_mixt_tree) MIXT_Br_Len_Brent(b,tree);   
+  else Br_Len_Brent(b,tree);
 
-  /* Opt_Dist_F(&(b->l->v),F,tree->mod); */
-  /* n_iter++; */
+  tree->mod->s_opt->min_diff_lk_local = init_min_diff_lk_local;
 
-  if(approx == NO)
-    Br_Len_Brent(0.001,100.,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 = BRENT_IT_MAX;
-    }
+  return tree->c_lnL;
 }
 
 //////////////////////////////////////////////////////////////
@@ -5431,11 +5446,11 @@ void Joint_Proba_States_Left_Right(phydbl *Pij, phydbl *p_lk_left, phydbl *p_lk_
   int i,j;
   phydbl sum = 0.0;
 
-  For(i,n) F[i] = .0;
+  for(i=0;i<n;i++) F[i] = .0;
 
-  For(i,n)
+  for(i=0;i<n;i++)
     {
-      For(j,n)
+      for(j=0;j<n;j++)
     {
       F[i*n+j] =
         pi->v[i] *
@@ -5453,7 +5468,7 @@ void Joint_Proba_States_Left_Right(phydbl *Pij, phydbl *p_lk_left, phydbl *p_lk_
       F[i] /= sum;
       if(isnan(F[i]) || isinf(F[i]))
         {
-          For(i,n) For(j,n)
+          for(i=0;i<n;i++) for(j=0;j<n;j++)
             PhyML_Printf("\n== %15G %15G %15G %15G %15G",
                          pi->v[i] ,
                          Pij[i*n+j] ,
@@ -5473,32 +5488,80 @@ void Joint_Proba_States_Left_Right(phydbl *Pij, phydbl *p_lk_left, phydbl *p_lk_
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-phydbl Triple_Dist(t_node *a, t_tree *tree, int approx)
+phydbl Triple_Dist(t_node *a, t_tree *tree)
 {
   if(a->tax) return UNLIKELY;
   else
     {
-
       Update_PMat_At_Given_Edge(a->b[1],tree);
       Update_PMat_At_Given_Edge(a->b[2],tree);
 
-      Update_P_Lk(tree,a->b[0],a);
-      Fast_Br_Len(a->b[0],tree,approx);
-
-      Update_P_Lk(tree,a->b[1],a);
-      Fast_Br_Len(a->b[1],tree,approx);
+      Update_Partial_Lk(tree,a->b[0],a);
+      Fast_Br_Len(a->b[0],tree,YES);
 
-      Update_P_Lk(tree,a->b[2],a);
-      Fast_Br_Len(a->b[2],tree,approx);
+      Update_Partial_Lk(tree,a->b[1],a);
+      Fast_Br_Len(a->b[1],tree,YES);
 
-      Update_P_Lk(tree,a->b[1],a);
-      Update_P_Lk(tree,a->b[0],a);
+      Update_Partial_Lk(tree,a->b[2],a);
+      Fast_Br_Len(a->b[2],tree,YES);
+        
+      
+      Update_Partial_Lk(tree,a->b[1],a);
+      Update_Partial_Lk(tree,a->b[0],a);
     }
-
+  
   return tree->c_lnL;
 
 }
 
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+phydbl Triple_Dist_Approx(t_node *a, t_edge *b, t_tree *tree)
+{
+  // !!!!!!!! NOT MIXT PROOF 
+  if(a->tax) return UNLIKELY;
+  else
+    {
+      int i;
+
+      for(i=0;i<3;i++)
+        if(a->b[i] != b)
+          Update_PMat_At_Given_Edge(a->b[i],tree);
+
+      Update_Partial_Lk(tree,b,a);
+      Fast_Br_Len(b,tree,YES);
+
+      return tree->c_lnL;
+
+      /* t_node *v0,*v1,*v2; */
+      /* phydbl d01,d02,d12; */
+      /* t_ll *tips0,*tips1,*tips2; */
+
+      /* d01 = d02 = d12 = 0.0; */
+
+      /* v0 = a->v[0]; */
+      /* v1 = a->v[1]; */
+      /* v2 = a->v[2]; */
+
+      /* tips0 = Get_List_Of_Reachable_Tips(a,v0,tree); */
+      /* tips1 = Get_List_Of_Reachable_Tips(a,v1,tree); */
+      /* tips2 = Get_List_Of_Reachable_Tips(a,v2,tree); */
+      
+      /* d01 = Length_Of_Path_Between_List_Of_Tips(tips0,tips1,tree->mat); */
+      /* d02 = Length_Of_Path_Between_List_Of_Tips(tips0,tips2,tree->mat); */
+      /* d12 = Length_Of_Path_Between_List_Of_Tips(tips1,tips2,tree->mat); */
+
+      /* a->b[0]->l->v = (d01 + d02 - d12)/2.; */
+      /* a->b[1]->l->v = (d01 + d12 - d02)/2.; */
+      /* a->b[2]->l->v = (d02 + d12 - d01)/2.; */
+      
+      /* Free_Linked_List(tips0); */
+      /* Free_Linked_List(tips1); */
+      /* Free_Linked_List(tips2); */
+
+    }
+}
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
@@ -5508,7 +5571,7 @@ void Make_Symmetric(phydbl **F, int size)
 {
   int i,j;
 
-  For(i,size)
+  for(i=0;i<size;i++)
     {
       for(j=i+1;j<size;j++)
     {
@@ -5526,9 +5589,9 @@ void Round_Down_Freq_Patt(phydbl **F, t_tree *tree)
 {
   int i,j;
 
-  For(i,tree->mod->ns)
+  for(i=0;i<tree->mod->ns;i++)
     {
-      For(j,tree->mod->ns)
+      for(j=0;j<tree->mod->ns;j++)
     {
       (*F)[tree->mod->ns*i+j] = RINT((*F)[tree->mod->ns*i+j]);
     }
@@ -5544,8 +5607,8 @@ phydbl Get_Sum_Of_Cells(phydbl *F, t_tree *tree)
   int i,j;
   phydbl sum = .0;
 
-  For(i,tree->mod->ns)
-    For(j,tree->mod->ns)
+  for(i=0;i<tree->mod->ns;i++)
+    for(j=0;j<tree->mod->ns;j++)
     sum += F[tree->mod->ns*i+j];
 
   return sum;
@@ -5560,8 +5623,8 @@ void Divide_Cells(phydbl **F, phydbl div, t_tree *tree)
 {
   int i,j;
 
-  For(i,tree->mod->ns)
-    For(j,tree->mod->ns)
+  for(i=0;i<tree->mod->ns;i++)
+    for(j=0;j<tree->mod->ns;j++)
     (*F)[tree->mod->ns*i+j] /= div;
 }
 
@@ -5572,8 +5635,8 @@ void Divide_Cells(phydbl **F, phydbl div, t_tree *tree)
 void Divide_Mat_By_Vect(phydbl **F, phydbl *vect, int size)
 {
   int i,j;
-  For(i,size)
-    For(j,size)
+  for(i=0;i<size;i++)
+    for(j=0;j<size;j++)
     (*F)[size*i+j] = (*F)[size*i+j] / vect[j];
 }
 
@@ -5584,8 +5647,8 @@ void Divide_Mat_By_Vect(phydbl **F, phydbl *vect, int size)
 void Multiply_Mat_By_Vect(phydbl **F, phydbl *vect, int size)
 {
   int i,j;
-  For(i,size)
-    For(j,size)
+  for(i=0;i<size;i++)
+    for(j=0;j<size;j++)
     (*F)[size*i+j] = (*F)[size*i+j] * vect[j];
 }
 
@@ -5600,7 +5663,7 @@ void Found_In_Subtree(t_node *a, t_node *d, t_node *target, int *match, t_tree *
     {
       int i;
       if(d == target) *match =  1;
-      For(i,3)
+      for(i=0;i<3;i++)
     {
       if(d->v[i] != a)
         Found_In_Subtree(d,d->v[i],target,match,tree);
@@ -5611,35 +5674,33 @@ void Found_In_Subtree(t_node *a, t_node *d, t_node *target, int *match, t_tree *
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Get_List_Of_Target_Edges(t_node *a, t_node *d, t_edge **list, int *list_size, t_tree *tree)
 {
   int i;
 
-  For(i,3)
+  for(i=0;i<3;i++)
     {
       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);
-    }
+      for(i=0;i<3;i++)
+        {
+          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 +5716,6 @@ void Fix_All(t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Record_Br_Len(t_tree *mixt_tree)
 {
   int i;
@@ -5681,6 +5741,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)
 {
@@ -5703,19 +5858,18 @@ void Restore_Br_Len(t_tree *mixt_tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Get_Dist_Btw_Edges(t_node *a, t_node *d, t_tree *tree)
 {
   int i;
   t_edge *b_fcus;
 
   b_fcus = NULL;
-  For(i,3) if(a->v[i] == d) {b_fcus = a->b[i]; break;}
+  for(i=0;i<3;i++) if(a->v[i] == d) {b_fcus = a->b[i]; break;}
 
   if(d->tax) return;
   else
     {
-      For(i,3)
+      for(i=0;i<3;i++)
     if(d->v[i] != a)
       {
         d->b[i]->topo_dist_btw_edges = b_fcus->topo_dist_btw_edges + 1;
@@ -5744,7 +5898,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;
@@ -5752,7 +5905,7 @@ void Get_List_Of_Nodes_In_Polytomy(t_node *a, t_node *d, t_node ***list, int *si
     {
       int i;
 
-      For(i,3)
+      for(i=0;i<3;i++)
     {
       if(d->v[i] != a)
         {
@@ -5800,7 +5953,6 @@ void Path_Length(t_node *dep, t_node *arr, phydbl *len, t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Check_Path(t_node *a, t_node *d, t_node *target, t_tree *tree)
 {
   PhyML_Printf("path---------\n");
@@ -5822,28 +5974,29 @@ 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;
-
-  For(i,3)
+  
+  if(a->tax) return;
+  
+  for(i=0;i<3;i++)
     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);
+    for(i=0;i<3;i++)
+      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);
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Sort_List_Of_Adjacent_Targets(t_edge ***list, int list_size)
 {
   t_edge *buff_edge;
@@ -5851,7 +6004,7 @@ void Sort_List_Of_Adjacent_Targets(t_edge ***list, int list_size)
 
   buff_edge = NULL;
 
-  For(i,list_size-1)
+  for(i=0;i<list_size-1;i++)
     {
       for(j=i+1;j<list_size;j++)
     if((*list)[j]->topo_dist_btw_edges < (*list)[i]->topo_dist_btw_edges)
@@ -5873,10 +6026,10 @@ t_node *Common_Nodes_Btw_Two_Edges(t_edge *a, t_edge *b)
   else if(a->rght == b->left) return b->left;
   else if(a->rght == b->rght) return b->rght;
 
-  PhyML_Printf("\n. First t_edge = %d (%d %d); Second t_edge = %d (%d %d)\n",
+  PhyML_Printf("\n\u2022 First t_edge = %d (%d %d); Second t_edge = %d (%d %d)\n",
      a->num,a->left->num,a->rght->num,
      b->num,b->left->num,b->rght->num);
-  PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__);
+  PhyML_Printf("\n\u2022 Err in file %s at line %d\n",__FILE__,__LINE__);
   Warn_And_Exit("");
 
   return NULL;
@@ -5885,7 +6038,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;
@@ -5897,7 +6049,7 @@ int KH_Test(phydbl *site_lk_M1, phydbl *site_lk_M2, t_tree *tree)
   threshold = .0;
   mean = .0;
   obs_stat = .0;
-  For(i,tree->n_pattern)
+  for(i=0;i<tree->n_pattern;i++)
     {
       delta[i] = site_lk_M1[i] - site_lk_M2[i];
       mean += ((int)tree->data->wght[i])*delta[i];
@@ -5907,10 +6059,10 @@ int KH_Test(phydbl *site_lk_M1, phydbl *site_lk_M2, t_tree *tree)
 
   mean /= tree->data->init_len;
 
-  For(i,tree->data->init_len) delta[i] -= mean;
+  for(i=0;i<tree->data->init_len;i++) delta[i] -= mean;
 
   sd = .0;
-  For(i,tree->data->init_len) sd += POW(delta[i],2);
+  for(i=0;i<tree->data->init_len;i++) sd += POW(delta[i],2);
   sd /= (phydbl)(tree->data->init_len-1.);
 
 /*   threshold = tree->dnorm_thresh*SQRT(sd*tree->data->init_len); */
@@ -5926,27 +6078,22 @@ 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;
   int i,node_num,step,n_available;
   phydbl min_edge_len;
 
-  min_edge_len = 1.E-3;
+  assert(tree);
 
-  if(tree->mod->s_opt && tree->mod->s_opt->print == YES)
-    PhyML_Printf("\n\n. Randomising the tree...\n");
+  min_edge_len = 1.E-3;
 
   is_available  = (int *)mCalloc(2*tree->n_otu-2,sizeof(int));
   list_of_nodes = (int *)mCalloc(tree->n_otu,    sizeof(int));
 
-  For(i,tree->n_otu) is_available[i]  = 1;
-  For(i,tree->n_otu) list_of_nodes[i] = i;
+  for(i=0;i<tree->n_otu;i++) is_available[i]  = 1;
+  for(i=0;i<tree->n_otu;i++) list_of_nodes[i] = i;
+
 
   step = 0;
   do
@@ -5955,7 +6102,7 @@ void Random_Tree(t_tree *tree)
       node_num = Rand_Int(0,tree->n_otu-1-step);
       node_num = list_of_nodes[node_num];
       is_available[node_num] = 0;
-      For(i,tree->n_otu) list_of_nodes[i] = -1;
+      for(i=0;i<tree->n_otu;i++) list_of_nodes[i] = -1;
       n_available = 0;
       For(i,2*tree->n_otu-2) if(is_available[i]) {list_of_nodes[n_available++] = i;}
 
@@ -5966,7 +6113,7 @@ void Random_Tree(t_tree *tree)
       node_num = Rand_Int(0,tree->n_otu-2-step);
       node_num = list_of_nodes[node_num];
       is_available[node_num] = 0;
-      For(i,tree->n_otu) list_of_nodes[i] = -1;
+      for(i=0;i<tree->n_otu;i++) list_of_nodes[i] = -1;
       n_available = 0;
       For(i,2*tree->n_otu-2) if(is_available[i]) {list_of_nodes[n_available++] = i;}
 
@@ -5974,7 +6121,7 @@ void Random_Tree(t_tree *tree)
       tree->a_nodes[tree->n_otu+step]->v[2] = tree->a_nodes[node_num];
 
       is_available[tree->n_otu+step] = 1;
-      For(i,tree->n_otu) list_of_nodes[i] = -1;
+      for(i=0;i<tree->n_otu;i++) list_of_nodes[i] = -1;
       n_available = 0;
       For(i,2*tree->n_otu-2) if(is_available[i]) list_of_nodes[n_available++] = i;
 
@@ -5989,9 +6136,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 +6145,8 @@ 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: make sure  p_lk_tips vector are re-initialized after
+// calling this function 
 void Reorganize_Edges_Given_Lk_Struct(t_tree *tree)
 {
   int j,i;
@@ -6009,83 +6154,35 @@ 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;
-        }
-          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],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],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[i]->p_lk_rght && tree->a_edges[i]->rght->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],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;
-        }
-        }
-    }
-    }
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-void Random_NNI(int n_moves, t_tree *tree)
-{
-  int i,j;
-  t_edge *b;
-  t_node *n1,*n2,*n_target;
-
-  n1 = n2 = NULL;
-  b = NULL;
-  For(i,n_moves)
-    {
-      n_target  = tree->a_nodes[tree->n_otu + (int)((phydbl)rand()/RAND_MAX * (2*tree->n_otu-3-tree->n_otu))];
-      For(j,3) if(!n_target->v[j]->tax) {b = n_target->b[j]; break;}
-
-
-      For(j,3) if(b->left->v[j] != b->rght) {n1 = b->left->v[j]; break;}
-      For(j,3) if(b->rght->v[j] != b->left) {n2 = b->rght->v[j]; break;}
-
-
-      Swap(n1,b->left,b->rght,n2,tree);
-    }
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-void Fill_Missing_Dist(matrix *mat)
-{
-  int i,j;
-  
-  For(i,mat->n_otu)
-    {
-      for(j=i+1;j<mat->n_otu;j++)
         {
-          if(i != j)
+          For(j,2*tree->n_otu-3)
             {
-              if(mat->dist[i][j] < .0)
+              if(!tree->a_edges[j]->p_lk_left && tree->a_edges[j]->left->tax == NO)
                 {
-                  Fill_Missing_Dist_XY(i,j,mat);
-                  mat->dist[j][i] = mat->dist[i][j];
+                  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;
                 }
             }
         }
@@ -6095,29 +6192,286 @@ void Fill_Missing_Dist(matrix *mat)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
-void Fill_Missing_Dist_XY(int x, int y, matrix *mat)
+void Swap_Partial_Lk(t_edge *a, t_edge *b, int side_a, int side_b, t_tree *tree)
 {
-
-  int i,j;
-  phydbl *local_mins,**S1S2;
-  int cpt;
-  int pos_best_estimate;
-  phydbl min_crit, curr_crit;
-
-  local_mins = (phydbl *)mCalloc(mat->n_otu*mat->n_otu,sizeof(phydbl ));
-  S1S2       = (phydbl **)mCalloc(mat->n_otu*mat->n_otu,sizeof(phydbl *));
-  For(i,mat->n_otu*mat->n_otu) S1S2[i] = (phydbl *)mCalloc(2,sizeof(phydbl));
-
-  cpt = 0;
-  For(i,mat->n_otu)
+  phydbl *buff_p_lk;
+  int *buff_scale;
+  int *buff_p_pars;
+  int *buff_pars;
+  int *buff_p_lk_loc, *buff_patt_id;
+  phydbl *buff_p_lk_tip;
+  int *buff_ui;
+  
+  
+  if(side_a == LEFT && side_b == LEFT)
     {
-      if((mat->dist[i][x] > .0) && (mat->dist[i][y] > .0))
-        {
-          For(j,mat->n_otu)
-            {
-              if((mat->dist[j][x] > .0) && (mat->dist[j][y] > .0))
-                {
+      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
+    }
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void Random_NNI(int n_moves, t_tree *tree)
+{
+  int i,j;
+  t_edge *b;
+  t_node *n1,*n2,*n_target;
+
+  n1 = n2 = NULL;
+  b = NULL;
+  for(i=0;i<n_moves;++i)
+    {
+      n_target  = tree->a_nodes[tree->n_otu + (int)((phydbl)rand()/RAND_MAX * (2*tree->n_otu-3-tree->n_otu))];
+      for(j=0;j<3;++j) if(!n_target->v[j]->tax) {b = n_target->b[j]; break;}
+
+      for(j=0;j<3;++j) if(b->left->v[j] != b->rght) {n1 = b->left->v[j]; break;}
+      for(j=0;j<3;++j) if(b->rght->v[j] != b->left) {n2 = b->rght->v[j]; break;}
+
+      Swap(n1,b->left,b->rght,n2,tree);
+    }
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void Fill_Missing_Dist(matrix *mat)
+{
+  int i,j;
+  
+  for(i=0;i<mat->n_otu;i++)
+    {
+      for(j=i+1;j<mat->n_otu;j++)
+        {
+          if(i != j)
+            {
+              if(mat->dist[i][j] < .0)
+                {
+                  Fill_Missing_Dist_XY(i,j,mat);
+                  mat->dist[j][i] = mat->dist[i][j];
+                }
+            }
+        }
+    }
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+
+void Fill_Missing_Dist_XY(int x, int y, matrix *mat)
+{
+
+  int i,j;
+  phydbl *local_mins,**S1S2;
+  int cpt;
+  int pos_best_estimate;
+  phydbl min_crit, curr_crit;
+
+  local_mins = (phydbl *)mCalloc(mat->n_otu*mat->n_otu,sizeof(phydbl ));
+  S1S2       = (phydbl **)mCalloc(mat->n_otu*mat->n_otu,sizeof(phydbl *));
+  For(i,mat->n_otu*mat->n_otu) S1S2[i] = (phydbl *)mCalloc(2,sizeof(phydbl));
+
+  cpt = 0;
+  for(i=0;i<mat->n_otu;i++)
+    {
+      if((mat->dist[i][x] > .0) && (mat->dist[i][y] > .0))
+        {
+          for(j=0;j<mat->n_otu;j++)
+            {
+              if((mat->dist[j][x] > .0) && (mat->dist[j][y] > .0))
+                {
                   if((i != j) && (i != x) && (i != y) && (j != x) && (j != y))
                     {
                       S1S2[cpt][0] = MIN(mat->dist[i][x] + mat->dist[j][y] - mat->dist[i][j] , mat->dist[i][y] + mat->dist[j][x] - mat->dist[i][j]);
@@ -6137,7 +6491,7 @@ void Fill_Missing_Dist_XY(int x, int y, matrix *mat)
   pos_best_estimate = 0;
   min_crit = curr_crit = BIG;
   
-  For(i,cpt-1)
+  for(i=0;i<cpt-1;i++)
     {
       if((local_mins[i] < S1S2[i+1][0]) && (local_mins[i] > S1S2[i][0]))
         {
@@ -6168,11 +6522,11 @@ phydbl Least_Square_Missing_Dist_XY(int x, int y, phydbl dxy, matrix *mat)
   phydbl fit;
   
   fit = .0;
-  For(i,mat->n_otu)
+  for(i=0;i<mat->n_otu;i++)
     {
       if((mat->dist[i][x] > .0) && (mat->dist[i][y] > .0))
         {
-          For(j,mat->n_otu)
+          for(j=0;j<mat->n_otu;j++)
             {
               if((mat->dist[j][x] > .0) && (mat->dist[j][y] > .0))
                 {
@@ -6215,7 +6569,7 @@ void Check_Memory_Amount(t_tree *tree)
 
   /* Partial Pars */
   nbytes += (2*n_otu-3) * 2 * tree->data->crunch_len * sizeof(int);
-  nbytes += (2*n_otu-3) * 2 * tree->data->crunch_len * sizeof(unsigned int);
+  nbytes += (2*n_otu-3) * 2 * tree->data->crunch_len * sizeof(int);
   nbytes += (2*n_otu-3) * 2 * tree->data->crunch_len * mod->ns * sizeof(int);
 
   /* Pmat */
@@ -6234,13 +6588,13 @@ void Check_Memory_Amount(t_tree *tree)
   if(((phydbl)nbytes/(1.E+06)) > 256.)
 /*   if(((phydbl)nbytes/(1.E+06)) > 0.) */
     {
-      PhyML_Printf("\n\n. WARNING: this analysis requires at least %.0f MB of memory space.\n",(phydbl)nbytes/(1.E+06));
+      PhyML_Printf("\n\n\u2022 WARNING: this analysis requires at least %.0f MB of memory space.\n",(phydbl)nbytes/(1.E+06));
 #ifndef BATCH
 
       char answer;
       if((!tree->io->quiet) && (tree->io->mem_question == YES))
         {
-          PhyML_Printf("\n. Do you really want to proceed? [Y/n] ");
+          PhyML_Printf("\n\u2022 Do you really want to proceed? [Y/n] ");
           if(scanf("%c", &answer))
             {
               if(answer == '\n') answer = 'Y';
@@ -6256,11 +6610,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\u2022 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\u2022 This analysis requires at least %.0f MB of memory space.\n",(phydbl)nbytes/(1.E+06));
     }
 }
 
@@ -6268,10 +6622,10 @@ void Check_Memory_Amount(t_tree *tree)
 //////////////////////////////////////////////////////////////
 
 
-int Get_State_From_P_Lk(phydbl *p_lk, int pos, t_tree *tree)
+int Get_State_From_Partial_Lk(phydbl *p_lk, int pos, t_tree *tree)
 {
   int i;
-  For(i,tree->mod->ns) if(p_lk[pos+i] > .0) return i;
+  for(i=0;i<tree->mod->ns;i++) if(p_lk[pos+i] > .0) return i;
   return -1;
 }
 
@@ -6279,10 +6633,10 @@ int Get_State_From_P_Lk(phydbl *p_lk, int pos, t_tree *tree)
 //////////////////////////////////////////////////////////////
 
 
-int Get_State_From_P_Pars(short int *p_pars, int pos, t_tree *tree)
+int Get_State_From_Partial_Pars(short int *p_pars, int pos, t_tree *tree)
 {
   int i;
-  For(i,tree->mod->ns) if(p_pars[pos+i] > .0) return i;
+  for(i=0;i<tree->mod->ns;i++) if(p_pars[pos+i] > .0) return i;
   return -1;
 }
 
@@ -6304,7 +6658,7 @@ void Check_Dirs(t_tree *tree)
       if(tree->a_edges[i]->left->v[tree->a_edges[i]->l_v1]->num <
          tree->a_edges[i]->left->v[tree->a_edges[i]->l_v2]->num)
         {
-          PhyML_Printf("\n. Edge %d ; v1=%d v2=%d",
+          PhyML_Printf("\n\u2022 Edge %d ; v1=%d v2=%d",
              tree->a_edges[i]->num,
              tree->a_edges[i]->left->v[tree->a_edges[i]->l_v1]->num,
              tree->a_edges[i]->left->v[tree->a_edges[i]->l_v2]->num);
@@ -6318,11 +6672,11 @@ void Check_Dirs(t_tree *tree)
       if(tree->a_edges[i]->rght->v[tree->a_edges[i]->r_v1]->num <
          tree->a_edges[i]->rght->v[tree->a_edges[i]->r_v2]->num)
         {
-          PhyML_Printf("\n. Edge %d ; v3=%d v4=%d",
+          PhyML_Printf("\n\u2022 Edge %d ; v3=%d v4=%d",
              tree->a_edges[i]->num,
              tree->a_edges[i]->rght->v[tree->a_edges[i]->r_v1]->num,
              tree->a_edges[i]->rght->v[tree->a_edges[i]->r_v2]->num);
-          PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__);
+          PhyML_Printf("\n\u2022 Err in file %s at line %d\n",__FILE__,__LINE__);
           Warn_And_Exit("");
         }
     }
@@ -6339,7 +6693,7 @@ void Warn_And_Exit(const char *s)
 #ifndef BATCH
   /* if (! tree->io->quiet) { */
   /* char c; */
-  PhyML_Fprintf(stdout,"\n. Type enter to exit.\n");
+  PhyML_Fprintf(stdout,"\n\u2022 Type enter to exit.\n");
   /*     if(!fscanf(stdin,"%c",&c))  */
   Exit("");
   /* } */
@@ -6350,6 +6704,55 @@ void Warn_And_Exit(const char *s)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
+// Apply random prune and regraft moves to an existing tree. As opposed to Random_Tree, using this 
+// function does not break the likelihood structure.
+void Randomize_Tree(t_tree *tree, int n_prune_regraft)
+{
+  t_node *rnd_node;
+  t_edge *rnd_edge,*b_target,*b_residual,**target_list;
+  int n_targets,n_rand,i;
+
+  target_list = (t_edge **)mCalloc(2*tree->n_otu-3,sizeof(t_edge *));
+
+  n_rand = n_prune_regraft;
+  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=0;i<3;i++)
+        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,tree->n_otu);
+      
+      for(i=0;i<3;i++)
+        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,tree->n_otu);
+      
+      if(n_targets > 0) b_target = target_list[Rand_Int(0,n_targets-1)];
+      
+      assert(b_target != NULL);
+      
+      Graft_Subtree(b_target,rnd_node,NULL,b_residual,NULL,tree);
+      
+      n_rand--;
+    }
+  while(n_rand > 0);
+
+  Free(target_list);
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
 void Randomize_Sequence_Order(calign *cdata)
 {
   int i,exchange_with;
@@ -6358,7 +6761,7 @@ void Randomize_Sequence_Order(calign *cdata)
   short int *buff_ambigu;
 
   exchange_with = -1;
-  For(i,cdata->n_otu)
+  for(i=0;i<cdata->n_otu;i++)
     {
       buff_dbl  = rand();
       buff_dbl /= (RAND_MAX+1.);
@@ -6404,21 +6807,18 @@ 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\u2022 Adding root on t_edge %d left = %d right = %d.",target->num,target->left ? target->left->num : -1, target->rght ? target->rght->num : -1); fflush(NULL) */;
   #endif
 
   tree->e_root = target;
 
   /* Create the root t_node if it does not exist yet */
-  if(!tree->a_nodes[2*tree->n_otu-2])
-    {
-      tree->n_root = (t_node *)Make_Node_Light(2*tree->n_otu-2);
-    }
-  else
-    {
-      tree->n_root = tree->a_nodes[2*tree->n_otu-2];
-    }
+  if(!tree->a_nodes[2*tree->n_otu-2]) tree->n_root = (t_node *)Make_Node_Light(2*tree->n_otu-2);
+  else                                tree->n_root = tree->a_nodes[2*tree->n_otu-2];
 
   tree->a_nodes[2*tree->n_otu-2] = tree->n_root;
 
@@ -6435,8 +6835,9 @@ void Add_Root(t_edge *target, t_tree *tree)
   if(tree->n_root_pos > -1.0)
     {
       if(tree->n_root_pos < 1.E-6 &&  tree->n_root_pos > -1.E-6)
-        printf("\n. WARNING: you put the root at a weird position...");
-
+        {
+          printf("\n== WARNING: you put the root at a weird position...");
+        }
 /*       tree->n_root->l[0] = tree->e_root->l->v * (tree->n_root_pos/(1.+tree->n_root_pos)); */
 /*       tree->n_root->l[1] = tree->e_root->l->v - tree->n_root->l[0]; */
 
@@ -6487,42 +6888,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);
 }
 
 //////////////////////////////////////////////////////////////
@@ -6530,16 +6934,20 @@ void Add_Root(t_edge *target, t_tree *tree)
 
 void Update_Ancestors(t_node *a, t_node *d, t_tree *tree)
 {
+  if(d == NULL)
+    {
+      PhyML_Printf("\n== d is NULL; a: %d root: %d",a->num,tree->n_root->num);
+      Generic_Exit(__FILE__,__LINE__,__FUNCTION__);    
+    }
+  d->anc = a;
 
   if(a == tree->n_root) a->anc = NULL;
 
-  d->anc = a;
-
   if(d->tax) return;
   else
     {
       int i;
-      For(i,3)
+      for(i=0;i<3;i++)
         if((d->v[i] != a) && (d->b[i] != tree->e_root))
           Update_Ancestors(d,d->v[i],tree);
     }
@@ -6562,15 +6970,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 +6986,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 +7001,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));
+  
+  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)
+  
+  for(i=0;i<tree->n_otu-1;i++)
     {
       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];
-
-
+  
+  for(i=0;i<tree->n_otu-1;i++) tmp[i] =  t[tree->n_otu-2-i];
+  for(i=0;i<tree->n_otu-1;i++) 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 +7035,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 +7045,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;
-      }
+      for(i=0;i<n_available;i++)
+        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)
+  
+  for(i=0;i<tree->n_otu;i++) tree->rates->nd_t[i] = 0.0;
+  
+  for(i=0;i<tree->n_otu;i++)
     {
       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 +7136,7 @@ t_tree *Generate_Random_Tree_From_Scratch(int n_otu, int rooted)
               break;
             }
         }
+
     }
   /* Or not... */
   else
@@ -6747,7 +7153,7 @@ t_tree *Generate_Random_Tree_From_Scratch(int n_otu, int rooted)
   Free(internal_nodes);
   Free(t);
   Free(tmp);
-
+  
   return tree;
 }
 #endif
@@ -6780,14 +7186,14 @@ void Random_Lineage_Rates(t_node *a, t_node *d, t_edge *b, phydbl stick_prob, ph
       new_rate = curr_rate;
     }
 
-      For(i,3)
+      for(i=0;i<3;i++)
     if(a->v[i] == d)
       {
         a->b[i]->l->v *= rates[new_rate];
         break;
       }
 
-      For(i,3)
+      for(i=0;i<3;i++)
     if(a->v[i] == d)
       {
         if(!(a->b[i]->n_labels%BLOCK_LABELS)) Make_New_Edge_Label(a->b[i]);
@@ -6803,7 +7209,7 @@ void Random_Lineage_Rates(t_node *a, t_node *d, t_edge *b, phydbl stick_prob, ph
   if(d->tax) return;
   else
     {
-      For(i,3)
+      for(i=0;i<3;i++)
     if(d->v[i] != a)
       Random_Lineage_Rates(d,d->v[i],d->b[i],stick_prob,rates,curr_rate,n_rates,tree);
     }
@@ -6812,7 +7218,6 @@ void Random_Lineage_Rates(t_node *a, t_node *d, t_edge *b, phydbl stick_prob, ph
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 t_edge *Find_Edge_With_Label(char *label, t_tree *tree)
 {
   int i,j;
@@ -6830,7 +7235,7 @@ t_edge *Find_Edge_With_Label(char *label, t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-void Evolve(calign *data, t_mod *mod, t_tree *tree)
+void Evolve(calign *data, t_mod *mod, int first_site_pos, t_tree *tree)
 {
   int root_state, root_rate_class;
   int site,i;
@@ -6846,17 +7251,14 @@ 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) 
-    {
-      switch_to_yes = YES;
-      /* tree->mod->gamma_mgf_bl = NO; */
-    }
-
+  if(tree->mod->gamma_mgf_bl == YES) switch_to_yes = YES;
 
-  For(site,data->init_len)
+  assert(first_site_pos < data->init_len);
+  
+  for(site=first_site_pos;site<data->init_len;++site)
     {
       Set_Model_Parameters(mod);
 
@@ -6878,12 +7280,21 @@ void Evolve(calign *data, t_mod *mod, t_tree *tree)
 
       /*   } */
 
-      For(i,2*tree->n_otu-3) Update_PMat_At_Given_Edge(tree->a_edges[i],tree);
+      for(i=0;i<2*tree->n_otu-3;++i) Update_PMat_At_Given_Edge(tree->a_edges[i],tree);
 
       /* Pick the root nucleotide/aa */
       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\u2022 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],
@@ -6931,7 +7342,6 @@ int Pick_State(int n, phydbl *prob)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Evolve_Recur(t_node *a, t_node *d, t_edge *b, int a_state, int r_class, int site_num, calign *gen_data, t_mod *mod, t_tree *tree)
 {
   int d_state;
@@ -6963,7 +7373,7 @@ void Evolve_Recur(t_node *a, t_node *d, t_edge *b, int a_state, int r_class, int
   else
     {
       int i;
-      For(i,3)
+      for(i=0;i<3;i++)
         if(d->v[i] != a)
           Evolve_Recur(d,d->v[i],d->b[i],
                        d_state,r_class,site_num,gen_data,
@@ -6988,32 +7398,32 @@ void Site_Diversity(t_tree *tree)
   
   For(i,2*tree->n_otu-3)
     {
-      For(j,ns)
+      for(j=0;j<ns;j++)
         {
           tree->a_edges[i]->div_post_pred_left[j] = 0;
           tree->a_edges[i]->div_post_pred_rght[j] = 0;
         }
     }
   
-  For(i,tree->n_pattern)
+  for(i=0;i<tree->n_pattern;i++)
     {
       For(j,2*tree->n_otu-3)
         {
           Binary_Decomposition(tree->a_edges[j]->ui_l[i],div,ns);
           sum = 0;
-          For(k,ns) sum += div[k];
+          for(k=0;k<ns;k++) sum += div[k];
           tree->a_edges[j]->div_post_pred_left[sum-1] += tree->data->wght[i];
           
           Binary_Decomposition(tree->a_edges[j]->ui_r[i],div,ns);
           sum = 0;
-          For(k,ns) sum += div[k];
+          for(k=0;k<ns;k++) sum += div[k];
           tree->a_edges[j]->div_post_pred_rght[sum-1] += tree->data->wght[i];
         }
     }
   
   /*   For(j,2*tree->n_otu-3) */
   /*     { */
-  /*       PhyML_Printf("\n. Edge %4d   div_left = %4d %4d %4d %4d -- div_rght = %4d %4d %4d %4d", */
+  /*       PhyML_Printf("\n\u2022 Edge %4d   div_left = %4d %4d %4d %4d -- div_rght = %4d %4d %4d %4d", */
   /* 	     j, */
   /* 	     tree->a_edges[j]->div_post_pred_left[0], */
   /* 	     tree->a_edges[j]->div_post_pred_left[1], */
@@ -7039,7 +7449,7 @@ void Site_Diversity_Post(t_node *a, t_node *d, t_edge *b, t_tree *tree)
     {
       int i;
 
-      For(i,3)
+      for(i=0;i<3;i++)
         if(d->v[i] != a)
           Site_Diversity_Post(d,d->v[i],d->b[i],tree);
       
@@ -7058,7 +7468,7 @@ void Site_Diversity_Pre(t_node *a, t_node *d, t_edge *b, t_tree *tree)
     {
       int i;
 
-      For(i,3)
+      for(i=0;i<3;i++)
     if(d->v[i] != a)
       {
         Subtree_Union(d,d->b[i],tree);
@@ -7084,7 +7494,7 @@ void Subtree_Union(t_node *n, t_edge *b_fcus, t_tree *tree)
 */
 
   int site;
-  unsigned int *ui, *ui_v1, *ui_v2;
+  int *ui, *ui_v1, *ui_v2;
 
   ui = ui_v1 = ui_v2 = NULL;
 
@@ -7117,7 +7527,7 @@ void Subtree_Union(t_node *n, t_edge *b_fcus, t_tree *tree)
       (n->b[b_fcus->r_v2]->ui_l);
     }
 
-  For(site,tree->n_pattern) ui[site] = ui_v1[site] | ui_v2[site];
+  for(site=0;site<tree->n_pattern;site++) ui[site] = ui_v1[site] | ui_v2[site];
 
 }
 
@@ -7129,7 +7539,7 @@ void Binary_Decomposition(int value, int *bit_vect, int size)
 {
   int i,cumul;
 
-  For(i,size) bit_vect[i] = 0;
+  for(i=0;i<size;i++) bit_vect[i] = 0;
 
   cumul = 0;
   for(i=size-1;i>=0;i--)
@@ -7183,7 +7593,7 @@ phydbl Univariate_Kernel_Density_Estimate(phydbl where, phydbl *x, int sample_si
   cons = (1./sample_size) * (1./h) * (1./sqrt2pi);
 
   density = .0;
-  For(i,sample_size) density += EXP(-0.5 * POW((x[i] - where)/h,2));
+  for(i=0;i<sample_size;i++) density += exp(-0.5 * POW((x[i] - where)/h,2));
   density *= cons;
 
   return density;
@@ -7212,26 +7622,26 @@ phydbl Multivariate_Kernel_Density_Estimate(phydbl *where, phydbl **x, int sampl
 
   _2pi = 6.283185;
 
-  For(i,vect_size)
+  for(i=0;i<vect_size;i++)
     {
       sd = SQRT(Var(x[i],sample_size));
 /*       h[i] = POW(4./(vect_size+2.),1./(vect_size+4)) * sd * POW(sample_size,-1./(vect_size+4)); */
       h[i] = sd * POW(sample_size,-1./(vect_size+4));
-/*       PhyML_Printf("\n. sd = %f, h[i] = %f",sd,h[i]); */
+/*       PhyML_Printf("\n\u2022 sd = %f, h[i] = %f",sd,h[i]); */
     }
 
   cons = sample_size;
-  For(i,vect_size) cons *= h[i];
+  for(i=0;i<vect_size;i++) cons *= h[i];
   cons *= POW(_2pi,vect_size/2.);
   cons = 1./cons;
 
   density = .0;
-  For(i,sample_size)
+  for(i=0;i<sample_size;i++)
     {
       tmp = 1.0;
-      For(j,vect_size)
+      for(j=0;j<vect_size;j++)
     {
-      tmp *= EXP(-0.5 * POW((x[j][i] - where[j])/h[j],2));
+      tmp *= exp(-0.5 * POW((x[j][i] - where[j])/h[j],2));
     }
       density += tmp;
     }
@@ -7255,7 +7665,7 @@ phydbl Var(phydbl *x, int n)
   mean = Mean(x,n);
 
   sum2 = .0;
-  For(i,n) sum2 += x[i] * x[i];
+  for(i=0;i<n;i++) sum2 += x[i] * x[i];
 
   return (1./n) * (sum2 - n * POW(mean,2));
 }
@@ -7271,7 +7681,7 @@ phydbl Mean(phydbl *x, int n)
 
   sum = .0;
 
-  For(i,n) sum += x[i];
+  for(i=0;i<n;i++) sum += x[i];
 
   return sum / n;
 }
@@ -7279,7 +7689,6 @@ phydbl Mean(phydbl *x, int n)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Best_Of_NNI_And_SPR(t_tree *tree)
 {
   if(tree->mod->s_opt->random_input_tree)
@@ -7288,35 +7697,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 +7727,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,36 +7759,39 @@ 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_Partial_Lk_Tips_Double(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];
+      Init_Partial_Pars_Tips(tree);
+      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 */
       Lk(NULL,tree);
       if(FABS(tree->c_lnL - best_lnL) > tree->mod->s_opt->min_diff_lk_local)
         {
-          PhyML_Printf("\n. best_lnL = %f, c_lnL = %f",best_lnL,tree->c_lnL);
-          PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__);
+          PhyML_Printf("\n\u2022 best_lnL = %f, c_lnL = %f",best_lnL,tree->c_lnL);
+          PhyML_Printf("\n\u2022 Err in file %s at line %d\n",__FILE__,__LINE__);
           Warn_And_Exit("");
         }
 
-      if(tree->mod->s_opt->print)
+      if(tree->verbose > VL0)
         {
-          PhyML_Printf("\n\n. Log likelihood obtained after NNI moves : %f",nni_lnL);
-          PhyML_Printf("\n. Log likelihood obtained after SPR moves : %f",spr_lnL);
+          PhyML_Printf("\n\n\u2022 Log likelihood obtained after NNI moves : %f",nni_lnL);
+          PhyML_Printf("\n\u2022 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);
@@ -7449,8 +7848,8 @@ int Polint(phydbl *xa, phydbl *ya, int n, phydbl x, phydbl *y, phydbl *dy)
        w=c[i+1]-d[i];
        if((den=ho-hp) < SMALL && (den=ho-hp) > -SMALL )
          {
-/* 	       Rprintf("\n. Error in routine POLINT.\n"); */
-           Exit("\n. Error in routine POLINT.\n");
+/* 	       Rprintf("\n\u2022 Error in routine POLINT.\n"); */
+           Exit("\n\u2022 Error in routine POLINT.\n");
            return(-1);
          }
        den=w/den;
@@ -7476,7 +7875,7 @@ void JF(t_tree *tree)
   PhyML_Printf("\n\nSITES LKS:\n");
   int n_patterns = (int)FLOOR(tree->n_pattern);
   int site=0;
-  For(site,n_patterns) {
+  for(site=0;site<n_patterns;site++) {
     int wei=0;
     For(wei,tree->data->wght[site]) {
       PhyML_Printf("%f\n",tree->c_lnL_sorted[site] / tree->data->wght[site]);
@@ -7489,10 +7888,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);
+        }
     }
 
 
@@ -7501,7 +7900,7 @@ void JF(t_tree *tree)
 /*   PhyML_Printf("\n\nSITES LKS:\n"); */
 /*   int n_patterns = (int)FLOOR(tree->n_pattern); */
 /*   int site=0; */
-/*   For(site,n_patterns) { */
+/*   for(site=0;site<n_patterns;site++) { */
 /*     int wei=0; */
 /*     For(wei,tree->data->wght[site]) { */
 /*       PhyML_Printf("%f\n",tree->c_lnL_sorted[site] / tree->data->wght[site]); */
@@ -7525,7 +7924,6 @@ void JF(t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 t_tree *Dist_And_BioNJ(calign *cdata, t_mod *mod, option *io)
 {
   t_tree *tree;
@@ -7533,15 +7931,13 @@ t_tree *Dist_And_BioNJ(calign *cdata, t_mod *mod, option *io)
 
   if(mod->s_opt->random_input_tree == NO)
     {
-      if(!io->quiet) PhyML_Printf("\n. Computing pairwise distances...");
+      if(!io->quiet) PhyML_Printf("\n\u2022 Computing pairwise distances...");
 
       mat = ML_Dist(cdata,mod);
       Fill_Missing_Dist(mat);
 
-      if(!io->quiet) PhyML_Printf("\n\n. Building BioNJ tree...");
-      
-      mat->tree = Make_Tree_From_Scratch(cdata->n_otu,cdata);
-      
+      if(!io->quiet) PhyML_Printf("\n\n\u2022 Building BioNJ tree...");
+      mat->tree = Make_Tree_From_Scratch(cdata->n_otu,cdata);      
       Bionj(mat);
       
       tree      = mat->tree;
@@ -7559,20 +7955,16 @@ t_tree *Dist_And_BioNJ(calign *cdata, t_mod *mod, option *io)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-void Add_BioNJ_Branch_Lengths(t_tree *tree, calign *cdata, t_mod *mod)
+void Add_BioNJ_Branch_Lengths(t_tree *tree, calign *cdata, t_mod *mod, matrix *mat)
 {
-  matrix *mat;
-
-  PhyML_Printf("\n");
-  PhyML_Printf("\n. Computing branch length estimates...\n");
-
+  short unsigned int freemat = NO;
+  if(mat == NULL) freemat = YES;
   Connect_CSeqs_To_Nodes(cdata,mod->io,tree);
-  mat = ML_Dist(cdata,mod);
+  if(mat == NULL) mat = ML_Dist(cdata,mod);
   mat->tree = tree;
   mat->method = 0;
   Bionj_Br_Length(mat);
-
-  Free_Mat(mat);
+  if(freemat == YES) Free_Mat(mat);
 }
 
 //////////////////////////////////////////////////////////////
@@ -7600,8 +7992,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);
@@ -7639,7 +8029,6 @@ char *Bootstrap_From_String(char *s_tree, calign *cdata, t_mod *mod, option *io)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 char *aLRT_From_String(char *s_tree, calign *cdata, t_mod *mod, option *io)
 {
   t_tree *tree;
@@ -7662,8 +8051,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 +8093,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);
@@ -7715,7 +8100,7 @@ void Prepare_Tree_For_Lk(t_tree *tree)
   Make_Spr_List(tree);
   Make_Best_Spr(tree);
 
-  if(tree->is_mixt_tree) MIXT_Prepare_Tree_For_Lk(tree);
+  if(tree->is_mixt_tree == YES) MIXT_Prepare_Tree_For_Lk(tree);
 }
 
 //////////////////////////////////////////////////////////////
@@ -7725,12 +8110,12 @@ void Find_Common_Tips(t_tree *tree1, t_tree *tree2)
 {
   int i,j;
 
-  For(i,tree1->n_otu) tree1->a_nodes[i]->common = 0;
-  For(i,tree2->n_otu) tree2->a_nodes[i]->common = 0;
+  for(i=0;i<tree1->n_otu;i++) tree1->a_nodes[i]->common = 0;
+  for(i=0;i<tree2->n_otu;i++) tree2->a_nodes[i]->common = 0;
 
-  For(i,tree1->n_otu)
+  for(i=0;i<tree1->n_otu;i++)
     {
-      For(j,tree2->n_otu)
+      for(j=0;j<tree2->n_otu;j++)
     {
       if(!strcmp(tree1->a_nodes[i]->name,tree2->a_nodes[j]->name))
         {
@@ -7783,7 +8168,7 @@ void Dist_To_Root_Pre(t_node *a, t_node *d, t_edge *b, t_tree *tree)
   if(d->tax) return;
   else
     {
-      For(i,3)
+      for(i=0;i<3;i++)
     if((d->v[i] != a) && (d->b[i] != tree->e_root))
       Dist_To_Root_Pre(d,d->v[i],d->b[i],tree);
     }
@@ -7839,7 +8224,7 @@ t_node *Find_Lca_Pair_Of_Nodes(t_node *n1, t_node *n2, t_tree *tree)
 
   if(!tree->n_root)
     {
-      PhyML_Printf("\n. The tree must be rooted in this function.");
+      PhyML_Printf("\n== The tree must be rooted in this function.");
       Generic_Exit(__FILE__,__LINE__,__FUNCTION__);    
     }
 
@@ -7864,7 +8249,7 @@ t_node *Find_Lca_Pair_Of_Nodes(t_node *n1, t_node *n2, t_tree *tree)
 
   if(lca == NULL)
     {
-      PhyML_Printf("\n. %s",Write_Tree(tree,NO));
+      PhyML_Printf("\n\u2022 %s",Write_Tree(tree,NO));
       Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
     }
   return lca;
@@ -7883,53 +8268,72 @@ 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 *));
+  for(i=0;i<node_list_size;i++) 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)
+  
+  for(i=0;i<node_list_size;i++)
     {
       if(!Get_List_Of_Ancestors(node_list[i],list[i],size+i,tree))
         {
-          For(i,node_list_size) PhyML_Printf("\n== %s",node_list[i]->name);
+          for(i=0;i<node_list_size;i++) PhyML_Printf("\n== %s",node_list[i]->name);
           Generic_Exit(__FILE__,__LINE__,__FUNCTION__);    
         }
     }
 
+  /* for(i=0;i<node_list_size;i++) */
+  /*   { */
+  /*     int j; */
+  /*     PhyML_Printf("\n\u2022 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\u2022  > %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;
-          
+          for(i=0;i<node_list_size-1;i++)
+            {
+              assert(list[i][size[i]-1]);
+              assert(list[i+1][size[i+1]-1]);
+              /* PhyML_Printf("\n\u2022 %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\u2022 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)
+          for(i=0;i<node_list_size;i++)
             {
               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
     {
       lca = node_list[0];
     }
   
-  For(i,node_list_size) Free(list[i]);
+  for(i=0;i<node_list_size;i++) Free(list[i]);
   Free(list);
   Free(size);
 
+  /* PhyML_Printf("\n\u2022 LCA: %d",lca->num); */
+
   return lca;
 }
 
@@ -7998,14 +8402,14 @@ void Time_To_Branch(t_tree *tree)
 void Time_To_Branch_Pre(t_node *a, t_node *d, t_tree *tree)
 {
   int i;
-
+  
   /* tree->rates->cur_l[d->num] = FABS(tree->rates->nd_t[d->num] - tree->rates->nd_t[a->num]); */
   tree->rates->cur_l[d->num] = tree->rates->nd_t[d->num] - tree->rates->nd_t[a->num];
-
+  
   if(d->tax) return;
   else
     {
-      For(i,3)
+      for(i=0;i<3;i++)
         if((d->v[i] != a) && (d->b[i] != tree->e_root))
           Time_To_Branch_Pre(d,d->v[i],tree);
     }
@@ -8014,9 +8418,6 @@ void Time_To_Branch_Pre(t_node *a, t_node *d, t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
 // Assume an ultrametric tree.
 void Branch_To_Time(t_tree *tree)
 {
@@ -8042,13 +8443,13 @@ void Branch_To_Time_Pre(t_node *a, t_node *d, t_tree *tree)
     }
   else
     {
-      For(i,3)
+      for(i=0;i<3;i++)
     if((d->v[i] != a) && (d->b[i] != tree->e_root))
       {
             Branch_To_Time_Pre(d,d->v[i],tree);
           }
 
-      For(i,3)
+      for(i=0;i<3;i++)
     if((d->v[i] != a) && (d->b[i] != tree->e_root))
       {
             tree->rates->nd_t[d->num] = tree->rates->nd_t[d->v[i]->num] - d->b[i]->l->v;
@@ -8083,7 +8484,7 @@ void Branch_Lengths_To_Rate_Lengths_Pre(t_node *a, t_node *d, t_tree *tree)
   if(d->tax) return;
   else
     {
-      For(i,3)
+      for(i=0;i<3;i++)
     if((d->v[i] != a) && (d->b[i] != tree->e_root))
       Branch_Lengths_To_Rate_Lengths_Pre(d,d->v[i],tree);
     }
@@ -8092,7 +8493,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;
@@ -8104,13 +8504,13 @@ int Find_Clade(char **tax_name_list, int list_size, t_tree *tree)
   tax_num_list = (int *)mCalloc(list_size,sizeof(int));
   tax_node_list = (t_node **)mCalloc(list_size,sizeof(t_node *));
 
-  For(i,list_size) tax_num_list[i] = -1;
+  for(i=0;i<list_size;i++) tax_num_list[i] = -1;
 
   n_matches = 0;
 
-  For(i,list_size)
+  for(i=0;i<list_size;i++)
     {
-      For(j,tree->n_otu)
+      for(j=0;j<tree->n_otu;j++)
         {
           if(!strcmp(tax_name_list[i],tree->a_nodes[j]->name))
             {
@@ -8130,44 +8530,12 @@ int Find_Clade(char **tax_name_list, int list_size, t_tree *tree)
     }
 
   lca = Find_Lca_Clade(tax_node_list,n_matches,tree);
-  if(lca) return lca->num;
-  else    return -1;
-
-/*   if(list_size == tree->n_otu) /\* Root node *\/ */
-/*     { */
-/*       int i,j; */
-/*       int score; */
-
-/*       score = 0; */
-/*       For(i,list_size) */
-/* 	{ */
-/* 	  For(j,tree->n_otu) */
-/* 	    { */
-/* /\* 	      if(!strcmp(tax_name_list[i],tree->a_nodes[j]->name)) score++; *\/ */
-/* 	      if(tax_num_list[i] == tree->a_nodes[j]->num) score++; */
-/* 	    } */
-/* 	} */
-
-/*       Free(tax_num_list); */
-/*       if(score == tree->n_otu) return tree->n_root->num; */
-/*       else return -1; */
-/*     } */
-/*   else */
-/*     { */
-/*       int num; */
-/*       num = -1; */
-/*       Free_Bip(tree); */
-/*       Alloc_Bip(tree); */
-/*       Get_Bip(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree); */
-/*       Find_Clade_Pre(tree->n_root,tree->n_root->v[2],tax_num_list,list_size,&num,tree); */
-/*       Find_Clade_Pre(tree->n_root,tree->n_root->v[1],tax_num_list,list_size,&num,tree); */
-/*       Free(tax_num_list); */
-/*       return num; */
-/*     } */
 
-  Free(tax_node_list);
   Free(tax_num_list);
-  return -1;
+  Free(tax_node_list);
+
+  if(lca) return lca->num;
+  else    return -1;
 }
 
 //////////////////////////////////////////////////////////////
@@ -8180,7 +8548,7 @@ void Find_Clade_Pre(t_node *a, t_node *d, int *tax_num_list, int list_size, int
   int score;
 
 
-  For(i,3)
+  for(i=0;i<3;i++)
     if((d->v[i] == a) || (d->b[i] == tree->e_root))
       {
     if(list_size == d->bip_size[i])
@@ -8188,7 +8556,7 @@ void Find_Clade_Pre(t_node *a, t_node *d, int *tax_num_list, int list_size, int
         score = 0;
         For(j,d->bip_size[i])
           {
-        For(k,list_size)
+        for(k=0;k<list_size;k++)
           {
             if(tax_num_list[k] == d->bip_node[i][j]->num)
               {
@@ -8204,9 +8572,9 @@ void Find_Clade_Pre(t_node *a, t_node *d, int *tax_num_list, int list_size, int
 
   if(d->tax) return;
   else
-    For(i,3)
+    for(i=0;i<3;i++)
       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);
 }
 
 //////////////////////////////////////////////////////////////
@@ -8288,7 +8656,8 @@ t_edge *Find_Root_Edge(FILE *fp_input_tree, t_tree *tree)
 
   root_edge = tree->a_edges[i];
 
-  For(i,NODE_DEG_MAX) Free(subs[i]);
+  i = 0;
+  while(subs[i] != NULL) Free(subs[i++]);
   Free(subs);
   Free(line);
 
@@ -8311,7 +8680,7 @@ void Copy_Tree_Topology_With_Labels(t_tree *ori, t_tree *cpy)
 
   For(i,2*ori->n_otu-2)
     {
-      For(j,3)
+      for(j=0;j<3;j++)
         {
           if(ori->a_nodes[i]->v[j])
             {
@@ -8330,7 +8699,7 @@ void Copy_Tree_Topology_With_Labels(t_tree *ori, t_tree *cpy)
       cpy->a_edges[i]->l->v = ori->a_edges[i]->l->v;
     }
 
-  For(i,ori->n_otu)
+  for(i=0;i<ori->n_otu;i++)
     {
       cpy->a_nodes[i]->tax = 1;
       strcpy(cpy->a_nodes[i]->name,ori->a_nodes[i]->name);
@@ -8478,19 +8847,16 @@ void Set_Model_Name(t_mod *mod)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Adjust_Min_Diff_Lk(t_tree *tree)
 {
-
   if(sizeof(phydbl) == 4)
     {
       int exponent;
       exponent = (int)FLOOR(log10(FABS(tree->c_lnL)));
       tree->mod->s_opt->min_diff_lk_local = POW(10.,exponent - FLT_DIG + 1);
-      tree->mod->s_opt->min_diff_lk_local  = tree->mod->s_opt->min_diff_lk_local;
-      tree->mod->s_opt->min_diff_lk_move   = tree->mod->s_opt->min_diff_lk_local;
+      tree->mod->s_opt->min_diff_lk_move  = tree->mod->s_opt->min_diff_lk_local;
     }
-/*   PhyML_Printf("\n. Exponent = %d Precision = %E DIG = %d",exponent,tree->mod->s_opt->min_diff_lk_local,FLT_DIG); */
+/*   PhyML_Printf("\n\u2022 Exponent = %d Precision = %E DIG = %d",exponent,tree->mod->s_opt->min_diff_lk_local,FLT_DIG); */
 }
 
 //////////////////////////////////////////////////////////////
@@ -8507,7 +8873,7 @@ void Translate_Tax_Names(char **tax_names, t_tree *tree)
   int i;
   int tax_num;
 
-  For(i,tree->n_otu)
+  for(i=0;i<tree->n_otu;i++)
     {
       tax_num = strtol(tree->a_nodes[i]->name,NULL,10);
       tree->a_nodes[i]->name = tax_names[tax_num-1];
@@ -8565,7 +8931,7 @@ void Get_Best_Root_Position(t_tree *tree)
 
   if(strstr(tree->a_nodes[0]->name,"*"))
     {
-      /* PhyML_Printf("\n. Found outgroup taxon: %s",tree->a_nodes[0]->name); */
+      /* PhyML_Printf("\n\u2022 Found outgroup taxon: %s",tree->a_nodes[0]->name); */
       tree->a_nodes[0]->s_ingrp[0]  = 0;
       tree->a_nodes[0]->s_outgrp[0] = 1;
       has_outgrp = YES;
@@ -8581,6 +8947,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]);
@@ -8590,10 +8957,10 @@ void Get_Best_Root_Position(t_tree *tree)
       s = s_max = 0.0;
       For(i,2*tree->n_otu-2)
         {
-          For(j,3)
+          for(j=0;j<3;j++)
             {
               s = (tree->a_nodes[i]->s_outgrp[j]+eps) / (tree->a_nodes[i]->s_ingrp[j] + eps) ;
-              /* printf("\n. [%d %d] %d %d",i,j,tree->a_nodes[i]->s_outgrp[j],tree->a_nodes[i]->s_ingrp[j]); */
+              /* printf("\n\u2022 [%d %d] %d %d",i,j,tree->a_nodes[i]->s_outgrp[j],tree->a_nodes[i]->s_ingrp[j]); */
               if(s > s_max)
                 {
                   s_max = s;
@@ -8620,7 +8987,7 @@ void Get_Best_Root_Position_Post(t_node *a, t_node *d, int *has_outgrp, t_tree *
       if(strstr(d->name,"*"))
         {
           *has_outgrp = YES;
-          /* PhyML_Printf("\n. Found outgroup taxon: %s",d->name); */
+          /* PhyML_Printf("\n\u2022 Found outgroup taxon: %s",d->name); */
           d->s_ingrp[0]  = NO;
           d->s_outgrp[0] = YES;
         }
@@ -8635,7 +9002,7 @@ void Get_Best_Root_Position_Post(t_node *a, t_node *d, int *has_outgrp, t_tree *
     {
       int i;
       
-      For(i,3)
+      for(i=0;i<3;i++)
         if(d->v[i] != a && (d->b[i] != tree->e_root))
           Get_Best_Root_Position_Post(d,d->v[i],has_outgrp,tree);
       
@@ -8662,7 +9029,7 @@ void Get_Best_Root_Position_Pre(t_node *a, t_node *d, t_tree *tree)
     {
       int i;
 
-      For(i,3)
+      for(i=0;i<3;i++)
     if(d->v[i] != a && (d->b[i] != tree->e_root))
       {
         Get_OutIn_Scores(d->v[i],d);
@@ -8685,7 +9052,7 @@ void Get_OutIn_Scores(t_node *a, t_node *d)
 
   d_a = v1_d = v2_d = -1;
   d_v1 = d_v2 = -1;
-  For(i,3)
+  for(i=0;i<3;i++)
     {
       if(d->v[i] != a)
     {
@@ -8694,9 +9061,9 @@ void Get_OutIn_Scores(t_node *a, t_node *d)
     }
     }
 
-  For(i,3) if(d->v[i] == a) { d_a = i; break; }
-  For(i,3) if(d->v[d_v1]->v[i] == d) { v1_d = i; break; }
-  For(i,3) if(d->v[d_v2]->v[i] == d) { v2_d = i; break; }
+  for(i=0;i<3;i++) if(d->v[i] == a) { d_a = i; break; }
+  for(i=0;i<3;i++) if(d->v[d_v1]->v[i] == d) { v1_d = i; break; }
+  for(i=0;i<3;i++) if(d->v[d_v2]->v[i] == d) { v2_d = i; break; }
 
   d->s_ingrp[d_a] =
     d->v[d_v1]->s_ingrp[v1_d] +
@@ -8750,52 +9117,50 @@ int Check_Sequence_Name(char *s)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 int Scale_Subtree_Height(t_node *a, phydbl K, phydbl floor, int *n_nodes, t_tree *tree)
 {
   phydbl new_height;
 
+  if(a->tax == YES) return 0;
+  
   *n_nodes = 0;
 
   new_height = .0;
 
-
-  if(!(tree->rates->nd_t[a->num] > floor))
-    new_height = K*(tree->rates->nd_t[a->num]-floor)+floor;
+  if(!(tree->rates->nd_t[a->num] > floor)) new_height = K*(tree->rates->nd_t[a->num]-floor)+floor;
 
   if(a == tree->n_root)
     {
       tree->rates->nd_t[tree->n_root->num] = new_height;
       *n_nodes = 1;
-
+      
       Scale_Node_Heights_Post(tree->n_root,tree->n_root->v[2],K,floor,n_nodes,tree);
       Scale_Node_Heights_Post(tree->n_root,tree->n_root->v[1],K,floor,n_nodes,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;
-    }
-
-      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);
-      }
+        {
+          tree->rates->nd_t[a->num] = new_height;
+          *n_nodes = 1;
+        }
+      
+      for(i=0;i<3;i++)
+        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)
@@ -8803,19 +9168,7 @@ void Scale_Node_Heights_Post(t_node *a, t_node *d, phydbl K, phydbl floor, int *
       Generic_Exit(__FILE__,__LINE__,__FUNCTION__);    
     }
 
-  if(d->tax)
-    {
-      if(!(tree->rates->nd_t[d->num] > floor))
-        {
-          /* Scaling does not change the node height here
-             but, in theory this tip is among the scaled
-             nodes. Therefore needs to count it in for
-             working out correct Hastings ratios
-          */
-          /* *n_nodes = *n_nodes+1; */
-        }
-      return;
-    }
+  if(d->tax) return;
   else
     {
       int i;
@@ -8824,7 +9177,7 @@ void Scale_Node_Heights_Post(t_node *a, t_node *d, phydbl K, phydbl floor, int *
          it then becomes possible for nodes with different floor values
          to have their orders interverted (i.e., ancestor below descendant)
       */
-      if(!(tree->rates->nd_t[d->num] > floor))
+      if((tree->rates->nd_t[d->num] > floor) == NO) // If node is strictly older than floor
         {
           tree->rates->nd_t[d->num] = K*(tree->rates->nd_t[d->num]-floor)+floor;
           *n_nodes = *n_nodes+1;
@@ -8832,14 +9185,14 @@ 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("");
         }
       
-      For(i,3)
+      for(i=0;i<3;i++)
         if(d->v[i] != a && d->b[i] != tree->e_root)
           Scale_Node_Heights_Post(d,d->v[i],K,floor,n_nodes,tree);
       
@@ -8853,7 +9206,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;
 
@@ -8865,7 +9218,7 @@ int Scale_Subtree_Rates(t_node *a, phydbl mult, int *n_nodes, t_tree *tree)
     }
   else
     {
-      For(i,3) if((a->v[i] != a->anc) &&
+      for(i=0;i<3;i++) if((a->v[i] != a->anc) &&
           (a->b[i] != tree->e_root) &&
           (res == 1)) res = Scale_Subtree_Rates_Post(a,a->v[i],mult,n_nodes,tree);
       return res;
@@ -8878,35 +9231,29 @@ int Scale_Subtree_Rates(t_node *a, phydbl mult, int *n_nodes, t_tree *tree)
 int Scale_Subtree_Rates_Post(t_node *a, t_node *d, phydbl mult, int *n_nodes, t_tree *tree)
 {
 
-  if(tree->rates->model_log_rates == YES)
-    {
-      tree->rates->br_r[d->num] += LOG(mult);
-    }
-  else
-    {
-      tree->rates->br_r[d->num] *= mult;
-    }
+  if(tree->rates->model_log_rates == YES) tree->rates->br_r[d->num] += log(mult);
+  else tree->rates->br_r[d->num] *= mult;
 
   *n_nodes = *n_nodes+1;
-
+  
   if(tree->rates->br_r[d->num] < tree->rates->min_rate) return 0;
   if(tree->rates->br_r[d->num] > tree->rates->max_rate) return 0;
-
+  
   if(d->tax) return 1;
   else
     {
       int i,res;
-
+      
       res = 1;
-      For(i,3)
-    {
-      if((d->v[i] != a) &&
-         (d->b[i] != tree->e_root) &&
-         (res == 1))
+      for(i=0;i<3;i++)
         {
-          res = Scale_Subtree_Rates_Post(d,d->v[i],mult,n_nodes,tree);
+          if((d->v[i] != a) &&
+             (d->b[i] != tree->e_root) &&
+             (res == 1))
+            {
+              res = Scale_Subtree_Rates_Post(d,d->v[i],mult,n_nodes,tree);
+            }
         }
-    }
       return res;
     }
 }
@@ -8937,7 +9284,7 @@ void Get_Node_Ranks_Pre(t_node *a, t_node *d,t_tree *tree)
     {
       int i;
 
-      For(i,3)
+      for(i=0;i<3;i++)
     {
       if(d->v[i] != a && d->b[i] != tree->e_root)
         {
@@ -8953,7 +9300,7 @@ void Get_Node_Ranks_Pre(t_node *a, t_node *d,t_tree *tree)
 void Log_Br_Len(t_tree *tree)
 {
   int i;
-  For(i,2*tree->n_otu-3) tree->a_edges[i]->l->v = LOG(tree->a_edges[i]->l->v);
+  For(i,2*tree->n_otu-3) tree->a_edges[i]->l->v = log(tree->a_edges[i]->l->v);
 }
 
 //////////////////////////////////////////////////////////////
@@ -8969,7 +9316,7 @@ phydbl Diff_Lk_Norm_At_Given_Edge(t_edge *b, t_tree *tree)
   dim = 2*tree->n_otu-3;
   sum = 0.0;
 
-  For(i,tree->n_short_l)
+  for(i=0;i<tree->n_short_l;i++)
     {
       b->l->v = tree->short_l[i];
 
@@ -8991,18 +9338,16 @@ phydbl Diff_Lk_Norm_At_Given_Edge(t_edge *b, t_tree *tree)
   return(sum);
 }
 
-
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-
 void Adjust_Variances(t_tree *tree)
 {
   int i;
   phydbl new_diff,curr_diff;
 
   Make_Short_L(tree);
-  For(i,tree->n_short_l)
+  for(i=0;i<tree->n_short_l;i++)
     {
       tree->short_l[i] = tree->mod->l_min + i*(0.1 - tree->mod->l_min)/tree->n_short_l;
     }
@@ -9011,44 +9356,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);
+        }
     }
 }
 
@@ -9134,7 +9479,7 @@ phydbl Reflect(phydbl x, phydbl l, phydbl u)
   do
     {
       rounds++;
-      /* printf("\n. l=%f u=%f x=%f",l,u,x); */
+      /* printf("\n\u2022 l=%f u=%f x=%f",l,u,x); */
       if(x > u || x < l)
     {
       if(x > u) x = x - 2.*(x - u);
@@ -9147,8 +9492,8 @@ phydbl Reflect(phydbl x, phydbl l, phydbl u)
 
   if(rounds == 100 && (x > u || x < l))
     {
-      PhyML_Printf("\n. u=%f l=%f x=%f",u,l,x);
-      PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__);
+      PhyML_Printf("\n\u2022 u=%f l=%f x=%f",u,l,x);
+      PhyML_Printf("\n\u2022 Err in file %s at line %d\n",__FILE__,__LINE__);
       Exit("\n");
     }
 
@@ -9214,9 +9559,9 @@ int Check_Topo_Constraints(t_tree *big_tree, t_tree *small_tree)
   diffs = Compare_Bip(small_tree,big_tree_cpy,NO);
 
   /* printf("\n"); */
-  /* printf("\n. %s",Write_Tree(big_tree_cpy,NO)); */
-  /* printf("\n. %s",Write_Tree(small_tree,NO)); */
-  /* printf("\n. diffs=%d",diffs); */
+  /* printf("\n\u2022 %s",Write_Tree(big_tree_cpy,NO)); */
+  /* printf("\n\u2022 %s",Write_Tree(small_tree,NO)); */
+  /* printf("\n\u2022 diffs=%d",diffs); */
 
 
   Free_Tree(big_tree_cpy);
@@ -9245,9 +9590,9 @@ void Prune_Tree(t_tree *big_tree, t_tree *small_tree)
   residual_edges = (t_edge **)mCalloc(big_tree->n_otu,sizeof(t_edge *));
 
   n_pruned_nodes = 0;
-  For(i,big_tree->n_otu)
+  for(i=0;i<big_tree->n_otu;i++)
     {
-      For(j,small_tree->n_otu)
+      for(j=0;j<small_tree->n_otu;j++)
         if(!strcmp(small_tree->a_nodes[j]->name,big_tree->a_nodes[i]->name))
           break;
       
@@ -9280,7 +9625,7 @@ void Prune_Tree(t_tree *big_tree, t_tree *small_tree)
   curr_br = 0;
   For(i,big_tree->n_otu+n_pruned_nodes)
     {
-      For(j,n_pruned_nodes)
+      for(j=0;j<n_pruned_nodes;j++)
         if(!strcmp(pruned_nodes[j]->name,big_tree->a_nodes[i]->name))
           break;
       
@@ -9298,7 +9643,7 @@ void Prune_Tree(t_tree *big_tree, t_tree *small_tree)
 
   big_tree->t_dir = (short int *)mCalloc((2*big_tree->n_otu-2)*(2*big_tree->n_otu-2),sizeof(short int));
   
-  For(i,n_pruned_nodes)
+  for(i=0;i<n_pruned_nodes;i++)
     {
       Free_Edge(residual_edges[i]);
       Free_Edge(pruned_nodes[i]->b[0]);
@@ -9329,8 +9674,8 @@ void Match_Nodes_In_Small_Tree(t_tree *small_tree, t_tree *big_tree)
 
   if(small_tree->n_otu > big_tree->n_otu)
     {
-      PhyML_Printf("\n. small_tree->n_otu=%d big_tree->n_otu=%d",small_tree->n_otu,big_tree->n_otu);
-      PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__);
+      PhyML_Printf("\n\u2022 small_tree->n_otu=%d big_tree->n_otu=%d",small_tree->n_otu,big_tree->n_otu);
+      PhyML_Printf("\n\u2022 Err in file %s at line %d\n",__FILE__,__LINE__);
       Exit("\n");
     }
 
@@ -9344,8 +9689,8 @@ void Match_Nodes_In_Small_Tree(t_tree *small_tree, t_tree *big_tree)
 
   if(!Check_Topo_Constraints(big_tree,small_tree))
     {
-      PhyML_Printf("\n. small_tree and big_tree cannot have distinct topologies.");
-      PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__);
+      PhyML_Printf("\n== small_tree and big_tree cannot have distinct topologies.");
+      PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__);
       Exit("\n");
     }
 
@@ -9354,9 +9699,9 @@ void Match_Nodes_In_Small_Tree(t_tree *small_tree, t_tree *big_tree)
 
   score = (int *)mCalloc(3,sizeof(int));
 
-  For(i,small_tree->n_otu)
+  for(i=0;i<small_tree->n_otu;i++)
     {
-      For(j,big_tree->n_otu)
+      for(j=0;j<big_tree->n_otu;j++)
     {
       if(!strcmp(small_tree->a_nodes[i]->name,big_tree->a_nodes[j]->name))
         {
@@ -9375,11 +9720,11 @@ void Match_Nodes_In_Small_Tree(t_tree *small_tree, t_tree *big_tree)
         {
           if(big_tree->a_nodes[j]->tax == NO)
         {
-          For(k,3) score[k] = 0;
+          for(k=0;k<3;k++) score[k] = 0;
 
-          For(k,3)
+          for(k=0;k<3;k++)
             {
-              For(l,3)
+              for(l=0;l<3;l++)
             {
               identical = 0;
               For(m,small_tree->a_nodes[i]->bip_size[k])
@@ -9400,7 +9745,7 @@ void Match_Nodes_In_Small_Tree(t_tree *small_tree, t_tree *big_tree)
             }
             }
 
-          /* printf("\n. [%d] [%d] %d %d %d -- %d %d %d",i,j, */
+          /* printf("\n\u2022 [%d] [%d] %d %d %d -- %d %d %d",i,j, */
           /* 	 score[0],score[1],score[2], */
           /* 	 small_tree->a_nodes[i]->bip_size[0], */
           /* 	 small_tree->a_nodes[i]->bip_size[1], */
@@ -9456,7 +9801,7 @@ void Find_Surviving_Edges_In_Small_Tree_Post(t_node *a, t_node *d, t_tree *small
     {
       int i;
 
-      For(i,3)
+      for(i=0;i<3;i++)
     {
       if(d->v[i] != a && d->b[i] != big_tree->e_root)
         {
@@ -9474,9 +9819,9 @@ void Set_Taxa_Id_Ranking(t_tree *tree)
 {
   int i,j;
 
-  For(i,tree->n_otu) tree->a_nodes[i]->id_rank = 0;
+  for(i=0;i<tree->n_otu;i++) tree->a_nodes[i]->id_rank = 0;
 
-  For(i,tree->n_otu)
+  for(i=0;i<tree->n_otu;i++)
     {
       for(j=i+1;j<tree->n_otu;j++)
     {
@@ -9486,7 +9831,7 @@ void Set_Taxa_Id_Ranking(t_tree *tree)
         tree->a_nodes[j]->id_rank++;
     }
     }
-  /* For(i,tree->n_otu) PhyML_Printf("\n. %20s %4d",tree->a_nodes[i]->name,tree->a_nodes[i]->id_rank); */
+  /* for(i=0;i<tree->n_otu;i++) PhyML_Printf("\n\u2022 %20s %4d",tree->a_nodes[i]->name,tree->a_nodes[i]->id_rank); */
 }
 
 //////////////////////////////////////////////////////////////
@@ -9541,8 +9886,8 @@ void Get_Edge_Binary_Coding_Number(t_tree *tree)
     }
 
       b->bin_cod_num = 0.;
-      For(j,list_size) b->bin_cod_num += POW(2,list[j]->id_rank);
-      /* printf("\n. %f",b->bin_cod_num); */
+      for(j=0;j<list_size;j++) b->bin_cod_num += POW(2,list[j]->id_rank);
+      /* printf("\n\u2022 %f",b->bin_cod_num); */
     }
 }
 
@@ -9610,7 +9955,7 @@ char *To_Lower_String(char *in)
 
   out = (char *)mCalloc(len+1,sizeof(char));
 
-  For(i,len) out[i] = (char)tolower(in[i]);
+  for(i=0;i<len;i++) out[i] = (char)tolower(in[i]);
 
   out[len] = '\0';
   return(out);
@@ -9629,7 +9974,7 @@ char *To_Upper_String(char *in)
 
   out = (char *)mCalloc(len+1,sizeof(char));
 
-  For(i,len)
+  for(i=0;i<len;i++)
     {
       out[i] = (char)toupper(in[i]);
     }
@@ -9654,21 +9999,21 @@ void Connect_CSeqs_To_Nodes(calign *cdata, option *io, t_tree *tree)
       Warn_And_Exit("\n== The number of tips in the tree is not the same as the number of sequences\n");
     }
   
-  For(i,MAX(n_otu_tree,n_otu_cdata))
+  for(i=0;i<n_otu_tree;i++)
     {
-      For(j,MIN(n_otu_tree,n_otu_cdata))
+      for(j=0;j<n_otu_cdata;j++)
         {          
           if(!strcmp(tree->a_nodes[i]->name,cdata->c_seq[j]->name)) break;
         }
       
-      if(j==MIN(n_otu_tree,n_otu_cdata))
+      if(j==n_otu_cdata)
         {
           PhyML_Printf("\n== Taxon '%s' was not found in sequence file '%s'.\n",
                        tree->a_nodes[i]->name,
                        io->in_align_file);
           Exit("\n");
-        }      
-      tree->a_nodes[i]->c_seq = cdata->c_seq[j];      
+        }
+      tree->a_nodes[i]->c_seq = cdata->c_seq[j];
     }
 }
 
@@ -9692,19 +10037,28 @@ void Switch_Eigen(int state, t_mod *mod)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-void Set_Both_Sides(int yesno, t_tree *mixt_tree)
+void Set_Both_Sides(int yesno, t_tree *tree)
 {
-  t_tree *tree;
+  tree->both_sides = yesno;
+  if(tree->is_mixt_tree == YES) MIXT_Set_Both_Sides(yesno,tree);
+}
 
-  tree = mixt_tree;
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
 
-  do
-    {
-      tree->both_sides = yesno;
-      tree = tree->next;
-    }
-  while(tree);
+void Set_Use_Eigen_Lr(int yesno, t_tree *tree)
+{
+  tree->use_eigen_lr = yesno;
+  if(tree->is_mixt_tree == YES) MIXT_Set_Use_Eigen_Lr(yesno,tree);
+}
 
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void Set_Update_Eigen_Lr(int yesno, t_tree *tree)
+{
+  tree->update_eigen_lr = yesno;
+  if(tree->is_mixt_tree == YES) MIXT_Set_Update_Eigen_Lr(yesno,tree);
 }
 
 //////////////////////////////////////////////////////////////
@@ -9717,10 +10071,7 @@ 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(i=0;i<tree->n_otu-1;i++)
     {
       for(j=i+1;j<tree->n_otu;j++)
         {
@@ -9748,10 +10099,10 @@ void Random_SPRs_On_Rooted_Tree(t_tree *tree)
   int err;
   int ok_dir,dir12,dir21;
 
-  /* printf("\n. >>>>>>>>>>>>>>.\n"); */
+  /* printf("\n\u2022 >>>>>>>>>>>>>>.\n"); */
   /* Print_Node(tree->n_root,tree->n_root->v[1],tree); */
   /* Print_Node(tree->n_root,tree->n_root->v[2],tree); */
-  /* printf("\n. >>>>>>>>>>>>>>."); */
+  /* printf("\n\u2022 >>>>>>>>>>>>>>."); */
   /* GEO_Update_Occup(tree->geo,tree); */
   /* GEO_Lk(tree->geo,tree); */
   /* PhyML_Printf("\n>> Init loglk: %f",tree->geo->c_lnL); */
@@ -9761,7 +10112,7 @@ void Random_SPRs_On_Rooted_Tree(t_tree *tree)
   residual = NULL;
   nouse = NULL;
   a = d = v1 = v2 = NULL;
-  For(i,tree->n_otu) // We will perform tree->n_otu random SPRs
+  for(i=0;i<tree->n_otu;i++) // We will perform tree->n_otu random SPRs
     {
       a = tree->a_nodes[Rand_Int(tree->n_otu,2*tree->n_otu-3)];
 
@@ -9773,7 +10124,7 @@ void Random_SPRs_On_Rooted_Tree(t_tree *tree)
       /* if(a == tree->n_root->v[1] || a == tree->n_root->v[2]) continue; */
 
       v1 = v2 = NULL;
-      For(j,3)
+      for(j=0;j<3;j++)
         {
           if(a->v[j] != a->anc && a->b[j] != tree->e_root)
             {
@@ -9787,7 +10138,7 @@ void Random_SPRs_On_Rooted_Tree(t_tree *tree)
       else       d = v2;
 
 
-      For(j,3) if(a->v[j] == d && a->b[j] == tree->e_root) break;
+      for(j=0;j<3;j++) if(a->v[j] == d && a->b[j] == tree->e_root) break;
       if(j != 3) continue;
 
       lim_sup = tree->rates->nd_t[d->num];
@@ -9840,7 +10191,7 @@ void Random_SPRs_On_Rooted_Tree(t_tree *tree)
               else
                 {
                   v1 = v2 = NULL;
-                  For(j,3)
+                  for(j=0;j<3;j++)
                     {
                       if(target_nd->v[j] != target_nd->anc)
                         {
@@ -9856,15 +10207,15 @@ void Random_SPRs_On_Rooted_Tree(t_tree *tree)
         }
 
       ok_dir = -1;
-      For(j,3) if(target_nd->v[j] == target_nd->anc || target_nd->b[j] == tree->e_root) ok_dir = j;
+      for(j=0;j<3;j++) if(target_nd->v[j] == target_nd->anc || target_nd->b[j] == tree->e_root) ok_dir = j;
 
       dir12 = -1;
-      For(j,3) if(tree->n_root->v[1]->v[j] == tree->n_root->v[2]) dir12 = j;
+      for(j=0;j<3;j++) if(tree->n_root->v[1]->v[j] == tree->n_root->v[2]) dir12 = j;
 
       if(dir12 == -1) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);        
 
       dir21 = -1;
-      For(j,3) if(tree->n_root->v[2]->v[j] == tree->n_root->v[1]) dir21 = j;
+      for(j=0;j<3;j++) if(tree->n_root->v[2]->v[j] == tree->n_root->v[1]) dir21 = j;
 
       if(dir21 == -1) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
 
@@ -9874,12 +10225,12 @@ void Random_SPRs_On_Rooted_Tree(t_tree *tree)
       /* d = tree->a_nodes[105]; */
       /* target_nd = tree->a_nodes[105]; */
       /* printf("\n pull %d %d target %d",a->num,d->num,target_nd->num); */
-      /* printf("\n. %d %d %d",tree->n_root->num,tree->n_root->v[1]->num,tree->n_root->v[2]->num); */
-      /* printf("\n. %d %d",tree->e_root->num,target_nd->b[ok_dir]->num); */
+      /* printf("\n\u2022 %d %d %d",tree->n_root->num,tree->n_root->v[1]->num,tree->n_root->v[2]->num); */
+      /* printf("\n\u2022 %d %d",tree->e_root->num,target_nd->b[ok_dir]->num); */
 
       Prune_Subtree(a,d,&nouse,&residual,tree);
 
-      Graft_Subtree(target_nd->b[ok_dir],a,residual,tree);
+      Graft_Subtree(target_nd->b[ok_dir],a,NULL,residual,NULL,tree);
 
       tree->rates->nd_t[a->num] = new_t;
 
@@ -9928,446 +10279,95 @@ void Random_SPRs_On_Rooted_Tree(t_tree *tree)
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-/*     |
-       |
-       |d
-      /  \
-     /    \
-    /      \b
-   /        \
-  /          \x (either n_v1 or n_v2)
-
-  Returns p_lk and sum_scale for subtree with x as root, Pij for edge b
-*/
 
-void Set_P_Lk_One_Side(phydbl **Pij, phydbl **p_lk,  int **sum_scale, t_node *d, t_edge *b, t_tree *tree
-#ifdef BEAGLE
-                       , int* child_p_idx, int* Pij_idx
-#endif
-                                              )
-{
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
 
-  if(Pij) {
-      *Pij = b->Pij_rr;
-#ifdef BEAGLE
-      *Pij_idx = b->Pij_rr_idx;
-#endif
-  }
+void Best_Root_Position_IL_Model(t_tree *tree)
+{
 
-  if(!d->tax)//if d is not a tip
+  if(tree->n_root)
     {
-      //Does d lie on "left" or "right" of the branch b?
-      if(d == b->left)//If d is on the left of b, then d's neighbor is on the right
-        {
-          *p_lk      = b->p_lk_rght;
-          *sum_scale = b->sum_scale_rght;
-#ifdef BEAGLE
-          *child_p_idx = b->rght->tax? b->p_lk_tip_idx: b->p_lk_rght_idx;
-#endif
-        }
-      else
-        {
-          *p_lk      = b->p_lk_left;
-          *sum_scale = b->sum_scale_left;
-#ifdef BEAGLE
-          *child_p_idx   = b->rght->tax? b->p_lk_tip_idx: b->p_lk_left_idx;
-#endif
-        }
+      PhyML_Printf("\n== The tree already has a root node");
+      Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
     }
   else
     {
-#ifdef BEAGLE
-      Warn_And_Exit(TODO_BEAGLE);
-#endif
-      *p_lk        = NULL;
-      *sum_scale   = NULL;
+      int i;
+      t_edge *best_edge;
+      phydbl best_lnL;
+
+      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]);
+      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)
+        {
+          PhyML_Printf("\n\u2022 Positionning root node on edge %4d",tree->a_edges[i]->num);
+          Add_Root(tree->a_edges[i],tree);
+          tree->ignore_root = NO;
+          Set_Both_Sides(YES,tree);
+          Lk(NULL,tree);
+
+          /* Optimize_Br_Len_Serie(tree); */
+
+          Update_Partial_Lk(tree,tree->n_root->b[1],tree->n_root);
+          Br_Len_Brent(tree->n_root->b[1],tree);
+          Update_Partial_Lk(tree,tree->n_root->b[2],tree->n_root);
+          Br_Len_Brent(tree->n_root->b[2],tree);
+
+          PhyML_Printf(" -- lnL: %20f",tree->c_lnL);
+          if(tree->c_lnL > best_lnL)
+            {
+              best_lnL  = tree->c_lnL;
+              best_edge = tree->a_edges[i];
+            }
+        }
+
+      Add_Root(best_edge,tree);
+      Set_Both_Sides(YES,tree);
+      Lk(NULL,tree);
+      Update_Partial_Lk(tree,tree->n_root->b[1],tree->n_root);
+      Br_Len_Brent(tree->n_root->b[1],tree);
+      Update_Partial_Lk(tree,tree->n_root->b[2],tree->n_root);
+      Br_Len_Brent(tree->n_root->b[2],tree);
+      tree->ignore_root = YES;
     }
 }
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
-/*     |
-       |
-       |b
-       |
-       |d
-      /  \
-     /    \
-    /      \
-   /        \
-  /v1        \v2
-
-  Set p_lk and sum_scale for subtrees with d, v1 and v2 as root,
-  Pij for edges b, and the two edges connecting d to v1 and d to
-  v2;
-  Account for rooted trees.
-*/
-
-void Set_All_P_Lk(t_node **n_v1, t_node **n_v2,
-                  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
-#ifdef BEAGLE
-                  , int *dest_p_idx, int *child1_p_idx, int* child2_p_idx, int* Pij1_idx, int* Pij2_idx
-#endif
-                  )
+void Set_Br_Len_Var(t_edge *b, t_tree *tree)
 {
-  int i;
-  
+  if(tree->is_mixt_tree)
+    {
+      MIXT_Set_Br_Len_Var(b,tree);
+      return;
+    }
 
-  if(!tree->n_root || tree->ignore_root == YES)
+  if(tree->rates == NO && tree->mod->gamma_mgf_bl == YES)
     {
-      if(tree->n_root && (b == tree->n_root->b[1] || b == tree->n_root->b[2])) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
 
-      /* Does d lie on the "left" or "right" of the branch? */
-      if(d == b->left)
+      phydbl len;
+      if(b == NULL)
         {
-          *p_lk      = b->p_lk_left;
-          *sum_scale = b->sum_scale_left;
-          *p_lk_loc  = b->p_lk_loc_left;
-#ifdef BEAGLE
-          *dest_p_idx = b->p_lk_left_idx;
-#endif
-        }
-      else
-        {
-          *p_lk      = b->p_lk_rght;
-          *sum_scale = b->sum_scale_rght;
-          *p_lk_loc  = b->p_lk_loc_rght;
-#ifdef BEAGLE
-          *dest_p_idx = b->p_lk_rght_idx;
-#endif
-        }
-
-      *n_v1 = *n_v2 = NULL;
-      For(i,3)//A node has 3 branches
-        {
-          if(d->b[i] != b)//Skip d's own branch(i.e. the branch coming from d's parent); because we only care about the branches of d's neighbors
-            {
-              if(!(*n_v1))//if we haven't found d's first neighbor
-                {
-                  *n_v1 = d->v[i];
-#ifdef BEAGLE
-                  Set_P_Lk_One_Side(Pij1,p_lk_v1,sum_scale_v1,d,d->b[i],tree,child1_p_idx,Pij1_idx);
-#else
-                  Set_P_Lk_One_Side(Pij1,p_lk_v1,sum_scale_v1,d,d->b[i],tree);
-#endif
-                }
-              else if(!(*n_v2))//we found his second neighbor
-                {
-                  *n_v2 = d->v[i];
-#ifdef BEAGLE
-                  Set_P_Lk_One_Side(Pij2,p_lk_v2,sum_scale_v2,d,d->b[i],tree,child2_p_idx,Pij2_idx);
-#else
-                  Set_P_Lk_One_Side(Pij2,p_lk_v2,sum_scale_v2,d,d->b[i],tree);
-#endif
-                }
-              else
-                {
-                  Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
-                }
-            }
-        }
-    }
-  else
-    {
-      if(b == tree->e_root)
-        {
-          if(d == tree->n_root->v[1])      b = tree->n_root->b[1];
-          else if(d == tree->n_root->v[2]) b = tree->n_root->b[2];
-          else
-            {
-              Generic_Exit(__FILE__,__LINE__,__FUNCTION__);            
-            }
-        }
-
-      if(d == tree->n_root)
-        {
-          if(b == tree->n_root->b[1])
-            {
-              *p_lk      = tree->n_root->b[1]->p_lk_left;
-              *sum_scale = tree->n_root->b[1]->sum_scale_left;
-              *p_lk_loc  = tree->n_root->b[1]->p_lk_loc_left;
-#ifdef BEAGLE
-              *dest_p_idx = tree->n_root->b[1]->p_lk_left_idx;
-#endif
-            }
-          else
-            {
-              *p_lk      = tree->n_root->b[2]->p_lk_left;
-              *sum_scale = tree->n_root->b[2]->sum_scale_left;
-              *p_lk_loc  = tree->n_root->b[2]->p_lk_loc_left;
-#ifdef BEAGLE
-              *dest_p_idx = tree->n_root->b[2]->p_lk_left_idx;
-#endif
-            }
-
-          *n_v1         = NULL;
-          *Pij1         = NULL;
-          *p_lk_v1      = NULL;
-          *sum_scale_v1 = NULL;
-
-          if(b == tree->n_root->b[1])
-            {
-              *n_v2         = tree->n_root->v[2];
-              *Pij2         = tree->n_root->b[2]->Pij_rr;
-              *p_lk_v2      = tree->n_root->b[2]->p_lk_rght;
-              *sum_scale_v2 = tree->n_root->b[2]->sum_scale_rght;
-#ifdef BEAGLE
-              *child2_p_idx = tree->n_root->b[2]->p_lk_rght_idx;
-              *Pij2_idx     = tree->n_root->b[2]->Pij_rr_idx;
-#endif
-            }
-          else if(b == tree->n_root->b[2])
-            {
-              *n_v2         = tree->n_root->v[1];
-              *Pij2         = tree->n_root->b[1]->Pij_rr;
-              *p_lk_v2      = tree->n_root->b[1]->p_lk_rght;
-              *sum_scale_v2 = tree->n_root->b[1]->sum_scale_rght;
-#ifdef BEAGLE
-              *child2_p_idx = tree->n_root->b[1]->p_lk_rght_idx;
-              *Pij2_idx     = tree->n_root->b[1]->Pij_rr_idx;
-#endif
-            }
-          else
-            {
-              Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
-            }
-        }
-      else if(d == tree->n_root->v[1] || d == tree->n_root->v[2])
-        {
-          if(b == tree->n_root->b[1] || b == tree->n_root->b[2])
-            {
-              if(b == tree->n_root->b[1])
-                {
-                  *p_lk      = tree->n_root->b[1]->p_lk_rght;
-                  *sum_scale = tree->n_root->b[1]->sum_scale_rght;
-                  *p_lk_loc  = tree->n_root->b[1]->p_lk_loc_left;
-#ifdef BEAGLE
-                  *dest_p_idx = tree->n_root->b[1]->p_lk_rght_idx;
-#endif
-                }
-              else
-                {
-                  *p_lk      = tree->n_root->b[2]->p_lk_rght;
-                  *sum_scale = tree->n_root->b[2]->sum_scale_rght;
-                  *p_lk_loc  = tree->n_root->b[2]->p_lk_loc_rght;
-#ifdef BEAGLE
-                  *dest_p_idx = tree->n_root->b[2]->p_lk_rght_idx;
-#endif
-                }
-
-
-              *n_v1 = *n_v2 = NULL;
-              For(i,3)
-                {
-                  if(d->b[i] != tree->e_root)
-                    {
-                      if(!(*n_v1))
-                        {
-                          *n_v1 = d->v[i];
-#ifdef BEAGLE
-                          Set_P_Lk_One_Side(Pij1,p_lk_v1,sum_scale_v1,d,d->b[i],tree,child1_p_idx,Pij1_idx);
-#else
-                          Set_P_Lk_One_Side(Pij1,p_lk_v1,sum_scale_v1,d,d->b[i],tree);
-#endif
-                        }
-                      else
-                        {
-                          *n_v2 = d->v[i];
-#ifdef BEAGLE
-                          Set_P_Lk_One_Side(Pij2,p_lk_v2,sum_scale_v2,d,d->b[i],tree,child2_p_idx,Pij2_idx);
-#else
-                          Set_P_Lk_One_Side(Pij2,p_lk_v2,sum_scale_v2,d,d->b[i],tree);
-#endif
-                        }
-                    }
-                }
-            }
-          else
+          int i;
+          
+          For(i,2*tree->n_otu-1)
             {
-              if(d == b->left)
-                {
-                  *p_lk      = b->p_lk_left;
-                  *sum_scale = b->sum_scale_left;
-                  *p_lk_loc  = b->p_lk_loc_left;
-#ifdef BEAGLE
-                  *dest_p_idx = b->p_lk_left_idx;
-#endif
-                }
-              else
-                {
-                  *p_lk      = b->p_lk_rght;
-                  *sum_scale = b->sum_scale_rght;
-                  *p_lk_loc  = b->p_lk_loc_rght;
-#ifdef BEAGLE
-                  *dest_p_idx = b->p_lk_rght_idx;
-#endif
-                }
-
-
-              *n_v1 = tree->n_root;
-#ifdef BEAGLE
-              Set_P_Lk_One_Side(Pij1,p_lk_v1,sum_scale_v1,d,
-                                (d == tree->n_root->v[1])?
-                                (tree->n_root->b[1]):
-                                (tree->n_root->b[2]),
-                                tree,child1_p_idx,Pij1_idx);
-#else
-              Set_P_Lk_One_Side(Pij1,p_lk_v1,sum_scale_v1,d,
-                                (d == tree->n_root->v[1])?
-                                (tree->n_root->b[1]):
-                                (tree->n_root->b[2]),
-                                tree);
-#endif
-              For(i,3)
-                {
-                  if(d->b[i] != tree->e_root && d->b[i] != b)
-                    {
-                      *n_v2 = d->v[i];
-#ifdef BEAGLE
-                      Set_P_Lk_One_Side(Pij2,p_lk_v2,sum_scale_v2,d,d->b[i],tree,child2_p_idx,Pij2_idx);
-#else
-                      Set_P_Lk_One_Side(Pij2,p_lk_v2,sum_scale_v2,d,d->b[i],tree);
-#endif
-                      break;
-                    }
-                }
-
+              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
         {
-          if(d == b->left)
-            {
-              *p_lk      = b->p_lk_left;
-              *sum_scale = b->sum_scale_left;
-              *p_lk_loc  = b->p_lk_loc_left;
-#ifdef BEAGLE
-              *dest_p_idx = b->p_lk_left_idx;
-#endif
-            }
-          else
-            {
-              *p_lk      = b->p_lk_rght;
-              *sum_scale = b->sum_scale_rght;
-              *p_lk_loc  = b->p_lk_loc_rght;
-#ifdef BEAGLE
-              *dest_p_idx = b->p_lk_rght_idx;
-#endif
-            }
-
-          *n_v1 = *n_v2 = NULL;
-          For(i,3)
-            {
-              if(d->b[i] != b)
-                {
-                  if(!(*n_v1))
-                    {
-                      *n_v1 = d->v[i];
-#ifdef BEAGLE
-                      Set_P_Lk_One_Side(Pij1,p_lk_v1,sum_scale_v1,d,d->b[i],tree,child1_p_idx,Pij1_idx);
-#else
-                      Set_P_Lk_One_Side(Pij1,p_lk_v1,sum_scale_v1,d,d->b[i],tree);
-#endif
-                    }
-                  else
-                    {
-                      *n_v2 = d->v[i];
-#ifdef BEAGLE
-                      Set_P_Lk_One_Side(Pij2,p_lk_v2,sum_scale_v2,d,d->b[i],tree,child2_p_idx,Pij2_idx);
-#else
-                      Set_P_Lk_One_Side(Pij2,p_lk_v2,sum_scale_v2,d,d->b[i],tree);
-#endif
-                    }
-                }
-            }
-        }
-    }
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-void Optimum_Root_Position_IL_Model(t_tree *tree)
-{
-
-  if(tree->n_root)
-    {
-      PhyML_Printf("\n== The tree already has a root node");
-      Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
-    }
-  else
-    {
-      int i;
-      t_edge *best_edge;
-      phydbl best_lnL;
-
-      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]);
-      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)
-        {
-          PhyML_Printf("\n. Positionning root node on edge %4d",tree->a_edges[i]->num);
-          Add_Root(tree->a_edges[i],tree);
-          tree->ignore_root = NO;
-          Set_Both_Sides(YES,tree);
-          Lk(NULL,tree);
-
-          /* Optimize_Br_Len_Serie(tree); */
-
-          Update_P_Lk(tree,tree->n_root->b[1],tree->n_root);
-          Br_Len_Brent(tree->mod->l_min,tree->mod->l_max,tree->n_root->b[1],tree);
-          Update_P_Lk(tree,tree->n_root->b[2],tree->n_root);
-          Br_Len_Brent(tree->mod->l_min,tree->mod->l_max,tree->n_root->b[2],tree);
-
-          PhyML_Printf(" -- lnL: %20f",tree->c_lnL);
-          if(tree->c_lnL > best_lnL)
-            {
-              best_lnL  = tree->c_lnL;
-              best_edge = tree->a_edges[i];
-            }
-        }
-
-      Add_Root(best_edge,tree);
-      Set_Both_Sides(YES,tree);
-      Lk(NULL,tree);
-      Update_P_Lk(tree,tree->n_root->b[1],tree->n_root);
-      Br_Len_Brent(tree->mod->l_min,tree->mod->l_max,tree->n_root->b[1],tree);
-      Update_P_Lk(tree,tree->n_root->b[2],tree->n_root);
-      Br_Len_Brent(tree->mod->l_min,tree->mod->l_max,tree->n_root->b[2],tree);
-      tree->ignore_root = YES;
-    }
-}
-
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-void Set_Br_Len_Var(t_tree *tree)
-{
-  if(tree->is_mixt_tree)
-    {
-      MIXT_Set_Br_Len_Var(tree);
-      return;
-    }
-
-  if(!tree->rates)
-    {
-      int i;
-      phydbl len;
-
-      For(i,2*tree->n_otu-1)
-        {
-          /* 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;
         }
     }
 }
@@ -10411,7 +10411,7 @@ void Build_Distrib_Number_Of_Diff_States_Under_Model(t_tree *tree)
     {
       if(tree->a_edges[i]->left->tax == NO && tree->a_edges[i]->rght->tax == NO)
         {
-          For(j,tree->mod->ns)
+          for(j=0;j<tree->mod->ns;j++)
             {
               PhyML_Printf("\n TRUE %3d 0 %3d %d",
                            i,
@@ -10443,13 +10443,13 @@ void Build_Distrib_Number_Of_Diff_States_Under_Model(t_tree *tree)
 
   do
     {
-      Evolve(tree->data,tree->mod,tree);
+      Evolve(tree->data,tree->mod,0,tree);
 
       Calculate_Number_Of_Diff_States(tree);
 
       For(i,2*tree->n_otu-3)
         {
-          For(j,tree->mod->ns)
+          for(j=0;j<tree->mod->ns;j++)
             {
               n_diff_states_all_l[j*(2*tree->n_otu-3)*(n_iter_tot) + i*(n_iter_tot) + iter] = tree->a_edges[i]->n_diff_states_l[j];
               n_diff_states_all_r[j*(2*tree->n_otu-3)*(n_iter_tot) + i*(n_iter_tot) + iter] = tree->a_edges[i]->n_diff_states_r[j];
@@ -10457,7 +10457,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);
       
@@ -10479,7 +10479,7 @@ void Build_Distrib_Number_Of_Diff_States_Under_Model(t_tree *tree)
     {
       if(tree->a_edges[i]->left->tax == NO && tree->a_edges[i]->rght->tax == NO)
         {
-          For(j,tree->mod->ns)
+          for(j=0;j<tree->mod->ns;j++)
             {              
               PhyML_Printf("\n SIM %3d 0 %3d %.0f %.0f",
                      i,
@@ -10523,7 +10523,7 @@ void Calculate_Number_Of_Diff_States(t_tree *tree)
   /* For(i,2*tree->n_otu-3) */
   /*   { */
   /*     if(tree->a_edges[i]->left->tax == NO && tree->a_edges[i]->rght->tax == NO) */
-        /* printf("\n. Edge %d left : %d %d %d %d right: %d %d %d %d", */
+        /* printf("\n\u2022 Edge %d left : %d %d %d %d right: %d %d %d %d", */
         /*        i, */
         /*        tree->a_edges[i]->n_diff_states_l[0], */
         /*        tree->a_edges[i]->n_diff_states_l[1], */
@@ -10546,7 +10546,7 @@ void Calculate_Number_Of_Diff_States_Post(t_node *a, t_node *d, t_edge *b, t_tre
     {
       int i;
 
-      For(i,3)
+      for(i=0;i<3;i++)
         if(d->v[i] != a)
           Calculate_Number_Of_Diff_States_Post(d,d->v[i],d->b[i],tree);
 
@@ -10565,7 +10565,7 @@ void Calculate_Number_Of_Diff_States_Pre(t_node *a, t_node *d, t_edge *b, t_tree
     {
       int i;
 
-      For(i,3)
+      for(i=0;i<3;i++)
         if(d->v[i] != a)
           {
             Calculate_Number_Of_Diff_States_Core(d->v[i],d,d->b[i],tree);
@@ -10579,7 +10579,7 @@ void Calculate_Number_Of_Diff_States_Pre(t_node *a, t_node *d, t_edge *b, t_tree
 
 void Calculate_Number_Of_Diff_States_Core(t_node *a, t_node *d, t_edge *b, t_tree *tree)
 {
-  unsigned int *ui, *ui_v1, *ui_v2;
+  int *ui, *ui_v1, *ui_v2;
   int sum,site,state;
   int *diff;
   t_node *v1, *v2;
@@ -10636,9 +10636,9 @@ void Calculate_Number_Of_Diff_States_Core(t_node *a, t_node *d, t_edge *b, t_tre
 
     }
 
-  For(state,tree->mod->ns) diff[state] = 0;
+  for(state=0;state<tree->mod->ns;state++) diff[state] = 0;
   
-  For(site,tree->n_pattern)
+  for(site=0;site<tree->n_pattern;site++)
     {
       if(v1->tax == YES)
         {
@@ -10696,7 +10696,7 @@ void Calculate_Number_Of_Diff_States_Core(t_node *a, t_node *d, t_edge *b, t_tre
       
       sum = Sum_Bits(ui[site],tree->mod->ns);
 
-      /* printf("\n. ui_v1: %d ui_v2: %d ui: %d sum: %d",ui_v1[site],ui_v2[site],ui[site],sum); fflush(NULL); */
+      /* printf("\n\u2022 ui_v1: %d ui_v2: %d ui: %d sum: %d",ui_v1[site],ui_v2[site],ui[site],sum); fflush(NULL); */
 
       if(sum-1 > tree->mod->ns-1) Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
 
@@ -10735,7 +10735,7 @@ void Number_Of_Diff_States_One_Site_Post(t_node *a, t_node *d, t_edge *b, int si
     {
       int i;
 
-      For(i,3)
+      for(i=0;i<3;i++)
         if(d->v[i] != a && d->b[i] != tree->e_root)
           Number_Of_Diff_States_One_Site_Post(d,d->v[i],d->b[i],site,tree);
 
@@ -10748,7 +10748,7 @@ void Number_Of_Diff_States_One_Site_Post(t_node *a, t_node *d, t_edge *b, int si
 
 int Number_Of_Diff_States_One_Site_Core(t_node *a, t_node *d, t_edge *b, int site, t_tree *tree)
 {
-  unsigned int *ui, *ui_v1, *ui_v2;
+  int *ui, *ui_v1, *ui_v2;
   int sum;
   t_node *v1, *v2;
   
@@ -10856,7 +10856,7 @@ int Number_Of_Diff_States_One_Site_Core(t_node *a, t_node *d, t_edge *b, int sit
       
   sum = Sum_Bits(ui[site],tree->mod->ns);
 
-  /* printf("\n. ui_v1: %d ui_v2: %d ui: %d sum: %d",ui_v1[site],ui_v2[site],ui[site],sum); fflush(NULL); */
+  /* printf("\n\u2022 ui_v1: %d ui_v2: %d ui: %d sum: %d",ui_v1[site],ui_v2[site],ui[site],sum); fflush(NULL); */
   
   if(sum-1 > tree->mod->ns-1)
     {
@@ -10884,6 +10884,36 @@ phydbl Get_Lk(t_tree *tree)
 /*////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////*/
 
+phydbl Get_dLk(t_tree *tree)
+{
+  t_tree *loc_tree;
+
+  loc_tree = tree;
+  /*! Rewind back to the first mixt_tree */
+  while(loc_tree->prev) loc_tree = loc_tree->prev;
+
+  return loc_tree->c_dlnL;
+
+}
+
+/*////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////*/
+
+phydbl Get_d2Lk(t_tree *tree)
+{
+  t_tree *loc_tree;
+
+  loc_tree = tree;
+  /*! Rewind back to the first mixt_tree */
+  while(loc_tree->prev) loc_tree = loc_tree->prev;
+
+  return loc_tree->c_d2lnL;
+
+}
+
+/*////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////*/
+
 align **Make_Empty_Alignment(option *io)
 {
   int i;
@@ -10893,7 +10923,7 @@ align **Make_Empty_Alignment(option *io)
   line   = (char *)mCalloc(T_MAX_LINE,sizeof(char));
   data   = (align **)mCalloc(io->n_otu,sizeof(align *));
   
-  For(i,io->n_otu)
+  for(i=0;i<io->n_otu;i++)
     {
       data[i]        = (align *)mCalloc(1,sizeof(align));
       data[i]->name  = (char *)mCalloc(T_MAX_NAME,sizeof(char));
@@ -10911,7 +10941,7 @@ align **Make_Empty_Alignment(option *io)
         }
     }
 
-  For(i,io->n_otu) data[i]->state[data[i]->len] = '\0';
+  for(i=0;i<io->n_otu;i++) data[i]->state[data[i]->len] = '\0';
 
   Free(line);
 
@@ -10929,7 +10959,7 @@ phydbl Mean_Identity(calign *data)
   n = data->n_otu;
   
   tot_idt = 0.0;
-  For(i,n-1)
+  for(i=0;i<n-1;i++)
     {
       for(j=i+1; j<n; j++)
         {
@@ -10950,7 +10980,7 @@ phydbl Pairwise_Identity(int i, int j, calign *data)
   phydbl div,p,d;
   
   div = 0.0;
-  For(k,data->crunch_len) if(data->c_seq[i]->state[k] == data->c_seq[j]->state[k]) div += (phydbl)data->wght[k];
+  for(k=0;k<data->crunch_len;k++) if(data->c_seq[i]->state[k] == data->c_seq[j]->state[k]) div += (phydbl)data->wght[k];
 
   /* observed proportion of identity */
   p = 1. - div / (phydbl)data->init_len;
@@ -10962,7 +10992,7 @@ phydbl Pairwise_Identity(int i, int j, calign *data)
       else
         {
           /* Jukes & Cantor distance */
-          d = -(3./4.)*LOG(1. - 4./3.*p);
+          d = -(3./4.)*log(1. - 4./3.*p);
         }
     }
   else if(data->io->datatype == AA)
@@ -10971,12 +11001,12 @@ phydbl Pairwise_Identity(int i, int j, calign *data)
       else
         {
           /* Jukes & Cantor distance */
-          d = -(19./20.)*LOG(1. - 20./19.*p);
+          d = -(19./20.)*log(1. - 20./19.*p);
         }
     }
   else Generic_Exit(__FILE__,__LINE__,__FUNCTION__);
 
-  return(EXP(-d));
+  return(exp(-d));
 }
 
 
@@ -10993,7 +11023,6 @@ phydbl Fst(int i, int j, calign *data)
   return((Fr-FA)/(1-FA));
 }
 
-
 /*////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////*/
 
@@ -11006,7 +11035,7 @@ phydbl Nucleotide_Diversity(calign *data)
   n = data->n_otu;
   
   pair_div = 0.0;
-  For(i,n-1)
+  for(i=0;i<n-1;i++)
     {
       for(j=i+1; j<n; j++)
         {
@@ -11016,3 +11045,531 @@ 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;
+  
+  if(ll == NULL) return NULL;
+  
+  loc = ll->head;
+  while(--pos >= 0) 
+    {
+      assert(loc);
+      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 == NULL) return 0;
+
+  loc = list->head;
+  len = 0;
+  do 
+    {
+      len++;
+      loc = loc->next;
+    }
+  while(loc != NULL);
+
+  return(len);
+
+}
+
+/*////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////*/
+
+void Push_Bottom_Linked_List(void *what, t_ll **list, bool remove_duplicates)
+{
+  t_ll *new,*ll;
+
+  /* { */
+  /*   if(*list) */
+  /*     { */
+  /*       t_node *n = what; */
+  /*       t_node *m = (*list)?(*list)->tail->v:NULL; */
+  /*       t_node *o = (*list)?(*list)->head->v:NULL; */
+  /*       printf("\n\u2022 before: push node %d bot %d head: %d --",n?n->num:-1,m?m->num:-1,o?o->num:-1); */
+  /*     } */
+  /*   else */
+  /*     { */
+  /*       printf("\n\u2022 "); */
+  /*     } */
+  /* } */
+
+  /* if(*list == NULL) printf("\n"); */
+  
+  new = (t_ll *)mCalloc(1,sizeof(t_ll));  
+  new->v = (void *)what;
+  
+  /* t_node *n = what; */
+  /* printf("\n push node %p list: %p %p",new,*list,(*list)?(*list)->head:NULL); */
+
+
+  // First elem of list
+  if(*list == NULL) 
+    {
+      *list     = new;
+      new->tail = new;
+      new->head = new;
+      new->next = NULL;
+      new->prev = NULL;
+    }
+  else
+    {
+      ll = (*list)->head;
+
+      if(remove_duplicates == YES)
+        {
+          do
+            {
+              if(ll->v == what)
+                {
+                  Free(new);
+                  return; // 'what' already in list 
+                }
+              ll = ll->next;
+            }
+          while(ll);
+        }
+
+      new->prev = (*list)->tail;
+      (*list)->tail->next = new;
+      new->next = NULL;
+      new->head = (*list)->head;      
+
+      ll = (*list)->head;
+      do
+        {
+          ll->tail = new;
+          ll = ll->next;
+        }
+      while(ll);
+    }
+}
+
+/*////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////*/
+
+void Remove_From_Linked_List(t_ll *elem, void *val, t_ll **list)
+{
+  t_ll *ll;
+  
+  if(*list == NULL) return;
+  
+  ll = (*list)->head;
+
+  /* t_node *n = elem ? elem->v : val; */
+
+  do
+    {
+      if((elem && ll == elem) || (val && ll->v == val))
+        {
+          if(ll == (*list)->head && ll != (*list)->tail)
+            {
+              // Re-initialise head of list
+              t_ll *mm,*newhead;
+              mm = (*list);
+              newhead = (*list)->head->next;
+              do { mm->head = newhead; mm = mm->next; } while(mm);              
+              (*list) = (*list)->head;
+              (*list)->head->prev = NULL;
+            }
+          else if(ll != (*list)->head && ll == (*list)->tail) 
+            {
+              // Re-initialise tail of list
+              t_ll *mm,*newtail;
+              mm = (*list);
+              newtail = (*list)->tail->prev;
+              do { mm->tail = newtail; mm = mm->next; } while(mm);              
+              (*list)->tail->next = NULL;
+            }
+          else if(ll == (*list)->head && ll == (*list)->tail) 
+            {
+              (*list)->tail = NULL;
+              (*list)->head = NULL;
+              (*list)->next = NULL;
+              (*list)->prev = NULL;
+              (*list) = NULL;
+              /* printf("\n\u2022 free %p",ll); */
+              Free(ll);
+              return;
+            }
+          else
+            {
+              ll->prev->next = ll->next;
+              ll->next->prev = ll->prev;
+            }
+
+          ll->next = NULL;
+          ll->prev = NULL;
+          ll->head = NULL;
+          ll->tail = NULL;
+          /* printf("\n\u2022 free %p",ll); */
+          Free(ll);
+          return;
+        }
+      ll = ll->next;
+    }
+  while(ll != NULL);
+}
+
+/*////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////*/
+
+t_ll *Get_List_Of_Reachable_Tips(t_node *a, t_node *d, t_tree *tree)
+{
+  t_ll *list;
+  Get_List_Of_Reachable_Tips_Post(a,d,&list,tree);
+  return list;
+}
+
+/*////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////*/
+
+void Get_List_Of_Reachable_Tips_Post(t_node *a, t_node *d, t_ll **list, t_tree *tree)
+{
+  if(d->tax)
+    {
+      /* printf("\n\u2022 push %d list: %p",d->num,list->head); */
+      Push_Bottom_Linked_List(d,list,YES);
+      return;
+    }
+  else
+    {
+      int i;
+      for(i=0;i<3;i++)
+        {
+          if(d->v[i] != a && d->b[i] != tree->e_root)
+            Get_List_Of_Reachable_Tips_Post(d,d->v[i],list,tree);
+        }
+    }  
+}
+
+/*////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////*/
+// tips0: first list of tips. tips1: second list of tips
+phydbl Length_Of_Path_Between_List_Of_Tips(t_ll *tips0, t_ll *tips1, matrix *mat)
+{
+  phydbl d,n;
+  t_ll *x, *y;
+  t_node *nx, *ny;
+
+  d = 0.0;
+  n = 0;
+
+  /* Print_Mat(mat); */
+
+  // Add all distances between tips in distinct lists
+  x = tips0->head;
+  do
+    {
+      y = tips1->head;
+      do
+        {
+          nx = (t_node *)x->v;
+          ny = (t_node *)y->v;
+
+          d += mat->dist[nx->c_seq->num][ny->c_seq->num];
+
+          /* printf("\n\u2022 nx: %d ny: %d [%p %p] d: %G", */
+          /*        nx->c_seq->num, */
+          /*        ny->c_seq->num, */
+          /*        x->head, */
+          /*        y->head, */
+          /*        mat->dist[nx->c_seq->num][ny->c_seq->num]); fflush(NULL); */
+
+          n++; //  number of pairs of tips, each tip in different lists
+          y = y->next;
+        }
+      while(y);
+      x = x->next;
+    }
+  while(x);
+  
+  // Remove distances between tips in tips0
+  x = tips0->head;
+  do
+    {
+      y = tips0->head;
+      do
+        {
+          nx = (t_node *)x->v;
+          ny = (t_node *)y->v;
+          d -= mat->dist[nx->c_seq->num][ny->c_seq->num];
+          y = y->next;
+        }
+      while(y);
+      x = x->next;
+    }
+  while(x);
+
+
+  // Remove distances between tips in tips1
+  x = tips1->head;
+  do
+    {
+      y = tips1->head;
+      do
+        {
+          nx = (t_node *)x->v;
+          ny = (t_node *)y->v;
+          d -= mat->dist[nx->c_seq->num][ny->c_seq->num];
+          y = y->next;
+        }
+      while(y);
+      x = x->next;
+    }
+  while(x);
+
+  return d/(phydbl)n;
+}
+
+/*////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////*/
+
+void Random_Walk_Along_Tree_On_Radius(t_node *a, t_node *d, t_edge *b, phydbl *radius, t_edge **target_edge, t_node **target_nd, phydbl *target_time, t_tree *tree)
+{
+  assert(tree->rates);
+  
+  phydbl delta,ta,td,u;
+
+  /* if(tree->rates->nd_t[a->num] < tree->rates->nd_t[d->num]) */
+  /*   { */
+  /*     printf("\n\u2022 a: %d d: %d radius: %f l: %f [%f] -- %f | %f [%d]", */
+  /*            a->num, */
+  /*            d->num, */
+  /*            *radius, */
+  /*            b->l->v, */
+  /*            FABS(tree->rates->nd_t[a->num] - tree->rates->nd_t[d->num]) * tree->rates->clock_r * tree->rates->br_r[d->num], */
+  /*            tree->rates->cur_l[d->num], */
+  /*            tree->rates->cur_l[a->num], */
+  /*            b == tree->e_root); fflush(NULL); */
+  /*   } */
+  /* else */
+  /*   { */
+  /*     printf("\n\u2022 a: %d d: %d radius: %f l: %f [%f] -- %f | %f [%d]", */
+  /*            a->num, */
+  /*            d->num, */
+  /*            *radius, */
+  /*            b->l->v, */
+  /*            FABS(tree->rates->nd_t[a->num] - tree->rates->nd_t[d->num]) * tree->rates->clock_r * tree->rates->br_r[a->num], */
+  /*            tree->rates->cur_l[d->num], */
+  /*            tree->rates->cur_l[a->num], */
+  /*            b == tree->e_root); fflush(NULL); */
+  /*   } */
+  
+  delta = *radius;
+
+  assert(delta > 0.0);
+  
+  (*radius) -= b->l->v;
+  if(*radius < 0.0)
+    {
+      *target_edge = b;
+      ta = tree->rates->nd_t[a->num];
+      td = tree->rates->nd_t[d->num];
+
+      if(b != tree->e_root)
+        {
+          if(ta < td)
+            {
+              *target_time = ta + delta / (tree->rates->clock_r * tree->rates->br_r[d->num]);
+              *target_nd = d;
+              /* printf("\n< ta: %f td: %f new_time: %f delta: %f c: %f r: %f",ta,td,*target_time,delta,tree->rates->clock_r,tree->rates->br_r[d->num]); */
+            }
+          else
+            {
+              *target_time = ta - delta / (tree->rates->clock_r * tree->rates->br_r[a->num]);
+              *target_nd = a;
+              /* printf("\n> ta: %f td: %f new_time: %f delta: %f c: %f r: %f",ta,td,*target_time,delta,tree->rates->clock_r,tree->rates->br_r[a->num]); */
+            }
+        }
+      else
+        {
+          // target falls on edge below root leading to node a
+          if(delta < tree->rates->cur_l[a->num])
+            {
+              *target_time = ta - delta / (tree->rates->clock_r * tree->rates->br_r[a->num]);
+              *target_nd = a;
+              /* printf("\n\u2022. delta: %f l(a): %f time: %f ta: %f",delta,tree->rates->cur_l[a->num],*target_time,ta); */
+            }
+          else
+            {
+              u = Uni();
+              if(u < .5)
+                {
+                  // target falls on edge below root leading to node d
+                  *target_time = tree->rates->nd_t[tree->n_root->num] + (delta - tree->rates->cur_l[a->num])/(tree->rates->clock_r * tree->rates->br_r[d->num]);
+                  *target_nd = d;
+                  /* printf("\n<< ta: %f td: %f new_time: %f delta: %f c: %f",ta,td,*target_time,delta,tree->rates->clock_r); */
+                }
+              else
+                {
+                  // target falls above root
+                  *target_time = tree->rates->nd_t[tree->n_root->num] - (delta - tree->rates->cur_l[a->num])/tree->rates->clock_r;
+                  *target_nd = tree->n_root;                  
+                  /* printf("\n>> ta: %f td: %f new_time: %f delta: %f c: %f",ta,td,*target_time,delta,tree->rates->clock_r); */
+                }
+            }
+        }
+      
+      return;
+    }
+  
+  if(d->tax == YES) return;
+  else
+    {      
+      int i,dir1,dir2;
+      
+      dir1 = dir2 = -1;
+      for(i=0;i<3;i++)
+        if(d->v[i] != a)
+          {
+            if(dir1 < 0) dir1 = i;
+            else         dir2 = i;
+          }
+             
+      u = Uni();
+      if(u < .5)
+        Random_Walk_Along_Tree_On_Radius(d,d->v[dir1],d->b[dir1],radius,target_edge,target_nd,target_time,tree);
+      else
+        Random_Walk_Along_Tree_On_Radius(d,d->v[dir2],d->b[dir2],radius,target_edge,target_nd,target_time,tree);
+    }
+}
+
+/*////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////*/
+
+void Table_Top(unsigned int width)
+{
+  unsigned int i;
+  PhyML_Printf("\n\t \u256D");
+  for(i=0;i<width;++i) PhyML_Printf("\u2500");
+  PhyML_Printf("\u256E ");
+}
+
+/*////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////*/
+
+void Table_Row(unsigned int width)
+{
+  unsigned int i;
+  /* PhyML_Printf("\n\t \u2502"); */
+  PhyML_Printf("\n\t \u251C");
+  for(i=0;i<width;++i) PhyML_Printf("\u2500");
+  /* PhyML_Printf("\u2502"); */
+  PhyML_Printf("\u2524");
+}
+
+/*////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////*/
+
+void Table_Bottom(unsigned int width)
+{
+  unsigned int i;
+  PhyML_Printf("\n\t \u2570");
+  for(i=0;i<width;++i) PhyML_Printf("\u2500");
+  PhyML_Printf("\u256F ");
+}
+
+/*////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////*/
+/*////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////*/
+/*////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////*/
+/*////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////*/
+/*////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////*/
diff --git a/src/utilities.h b/src/utilities.h
index 7f7cd5f..0022451 100644
--- a/src/utilities.h
+++ b/src/utilities.h
@@ -28,10 +28,24 @@ the GNU public licence. See http://www.opensource.org for details.
 #include <float.h>
 #include <assert.h>
 #include <stdbool.h>
+/* #include <malloc/malloc.h> */
+#include <malloc.h>
+
+#if (defined(__AVX__))
+#include <xmmintrin.h>
+#include <pmmintrin.h>
+#include <immintrin.h>
+#elif (defined(__SSE3__))
+#include <emmintrin.h>
+#include <pmmintrin.h>
+#endif
+
 
 extern int n_sec1;
 extern int n_sec2;
 
+#define __FUNCTION__ NULL
+
 #define For(i,n)                     for(i=0; i<n; i++)
 #define Fors(i,n,s)                  for(i=0; i<n; i+=s)
 #define PointGamma(prob,alpha,beta)  PointChi2(prob,2.0*(alpha))/(2.0*(beta))
@@ -48,8 +62,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)						 \
@@ -71,6 +87,10 @@ static inline int isinf_d  (double      x) { return isnan (x - x); }
 static inline int isinf_ld (long double x) { return isnan (x - x); }
 #endif
 
+
+extern int CALL;
+extern int TIME;
+
 #define AC 0
 #define AG 1
 #define AT 2
@@ -78,19 +98,59 @@ static inline int isinf_ld (long double x) { return isnan (x - x); }
 #define CT 4
 #define GT 5
 
+#if (defined __AVX__)
+#define BYTE_ALIGN 32
+#elif (defined __SSE3__)
+#define BYTE_ALIGN 16
+#else
+#define BYTE_ALIGN 1
+#endif
+
 #ifndef M_1_SQRT_2PI
 #define M_1_SQRT_2PI	0.398942280401432677939946059934	/* 1/sqrt(2pi) */
 #endif
 
-
+// verbose levels
+#define VL0 0
+#define VL1 1
+#define VL2 2
+#define VL3 3
+#define VL4 4
 
 #define T_MAX_MCMC_MOVE_NAME 500
 
 #define WINDOW_WIDTH  800
 #define WINDOW_HEIGHT 800
 
+#define  ALPHA_MIN 0.01
+#define  ALPHA_MAX 1000.
+
+#define  E_FRQ_WEIGHT_MIN 0.01
+#define  E_FRQ_WEIGHT_MAX 100.
+
+#define  R_MAT_WEIGHT_MIN 0.01
+#define  R_MAT_WEIGHT_MAX 100.
+
+#define  E_FRQ_MIN 0.01
+#define  E_FRQ_MAX 1.00
+
+#define  UNSCALED_E_FRQ_MIN 0.01
+#define  UNSCALED_E_FRQ_MAX 100.
+
+#define  TSTV_MIN 0.05
+#define  TSTV_MAX 20.0
+
+#define  PINV_MIN 0.00001
+#define  PINV_MAX 0.99999
+
 #define RR_MIN 0.01
-#define RR_MAX 200.0
+#define RR_MAX 100.0
+
+#define GAMMA_RR_UNSCALED_MIN 0.01
+#define GAMMA_RR_UNSCALED_MAX 200.
+
+#define GAMMA_R_PROBA_UNSCALED_MIN 0.01
+#define GAMMA_R_PROBA_UNSCALED_MAX 200.
 
 #define PHYREX_UNIFORM 0
 #define PHYREX_NORMAL  1
@@ -108,8 +168,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
 
@@ -136,6 +196,7 @@ static inline int isinf_ld (long double x) { return isnan (x - x); }
 
 #define  PHYLIP 0
 #define  NEXUS  1
+#define  IBDSIM 2
 
 #ifndef YES
 #define  YES 1
@@ -180,7 +241,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             100
+#define N_MAX_OPTIONS         100
 
 #define NEXT_BLOCK_SIZE        50
 
@@ -195,15 +257,13 @@ static inline int isinf_ld (long double x) { return isnan (x - x); }
 #define  N_MAX_LABEL           10
 #define  BLOCK_LABELS         100
 
-#define  NODE_DEG_MAX         500
-#define  BRENT_IT_MAX         500
+#define  NODE_DEG_MAX        2000
+#define  BRENT_IT_MAX         100
 #define  BRENT_CGOLD    0.3819660
 #define  BRENT_ZEPS        1.e-10
 #define  MNBRAK_GOLD     1.618034
 #define  MNBRAK_GLIMIT      100.0
 #define  MNBRAK_TINY       1.e-20
-#define  ALPHA_MIN           0.04
-#define  ALPHA_MAX            100
 #define  BL_START          1.e-04
 #define  GOLDEN_R      0.61803399
 #define  GOLDEN_C  (1.0-GOLDEN_R)
@@ -270,6 +330,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
@@ -318,7 +379,7 @@ typedef	double phydbl;
 #define TAN tan
 #define SMALL DBL_MIN
 #define BIG  DBL_MAX
-#define SMALL_PIJ 1.E-20
+#define SMALL_PIJ 1.E-100
 #define LOGBIG 690.
 #define LOGSMALL -690.
 
@@ -331,13 +392,30 @@ typedef	double phydbl;
 #define BL_MAX 1.
 #endif
 
-/* #define P_LK_LIM_INF 7.888609052e-31 */
-/* #define P_LK_LIM_MAX 1.267650600e+30 */
-/* #define P_LK_LIM_INF 4.909093465e-91 /\* R: format(2^(-300),digits=10) *\/ */
-/* #define P_LK_LIM_SUP 2.037035976e+90 /\* R: format(2^(+300),digits=10) *\/ */
+// Do *not* change the values below and leave the lines with
+// curr_scaler_pow = (int)(-XXX.-LOG(smallest_p_lk))/LOG2;
+// as XXX depends on what the value of P_LK_LIM_INF is 
 #define  P_LK_LIM_INF   3.054936e-151 /* 2^-500 */
 #define  P_LK_LIM_SUP   3.273391e+150 /* 2^500 */
-//#define  P_LK_LIM_INF   4.656612873e-10 /*2^-31 */
+/* #define  P_LK_LIM_INF   1.499697e-241 /\* 2^-800 *\/ */
+/* #define  P_LK_LIM_SUP   6.668014e+240 /\* 2^800 *\/ */
+
+/* #define LARGE 100 */
+/* #define TWO_TO_THE_LARGE 1267650600228229401496703205376.0 /\* 2^100 In R : sprintf("%.100f", 2^100)*\/ */
+
+/* #define LARGE 200 */
+/* #define TWO_TO_THE_LARGE 1606938044258990275541962092341162602522202993782792835301376.0 /\* 2^200 In R : sprintf("%.100f", 2^256)*\/ */
+
+#define LARGE 256
+#define TWO_TO_THE_LARGE 115792089237316195423570985008687907853269984665640564039457584007913129639936.0 /* 2^256 In R : sprintf("%.100f", 2^256)*/
+
+#define INV_TWO_TO_THE_LARGE (1./TWO_TO_THE_LARGE)
+
+#define SCALE_RATE_SPECIFIC 1
+#define SCALE_FAST 2
+
+#define SCALENO 0
+#define SCALEYES 1
 
 #define T_MAX_XML_TAG 64
 
@@ -364,6 +442,16 @@ 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  *prev;
+  struct __Generic_LL  *tail;
+  struct __Generic_LL  *head;
+}t_ll;
+
+/*!********************************************************/
 
 typedef struct __Scalar_Int {
   int                      v;
@@ -426,10 +514,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 +522,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 +588,13 @@ 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) */
+  phydbl                          *tPij_rr; /*! transpose 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,42 +602,44 @@ typedef struct __Edge {
   short int                    does_exist;
 
 
-  int                       *patt_id_left;
-  int                       *patt_id_rght;
-  int                      *p_lk_loc_left;
-  int                      *p_lk_loc_rght;
+
+  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) */
+  phydbl         *p_lk_tip_r, *p_lk_tip_l;
 
 
-  phydbl                          *Pij_rr; /*! matrix of change probabilities and its first and secnd derivates (rate*state*state) */
 #ifdef BEAGLE
-  int                          Pij_rr_idx;
+  int        p_lk_left_idx, p_lk_rght_idx;
+  int                        p_lk_tip_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 */
+  int                       *patt_id_left;
+  int                       *patt_id_rght;
+  int                      *p_lk_loc_left;
+  int                      *p_lk_loc_rght;
 
+  int            *pars_l,*pars_r; /*! parsimony of the subtree on the left and right sides (for each site) */
+  int               *ui_l, *ui_r; /*! union - intersection vectors used in Fitch's parsimony algorithm */
+  int       *p_pars_l, *p_pars_r; /*! conditional parsimony vectors */
 
   /*! Below are the likelihood scaling factors (used in functions
-     `Get_All_Partial_Lk_Scale' in lk.c. */
+    `Get_All_Partial_Lk_Scale' in lk.c. */
   /*
-For every site, every subtree and every rate class, PhyML maintains a`sum_scale_pow' value
-where sum_scale_pow = sum_scale_pow_v1 + sum_scale_pow_v2 + curr_scale_pow'
-sum_scale_pow_v1 and sum_scale_pow_v2 are sum_scale_pow of the left and
-right subtrees. curr_scale_pow is an integer greater than one.
-The smaller the partials, the larger curr_scale_pow.
-
-Now the partials for this subtree are scaled by *multiplying* each of
-them by 2^curr_scale_pow. The reason for doing the scaling this way is
-that multiplications by 2^x (x an integer) can be done in an 'exact'
-manner (i.e., there is no loss of numerical precision)
-
-At the root edge, the log-likelihood is then
+    For every site, every subtree and every rate class, PhyML maintains a`sum_scale_pow' value
+    where sum_scale_pow = sum_scale_pow_v1 + sum_scale_pow_v2 + curr_scale_pow'
+    sum_scale_pow_v1 and sum_scale_pow_v2 are sum_scale_pow of the left and
+    right subtrees. curr_scale_pow is an integer greater than one.
+    The smaller the partials, the larger curr_scale_pow.
+    
+    Now the partials for this subtree are scaled by *multiplying* each of
+    them by 2^curr_scale_pow. The reason for doing the scaling this way is
+    that multiplications by 2^x (x an integer) can be done in an 'exact'
+    manner (i.e., there is no loss of numerical precision)
+    
+    At the root edge, the log-likelihood is then
     logL = logL' - (sum_scale_pow_left + sum_scale_pow_right)log(2),
-where L' is the scaled likelihood.
-*/
+    where L' is the scaled likelihood.
+  */
+  
   int                 *sum_scale_left_cat;
   int                 *sum_scale_rght_cat;
   int                     *sum_scale_left;
@@ -592,6 +682,7 @@ typedef struct __Tree{
   struct __Tree                    *next_mixt; /*! set to NULL by default. Used for mixture models */
   struct __Tree                    *prev_mixt; /*! set to NULL by default. Used for mixture models */
   struct __Tree                    *mixt_tree; /*! set to NULL by default. Used for mixture models */
+  struct __Tree                   *extra_tree; /*! set to NULL by default. Used a latent variable in molecular dating */
   struct __Option                         *io; /*! input/output */
   struct __Matrix                        *mat; /*! pairwise distance matrix */
   struct __Node                   **curr_path; /*! list of nodes that form a path in the tree */
@@ -604,7 +695,17 @@ typedef struct __Tree{
   struct __Phylogeo                      *geo;
   struct __Migrep_Model                 *mmod;
   struct __Disk_Event                   *disk;
+  struct __XML_node                 *xml_root;
+  struct __Generic_LL              *edge_list;
+  struct __Generic_LL              *node_list;
 
+
+  short int                         eval_alnL; /*! Evaluate likelihood for genetic data */
+  short int                         eval_rlnL; /*! Evaluate likelihood for rates along the tree */
+  short int                         eval_glnL; /*! Evaluate tree likelihood */
+  short int                    scaling_method;
+
+  short int                      use_eigen_lr;
   int                            is_mixt_tree;
   int                                tree_num; /*! tree number. Used for mixture models */
   int                          ps_page_number; /*! when multiple trees are printed, this variable give the current page number */
@@ -626,6 +727,7 @@ typedef struct __Tree{
   short int                            *t_dir;
   int                          n_improvements;
   int                                 n_moves;
+  int                                 verbose;
 
   int                                      dp; /*! Data partition */
   int                               s_mod_num; /*! Substitution model number */
@@ -633,6 +735,14 @@ typedef struct __Tree{
   int                            write_labels;
   int                           write_br_lens;
   int                                 *mutmap; /*! Mutational map */
+  int                                json_num;
+  short int                   update_eigen_lr;
+  
+  phydbl                       *eigen_lr_left;
+  phydbl                       *eigen_lr_rght;
+  phydbl                            *dot_prod;
+
+  phydbl                                *expl;
 
   phydbl                             init_lnL;
   phydbl                             best_lnL; /*! highest value of the loglikelihood found so far */
@@ -644,6 +754,9 @@ typedef struct __Tree{
   phydbl                         *cur_site_lk; /*! vector of loglikelihoods at individual sites */
   phydbl                         *old_site_lk; /*! vector of likelihoods at individual sites */
   phydbl                       annealing_temp; /*! annealing temperature in simulated annealing optimization algo */
+  phydbl                               c_dlnL; /*! First derivative of the log-likelihood with respect to the length of a branch */
+  phydbl                              c_d2lnL; /*! Second derivative of the log-likelihood with respect to the length of a branch */
+
 
   phydbl                *unscaled_site_lk_cat; /*! partially scaled site likelihood at individual sites */
 
@@ -656,6 +769,7 @@ typedef struct __Tree{
   int                              *site_pars;
   int                                  c_pars;
   int                               *step_mat;
+  
 
   int                           size_spr_list;
   int                  perform_spr_right_away;
@@ -805,17 +919,17 @@ typedef struct __Align {
   char          *state; /*! sequence itself */
   int         *d_state; /*! sequence itself (digits) */
   short int *is_ambigu; /*! is_ambigu[site] = 1 if state[site] is an ambiguous character. 0 otherwise */
+  int              num;
 }align;
 
 /*!********************************************************/
 
-
 typedef struct __Calign {
   struct __Align **c_seq;             /*! compressed sequences      */
   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 +941,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 +1018,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) */
+
+  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;
+  struct __EquFreq         *next;
+  struct __EquFreq         *prev;
 
 }t_efrq;
 
@@ -929,7 +1050,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 +1100,6 @@ typedef struct __Model {
 
 }t_mod;
 
-
-
 /*!********************************************************/
 
 typedef struct __Eigen{
@@ -1028,6 +1146,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 +1161,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 +1211,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,13 +1245,12 @@ typedef struct __Option { /*! mostly used in 'help.c' */
 #endif
 
   int                       ancestral;
+  int                  has_io_weights;
 }option;
 
 /*!********************************************************/
 
 typedef struct __Optimiz { /*! parameters to be optimised (mostly used in 'optimiz.c') */
-  int                    print; /*! =1 -> verbose mode  */
-
   int                opt_alpha; /*! =1 -> the gamma shape parameter is optimised */
   int                opt_kappa; /*! =1 -> the ts/tv ratio parameter is optimised */
   int               opt_lambda; /*! =1 -> the F84|TN93 model specific parameter is optimised */
@@ -1152,7 +1276,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;
@@ -1172,7 +1295,10 @@ typedef struct __Optimiz { /*! parameters to be optimised (mostly used in 'optim
   int           max_depth_path;
   int           min_depth_path;
   int             deepest_path;
+  int        eval_list_regraft;
   phydbl     max_delta_lnL_spr;
+  phydbl     max_delta_lnL_spr_current;
+  phydbl         worst_lnL_spr;
   int            br_len_in_spr;
   int      opt_free_mixt_rates;
   int       constrained_br_len;
@@ -1192,6 +1318,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 +1331,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 +1349,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 +1360,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;
@@ -1242,6 +1376,8 @@ typedef struct __SPR{
   struct __SPR            *prev;
   struct __SPR       *next_mixt;
   struct __SPR       *prev_mixt;
+  struct __SPR       *path_prev;
+  struct __SPR       *path_next;
 
 }t_spr;
 
@@ -1323,6 +1459,11 @@ typedef struct __T_Rate {
   phydbl birth_rate;
   phydbl birth_rate_min;
   phydbl birth_rate_max;
+  phydbl birth_rate_pivot;
+  phydbl death_rate;
+  phydbl death_rate_min;
+  phydbl death_rate_max;
+  phydbl death_rate_pivot;
   phydbl min_rate;
   phydbl max_rate;
   phydbl c_lnL1;
@@ -1409,7 +1550,7 @@ typedef struct __T_Rate {
   int *n_tips_below;
 
   short int *t_has_prior;
-  struct __Node **lca; /*! 2-way table of common ancestral nodes for each pari of nodes */
+  struct __Node **lca; /*! 2-way table of common ancestral nodes for each pair of nodes */
 
   short int *br_do_updt;
   phydbl *cur_gamma_prior_mean;
@@ -1422,10 +1563,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;
@@ -1434,9 +1573,11 @@ typedef struct __T_Rate {
   phydbl log_K_cur;
   int cur_comb_numb;
   int *numb_calib_chosen;
-  phydbl *node_height_dens_log_norm_const_update;
   int update_time_norm_const;
 
+  struct __T_Rate *next;
+  struct __T_Rate *prev;
+
 }t_rate;
 
 /*!********************************************************/
@@ -1458,12 +1599,20 @@ typedef struct __Tmcmc {
 
   int num_move_nd_r;
   int num_move_br_r;
-  int num_move_nd_t;
+  int num_move_times;
+  int num_move_times_and_rates;
+  int num_move_times_and_rates_root;
+  int num_move_root_time;
   int num_move_nu;
   int num_move_clock_r;
   int num_move_tree_height;
+  int num_move_time_slice;
   int num_move_subtree_height;
   int num_move_kappa;
+  int num_move_spr;
+  int num_move_spr_weighted;
+  int num_move_spr_local;
+  int num_move_spr_root;
   int num_move_tree_rates;
   int num_move_subtree_rates;
   int num_move_updown_nu_cr;
@@ -1473,6 +1622,8 @@ 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_birth_death_updown;
   int num_move_jump_calibration;
   int num_move_geo_lambda;
   int num_move_geo_sigma;
@@ -1522,7 +1673,6 @@ typedef struct __Tmcmc {
 
   int *adjust_tuning;
   int n_moves;
-  int use_data;
   int randomize;
   int norm_freq;
   int run;
@@ -1627,15 +1777,19 @@ 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?
+  
+  struct __Node **target_tip; // Array of targeted tips
+  char **target_tax;
+  int  n_target_tax;
+  char *clade_id;
 }t_cal;
 
 /*!********************************************************/
@@ -1704,7 +1858,9 @@ typedef struct __Migrep_Model{
   phydbl           prior_param_sigsq; // parameter of the parameter for the prior 
 
   phydbl                         rho; // intensity parameter of the Poisson point processs
+  phydbl                gen_cal_time; // duration of one generation in calendar time unit
 
+  
   phydbl                       c_lnL; // current value of log-likelihood 
   phydbl              c_ln_prior_rad; // current value of log prior for the prior on radius
   phydbl             c_ln_prior_lbda; // current value of log prior for the prior on lbda
@@ -1716,7 +1872,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 +1921,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);
@@ -1816,7 +1996,6 @@ int Sort_Edges_Depth(t_tree *tree,t_edge **sorted_edges,int n_elem);
 void NNI(t_tree *tree,t_edge *b_fcus,int do_swap);
 void NNI_Pars(t_tree *tree,t_edge *b_fcus,int do_swap);
 void Swap(t_node *a,t_node *b,t_node *c,t_node *d,t_tree *tree);
-void Update_All_Partial_Lk(t_edge *b_fcus,t_tree *tree);
 void Update_SubTree_Partial_Lk(t_edge *b_fcus,t_node *a,t_node *d,t_tree *tree);
 void Copy_Seq_Names_To_Tip_Labels(t_tree *tree,calign *data);
 calign *Copy_Cseq(calign *ori,option *io);
@@ -1863,18 +2042,19 @@ void Match_Tip_Numbers(t_tree *tree1,t_tree *tree2);
 void Test_Multiple_Data_Set_Format(option *io);
 int Are_Compatible(char *statea,char *stateb,int stepsize,int datatype);
 void Hide_Ambiguities(calign *data);
-void Copy_Tree(t_tree *ori,t_tree *cpy);
+void Copy_Tree(t_tree *ori, t_tree *cpy);
 void Prune_Subtree(t_node *a,t_node *d,t_edge **target,t_edge **residual,t_tree *tree);
-void Graft_Subtree(t_edge *target,t_node *link,t_edge *residual,t_tree *tree);
+void Graft_Subtree(t_edge *target, t_node *link, t_node *link_daughter, t_edge *residual, t_node *target_nd, t_tree *tree);
 void Reassign_Node_Nums(t_node *a,t_node *d,int *curr_ext_node,int *curr_int_node,t_tree *tree);
 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);
 void Update_Dir_To_Tips(t_node *a,t_node *d,t_tree *tree);
 void Fill_Dir_Table(t_tree *tree);
 int Get_Subtree_Size(t_node *a,t_node *d);
-void Fast_Br_Len(t_edge *b,t_tree *tree,int approx);
+phydbl Fast_Br_Len(t_edge *b, t_tree *tree, int approx);
 void Init_Eigen_Struct(eigen *this);
-phydbl Triple_Dist(t_node *a,t_tree *tree,int approx);
+phydbl Triple_Dist(t_node *a,t_tree *tree);
+phydbl Triple_Dist_Approx(t_node *a, t_edge *b, t_tree *tree);
 void Make_Symmetric(phydbl **F,int size);
 void Round_Down_Freq_Patt(phydbl **F,t_tree *tree);
 phydbl Get_Sum_Of_Cells(phydbl *F,t_tree *tree);
@@ -1891,7 +2071,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);
@@ -1915,7 +2095,7 @@ t_tree *Generate_Random_Tree_From_Scratch(int n_otu,int rooted);
 #endif
 void Random_Lineage_Rates(t_node *a,t_node *d,t_edge *b,phydbl stick_prob,phydbl *rates,int curr_rate,int n_rates,t_tree *tree);
 t_edge *Find_Edge_With_Label(char *label,t_tree *tree);
-void Evolve(calign *data,t_mod *mod,t_tree *tree);
+void Evolve(calign *data, t_mod *mod, int first_site_pos, t_tree *tree);
 int Pick_State(int n,phydbl *prob);
 void Evolve_Recur(t_node *a,t_node *d,t_edge *b,int a_state,int r_class,int site_num,calign *gen_data,t_mod *mod,t_tree *tree);
 void Site_Diversity(t_tree *tree);
@@ -1932,7 +2112,7 @@ void Best_Of_NNI_And_SPR(t_tree *tree);
 int Polint(phydbl *xa,phydbl *ya,int n,phydbl x,phydbl *y,phydbl *dy);
 void JF(t_tree *tree);
 t_tree *Dist_And_BioNJ(calign *cdata,t_mod *mod,option *io);
-void Add_BioNJ_Branch_Lengths(t_tree *tree,calign *cdata,t_mod *mod);
+void Add_BioNJ_Branch_Lengths(t_tree *tree, calign *cdata, t_mod *mod, matrix *mat);
 char *Bootstrap_From_String(char *s_tree,calign *cdata,t_mod *mod,option *io);
 char *aLRT_From_String(char *s_tree,calign *cdata,t_mod *mod,option *io);
 void Prepare_Tree_For_Lk(t_tree *tree);
@@ -2009,27 +2189,8 @@ void Branch_To_Time_Pre(t_node *a, t_node *d, t_tree *tree);
 void Path_Length(t_node *dep, t_node *arr, phydbl *len, t_tree *tree);
 phydbl *Dist_Btw_Tips(t_tree *tree);
 void Random_SPRs_On_Rooted_Tree(t_tree *tree);
-
-
-void Set_P_Lk_One_Side(phydbl **Pij, phydbl **p_lk,  int **sum_scale, t_node *d, t_edge *b, t_tree *tree
-#ifdef BEAGLE
-                       , int* child_p_idx, int* Pij_idx
-#endif
-                       );
-
-
-void Set_All_P_Lk(t_node **n_v1, t_node **n_v2,
-                                 phydbl **p_lk , int **sum_scale , int **p_lk_loc,
-                  phydbl **Pij1, phydbl **p_lk1, int **sum_scale1,
-                  phydbl **Pij2, phydbl **p_lk2, int **sum_scale2,
-                  t_node *d, t_edge *b, t_tree *tree
-#ifdef BEAGLE
-                  , int *dest_p_idx, int *child1_p_idx, int* child2_p_idx, int* Pij1_idx, int* Pij2_idx
-#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);
@@ -2040,12 +2201,38 @@ int Number_Of_Diff_States_One_Site(int site, t_tree *tree);
 void Number_Of_Diff_States_One_Site_Post(t_node *a, t_node *d, t_edge *b, int site, t_tree *tree);
 int Number_Of_Diff_States_One_Site_Core(t_node *a, t_node *d, t_edge *b, int site, t_tree *tree);
 phydbl Get_Lk(t_tree *tree);
+phydbl Get_d2Lk(t_tree *tree);
+phydbl Get_dLk(t_tree *tree);
 align **Make_Empty_Alignment(option *io);
 void Connect_Edges_To_Nodes_Serial(t_tree *tree);
 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, bool remove_duplicates);
+void Remove_From_Linked_List(t_ll *elem, void *val, t_ll **list);
+int Linked_List_Len(t_ll *list);
+void *Linked_List_Elem(int pos, t_ll *ll);
+void Randomize_Tree(t_tree *tree, int n_prune_regraft);
+t_ll *Get_List_Of_Reachable_Tips(t_node *a, t_node *d, t_tree *tree);
+void Get_List_Of_Reachable_Tips_Post(t_node *a, t_node *d, t_ll **list, t_tree *tree);
+phydbl Length_Of_Path_Between_List_Of_Tips(t_ll *tips0, t_ll *tips1, matrix *mat);
+void Set_Update_Eigen_Lr(int yn, t_tree *tree);
+void Set_Use_Eigen_Lr(int yn, t_tree *tree);
+void Random_Walk_Along_Tree_On_Radius(t_node *a, t_node *d, t_edge *b, phydbl *radius, t_edge **target_edge, t_node **target_nd, phydbl *target_time, t_tree *tree);
+void Table_Top(unsigned int width);
+void Table_Row(unsigned int width);
+void Table_Bottom(unsigned int width);
 
 
 #include "xml.h"
diff --git a/src/xml.c b/src/xml.c
index 6ae9712..23c62ec 100644
--- a/src/xml.c
+++ b/src/xml.c
@@ -3,6 +3,1099 @@
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 
+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=0;i<N_MAX_MIXT_CLASSES;i++) 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);
+    }
+
+  s = XML_Get_Attribute_Value(p_elem,"r.seed");
+  if(s)
+    {
+      io->r_seed = (int)atoi(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(PHYTIME)
+  strcat(io->out_tree_file,"_phytime_tree.txt");
+# else
+  strcat(io->out_tree_file,"_phyml_tree.txt");
+#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(PHYTIME)
+  strcat(io->out_stats_file,"_phytime_stats.txt");
+# else
+  strcat(io->out_stats_file,"_phyml_stats.txt");
+#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.txt");
+          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;
+      iomod->s_opt->opt_subst_param = 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.txt");
+          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_Ratematrix_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->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;
@@ -131,7 +1224,7 @@ xml_node *XML_Load_File(FILE *fp)
               if(c != '/') parent = node;
 
               buffer[0] = '\0';
-            }     
+            }
           bufptr = buffer;
         }
       else if(isspace(c) == NO)
@@ -517,15 +1610,13 @@ 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 ", */
   /*     node?node->name:"xx", */
   /*     node->child?node->child->name:"xx", */
   /*     node->next?node->next->name:"xx"); fflush(NULL); */
-
-
+  
   match = NULL;
   if(skip == NO && !strcmp(node->name,name)) match = node;
   else
@@ -562,7 +1653,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");         
     }
       
@@ -617,12 +1708,15 @@ xml_node *XML_Search_Node_Attribute_Value(char *attr_name, char *value, int skip
       match = XML_Search_Node_Attribute_Value(attr_name, value, NO, node->child);
       return match;
     }
-
+  
   if(skip == NO && node->attr)
     {
       xml_attr *attr;
       char *sname, *sval;
+      char *qname, *qval;
 
+      qname = To_Lower_String(attr_name);
+      qval  = To_Lower_String(value);
 
       attr = node->attr;
       do
@@ -630,7 +1724,7 @@ xml_node *XML_Search_Node_Attribute_Value(char *attr_name, char *value, int skip
           sname = To_Lower_String(attr->name);
           sval  = To_Lower_String(attr->value);
 
-          if(!strcmp(sname,attr_name) && !strcmp(sval,value)) 
+          if(!strcmp(sname,qname) && !strcmp(sval,qval)) 
             {
               match = node;
               Free(sname);
@@ -640,11 +1734,15 @@ xml_node *XML_Search_Node_Attribute_Value(char *attr_name, char *value, int skip
 
           Free(sname);
           Free(sval);
+
           attr = attr->next;
+
           if(!attr) break;
         }
       while(1);
 
+      Free(qval);
+      Free(qname);
     }
 
   if(match) return(match);
@@ -702,7 +1800,7 @@ int XML_Validate_Attr_Int(char *target, int num, ...)
   sc_target = To_Lower_String(target);
   
   va_start(args,num);           
-  For(i,num)
+  for(i=0;i<num;i++)
     {
       s = va_arg(args, char *); 
       sc_s = To_Lower_String(s);      
@@ -1024,6 +2122,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 +2134,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