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

tille pushed a commit to branch master
in repository beast2-mcmc.

commit 0110375702f870fe075b1f2ccfb8465b9aeab5e7
Author: Andreas Tille <[email protected]>
Date:   Wed May 4 09:43:54 2016 +0200

    Imported Upstream version 2.4.1pre+dfsg
---
 build.xml                                          |  23 +++--
 examples/testUCLNclock.json                        |   2 +-
 release/Linux/bin/beast                            |  19 +++-
 release/Mac/install.png                            | Bin 17518 -> 17128 bytes
 release/Windows/AppStore_launch4j.xml              |   2 +-
 release/Windows/BEAST_launch4j.xml                 |   2 +-
 release/Windows/BEAUti_launch4j.xml                |   2 +-
 release/Windows/LogCombiner_launch4j.xml           |   2 +-
 release/Windows/TreeAnnotator_launch4j.xml         |   2 +-
 release/common/README.txt                          |   6 +-
 release/common/VERSION HISTORY.txt                 |  29 +++++-
 src/beast/app/BEASTVersion.java                    |   4 +-
 src/beast/app/beastapp/BeastLauncher.java          |  56 ++++++++---
 src/beast/app/beastapp/BeastMain.java              |  10 +-
 src/beast/app/beauti/AlignmentListInputEditor.java |  52 +++++-----
 src/beast/app/beauti/Beauti.java                   |  47 ++++++---
 src/beast/app/beauti/BeautiAlignmentProvider.java  |  12 ++-
 src/beast/app/beauti/BeautiDoc.java                | 101 +++++++++----------
 src/beast/app/beauti/BeautiLauncher.java           |   2 +
 src/beast/app/beauti/BeautiPanelConfig.java        |   2 +-
 src/beast/app/beauti/GuessPatternDialog.java       |  12 ++-
 src/beast/app/beauti/JPackageDialog.java           |   6 +-
 src/beast/app/beauti/TaxonSetInputEditor.java      |  36 ++++---
 src/beast/app/beauti/TipDatesInputEditor.java      |   2 +-
 src/beast/app/draw/InputEditorFactory.java         |   2 +-
 src/beast/app/draw/ListInputEditor.java            |   5 +-
 .../treeannotator/KernelDensityEstimator2D.java    |   2 +-
 src/beast/app/treeannotator/RealNumberField.java   |   2 +-
 src/beast/app/util/Utils.java                      | 107 +++++++++++++++++++++
 src/beast/app/util/Utils6.java                     |  12 +++
 src/beast/core/Input.java                          |   4 +
 src/beast/core/Logger.java                         |   7 +-
 src/beast/core/OperatorSchedule.java               |   2 -
 .../evolution/likelihood/BeagleTreeLikelihood.java |  80 ++++++++++++---
 .../likelihood/ThreadedTreeLikelihood.java         |   4 +-
 src/beast/evolution/likelihood/TreeLikelihood.java |   2 +-
 .../evolution/operators/DeltaExchangeOperator.java |  72 ++++++++------
 src/beast/evolution/operators/SubtreeSlide.java    |   2 +-
 .../evolution/sitemodel/SiteModelInterface.java    |   2 +-
 .../substitutionmodel/DefaultEigenSystem.java      |   6 +-
 .../evolution/substitutionmodel/Frequencies.java   |   9 +-
 src/beast/evolution/tree/RandomTree.java           |   6 +-
 src/beast/util/AddOnManager.java                   |  78 ++++++++++-----
 src/beast/util/ClusterTree.java                    |   3 +-
 src/beast/util/JSONProducer.java                   |  25 +++--
 src/beast/util/MersenneTwisterFast.java            |   4 +-
 src/beast/util/NexusParser.java                    |   2 +-
 src/beast/util/Package.java                        |   2 +-
 src/beast/util/PackageDependency.java              |   2 +-
 src/beast/util/Randomizer.java                     |   2 +-
 src/beast/util/TreeParser.java                     |   3 +-
 src/beast/util/XMLProducer.java                    |   4 +
 .../operator/DeltaExchangeOperatorTest.java        |  64 ++++++++++++
 .../beast/evolution/operator/TestOperator.java     |  52 ++++++++++
 src/test/beast/util/JSONTest.java                  |   6 +-
 templates/ClockModels.xml                          |  14 +--
 templates/Standard.xml                             |   2 +-
 templates/StarBeast.xml                            |   4 +-
 version.xml                                        |   2 +-
 59 files changed, 750 insertions(+), 276 deletions(-)

diff --git a/build.xml b/build.xml
index 821d599..ee8e6f8 100644
--- a/build.xml
+++ b/build.xml
@@ -90,6 +90,7 @@
         <delete 
file="${build}/beast/app/treeannotator/TreeAnnotatorLauncher.class" />
         <delete file="${build}/beast/app/util/Utils6.class" />
         <delete file="${build}/beast/app/BEASTVersion.class" />
+        <delete file="${build}/beast/app/util/Version.class" />
         <javac source="1.6"
                target="1.6"
                bootclasspath='/opt/jdk1.6.0_45/jre/lib/rt.jar'
@@ -103,6 +104,7 @@
             <include name="beast/**/*Launcher.java" />
             <include name="beast/**/Utils6.java" />
             <include name="beast/**/BEASTVersion.java" />
+            <include name="beast/**/Version.java" />
         </javac>
         <copy todir="${build}">
             <fileset dir="${src}" includes="**/*.properties" />
@@ -111,7 +113,7 @@
         <echo message="Successfully compiled." />
     </target>
 
-    <!-- make the beast.jar and beauti.jar -->
+    <!-- make the beast.jar -->
     <target name="dist_all_BEAST" depends="compile-all" description="create 
BEAST jar">
         <!-- Create the distribution directory -->
         <mkdir dir="${dist}" />
@@ -140,6 +142,7 @@
                 <include name="beast/**/*Launcher.class" />
                 <include name="beast/**/Utils6*.class" />
                 <include name="beast/**/BEASTVersion.class" />
+                <include name="beast/**/Version.class" />
                 <include name="beast/app/draw/icons/beauti.png"/>
             </fileset>
         </jar>
@@ -160,7 +163,7 @@
         <copy file="${dist}/beast.jar" todir="${release_dir}/package/lib/"/>
         <copy file="../beast2/version.xml" todir="${release_dir}/package/"/>
 
-        <jar jarfile="${release_dir}/package/beast.package.${version}.jar">
+        <jar jarfile="${release_dir}/package/beast.package.${version}.zip">
             <fileset dir="${release_dir}/package">
                 <include name="version.xml" />
                 <include name="lib/beast.jar" />
@@ -237,7 +240,7 @@
     <property name="version" value="2.4.0" />
     <property name="version_number" value="2.4.0" />
     <property name="release_dir" value="release" />
-    <property name="copyright" value="Beast 2 development team 2011-2015" />
+    <property name="copyright" value="Beast 2 development team 2011-2016" />
 
     <property name="BEAST_name" value="BEAST" />
     <property name="beast_name" value="beast" />
@@ -379,6 +382,7 @@
         <zip destfile="${Windows_dir}/${BEAST_name}.v${version}.zip">
             <zipfileset dir="${Windows_package_dir}" prefix="${BEAST_name}" />
         </zip>
+       <copy file="${Windows_dir}/${BEAST_name}.v${version}.zip" 
todir="../../tmp/" />
 
         <echo message="Windows version release is finished." />
     </target>
@@ -441,10 +445,14 @@
             </tar>-->
         <!-- [ANT Bug 550] the tar task change the mode of the executables 
files, have to tar manaully -->
         <echo message="Have to tar manaully, because [ANT Bug 550] the tar 
task change the mode of the executables files." />
-        <!-- tar -cvzf BEASTv1.x.x.tgz BEASTv1.x.x/ -->
-        <!-- cksum BEASTv1.x.x.tgz -->
-        <!-- tar -xvzf BEASTv1.x.x.tgz -->
+        <!-- tar -cvzf BEASTv1.x.x.tgz BEASTv2.x.x/ -->
+        <!-- cksum BEASTv2.x.x.tgz -->
+        <!-- tar -xvzf BEASTv2.x.x.tgz -->
         <echo message="Linux/Unix version release is finished." />
+        
+        <echo message="cd release/Linux"/>
+        <echo message="tar fcz BEAST.v${version}.tgz beast"/>
+        <echo message="cp BEAST.v${version}.tgz ~/tmp"/>
     </target>
 
     <!-- Define the appbundler task -->
@@ -661,6 +669,9 @@
         </exec>
 
         <delete file="${Mac_dir}/pack.temp.dmg"/>
+        
+       <copy file="${Mac_dir}/${BEAST_name} v${version}.dmg" 
tofile="../../tmp/${Mac_dir}/${BEAST_name}.v${version}.dmg" />
+
 
         <echo message="Mac version release is finished." />
     </target>
diff --git a/examples/testUCLNclock.json b/examples/testUCLNclock.json
index 7f90251..5bfbeb6 100644
--- a/examples/testUCLNclock.json
+++ b/examples/testUCLNclock.json
@@ -1,4 +1,4 @@
-{version: "2.3",
+{version: "2.4",
 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",
 
 beast: [
diff --git a/release/Linux/bin/beast b/release/Linux/bin/beast
index c6ee8c9..c947df4 100755
--- a/release/Linux/bin/beast
+++ b/release/Linux/bin/beast
@@ -29,4 +29,21 @@ if [ -z "$JAVA_HOME" ]; then
 else
   JAVA=$JAVA_HOME/bin/java
 fi
-$JAVA -Xms64m -Xmx4g -cp "$BEAST_LIB/launcher.jar" 
beast.app.beastapp.BeastLauncher $*
+
+
+# use BEAGL_LIB if the BEAGLE library is not in a standard location
+if [ -n "$BEAGLE_LIB" ]; then
+       if [ -n "$BEAST_EXTRA_LIBS" ]; then
+               BEAST_EXTRA_LIBS=$BEAST_EXTRA_LIBS:$BEAGLE_LIB
+       else
+               BEAST_EXTRA_LIBS=$BEAGLE_LIB
+       fi
+fi
+
+# use BEAST_EXTRA_LIBS variable to load BEAGLE and other libraries from 
non-default locations 
+# this assumes that the library path contains all these libraries (or are set 
through LD_LIBRARY_PATH)
+if [ -n "$BEAST_EXTRA_LIBS" ]; then 
+  $JAVA -Xms64m -Xmx4g -Djava.library.path=$BEAST_EXTRA_LIBS -cp 
"$BEAST_LIB/launcher.jar" beast.app.beastapp.BeastLauncher $*
+else   
+  $JAVA -Xms64m -Xmx4g -cp "$BEAST_LIB/launcher.jar" 
beast.app.beastapp.BeastLauncher $*
+fi
diff --git a/release/Mac/install.png b/release/Mac/install.png
index a409bf5..5649f43 100755
Binary files a/release/Mac/install.png and b/release/Mac/install.png differ
diff --git a/release/Windows/AppStore_launch4j.xml 
b/release/Windows/AppStore_launch4j.xml
index 0861c65..7426414 100644
--- a/release/Windows/AppStore_launch4j.xml
+++ b/release/Windows/AppStore_launch4j.xml
@@ -13,7 +13,7 @@
   </jre>    
   <versionInfo>
     <fileDescription>AppStore</fileDescription>
-    <copyright>Beast 2 development team 2002-2015</copyright>
+    <copyright>Beast 2 development team 2002-2016</copyright>
     <productName>AppStore</productName>
     <internalName>AppStore</internalName>
     <originalFilename>AppStore.exe</originalFilename>
diff --git a/release/Windows/BEAST_launch4j.xml 
b/release/Windows/BEAST_launch4j.xml
index 5e7d5ca..ae6145c 100644
--- a/release/Windows/BEAST_launch4j.xml
+++ b/release/Windows/BEAST_launch4j.xml
@@ -13,7 +13,7 @@
   </jre>    
   <versionInfo>
     <fileDescription>BEAST2</fileDescription>    
-    <copyright>Beast 2 development team 2002-2015</copyright>
+    <copyright>Beast 2 development team 2002-2016</copyright>
     <productName>BEAST2</productName>
     <internalName>BEAST2</internalName>
     <originalFilename>BEAST2.exe</originalFilename>    
diff --git a/release/Windows/BEAUti_launch4j.xml 
b/release/Windows/BEAUti_launch4j.xml
index e7b1f5d..c806677 100644
--- a/release/Windows/BEAUti_launch4j.xml
+++ b/release/Windows/BEAUti_launch4j.xml
@@ -13,7 +13,7 @@
   </jre>    
   <versionInfo>
     <fileDescription>BEAUti2</fileDescription>
-    <copyright>Beast 2 development team 2002-2015</copyright>
+    <copyright>Beast 2 development team 2002-2016</copyright>
     <productName>BEAUti2</productName>
     <internalName>BEAUti2</internalName>
     <originalFilename>BEAUti2.exe</originalFilename>    
diff --git a/release/Windows/LogCombiner_launch4j.xml 
b/release/Windows/LogCombiner_launch4j.xml
index 40e6fff..acf9b92 100644
--- a/release/Windows/LogCombiner_launch4j.xml
+++ b/release/Windows/LogCombiner_launch4j.xml
@@ -13,7 +13,7 @@
   </jre>    
   <versionInfo>
     <fileDescription>LogCombiner</fileDescription>    
-    <copyright>Beast 2 development team 2002-2015</copyright>
+    <copyright>Beast 2 development team 2002-2016</copyright>
     <productName>LogCombiner</productName>
     <internalName>LogCombiner</internalName>
     <originalFilename>LogCombiner.exe</originalFilename>    
diff --git a/release/Windows/TreeAnnotator_launch4j.xml 
b/release/Windows/TreeAnnotator_launch4j.xml
index 02982d1..be58c4f 100644
--- a/release/Windows/TreeAnnotator_launch4j.xml
+++ b/release/Windows/TreeAnnotator_launch4j.xml
@@ -12,7 +12,7 @@
   </jre>    
   <versionInfo>
     <fileDescription>TreeAnnotator</fileDescription>    
-    <copyright>Beast 2 development team 2002-2015</copyright>
+    <copyright>Beast 2 development team 2002-2016</copyright>
     <productName>TreeAnnotator</productName>
     <internalName>TreeAnnotator</internalName>
     <originalFilename>TreeAnnotator.exe</originalFilename>    
diff --git a/release/common/README.txt b/release/common/README.txt
index a19fbfb..bf68ffb 100644
--- a/release/common/README.txt
+++ b/release/common/README.txt
@@ -1,7 +1,7 @@
-                    BEAST v2.3.2 2015
-                 Beast 2 development team 2011-2015
+                    BEAST v2.4.0 2016
+                 Beast 2 development team 2011-2016
 
-Last updated: December 2015
+Last updated: March 2016
 
 Contents:
 1) INTRODUCTION
diff --git a/release/common/VERSION HISTORY.txt b/release/common/VERSION 
HISTORY.txt
index d5399e0..77610f2 100644
--- a/release/common/VERSION HISTORY.txt        
+++ b/release/common/VERSION HISTORY.txt        
@@ -1,10 +1,33 @@
-                    BEAST v2.3.2 2015
-                 Beast 2 development team 2011-2015
+                    BEAST v2.4.0 2016
+                 Beast 2 development team 2011-2016
 Version History
-Last updated: December 2015
+Last updated: March 2016
 
 All issues can be viewed at https://github.com/CompEvol/beast2/issues
 
================================================================================
+Version 2.4.0 February 2016
+    BEAST improved performance
+        up to 2x faster when using proportion invariant sites
+        improved threading support        
+        "instances" flag replaces beagle_instances
+        faster MRCAPrior handling
+        StartBeastStartState works with calibrations with other than 
CalibratedYule
+    
+    BEAUti
+        show mean of parametric distributions in priors panel
+        better taxon management preventing adding numbers to taxon names 
+        improved layout tip dates panel
+        improved package list errors
+        *BEAST clock cloning fix
+        Allow setting branch length as substitution option on tree logger
+        Improved JSON support
+        
+    Package manager
+       Allow BEAST to be upgraded as a package
+       Improved GUI
+    
+    For developers: 
http://beast2.org/2016/02/04/what-will-change-in-v2-4-0-for-developers/
+
 Version 2.3.2 December 2015
        BEAUti
                path corrected so Standard and StarBeast templates are visible 
under templates menu
diff --git a/src/beast/app/BEASTVersion.java b/src/beast/app/BEASTVersion.java
index 239cefa..999d551 100644
--- a/src/beast/app/BEASTVersion.java
+++ b/src/beast/app/BEASTVersion.java
@@ -19,9 +19,9 @@ public class BEASTVersion extends Version {
     /**
      * Version string: assumed to be in format x.x.x
      */
-    private static final String VERSION = "2.3.2";
+    private static final String VERSION = "2.4.0";
 
-    private static final String DATE_STRING = "2002-2015";
+    private static final String DATE_STRING = "2002-2016";
 
     private static final boolean IS_PRERELEASE = true;
 
diff --git a/src/beast/app/beastapp/BeastLauncher.java 
b/src/beast/app/beastapp/BeastLauncher.java
index 84b9515..c162ab0 100644
--- a/src/beast/app/beastapp/BeastLauncher.java
+++ b/src/beast/app/beastapp/BeastLauncher.java
@@ -1,34 +1,39 @@
 package beast.app.beastapp;
 
 
+
 import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
 import java.io.FileWriter;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.net.URL;
 import java.net.URLClassLoader;
 import java.net.URLDecoder;
-import java.nio.file.Files;
 
 import javax.swing.JOptionPane;
 
 import beast.app.BEASTVersion;
 import beast.app.util.Utils;
-import beast.core.util.Log;
+import beast.app.util.Utils6;
 
 
 /**
  * Loads beast.jar and launches BEAST through the BEASTMain class
  * 
  * This class should be compiled against 1.6 and packaged by itself. The
- * remained of BEAST can be compiled against Java 1.8
+ * remainder of BEAST can be compiled against Java 1.8
  * **/
 public class BeastLauncher {
 
        public static void main(String[] args) throws NoSuchMethodException, 
SecurityException, ClassNotFoundException, IllegalAccessException, 
IllegalArgumentException, InvocationTargetException, IOException {
                if (javaVersionCheck("BEAST")) {
                        loadBEASTJars();
+                       Utils.testCudaStatusOnMac();
                        BeastMain.main(args);
                }
        }
@@ -51,7 +56,7 @@ public class BeastLauncher {
                String launcherJar = 
clu.getClass().getProtectionDomain().getCodeSource().getLocation().getPath();
                // deal with special characters and spaces in path
                launcherJar = URLDecoder.decode(launcherJar, "UTF-8");
-               Log.warning.println("jardir = " + launcherJar);
+               System.err.println("jardir = " + launcherJar);
                File jarDir0 = new File(launcherJar).getParentFile();
                while ((!foundOne) && (jarDir0 != null)) { // && 
jarDir0.exists() &&
                                                                                
        // jarDir0.isDirectory()) {
@@ -67,7 +72,7 @@ public class BeastLauncher {
                }
                
                if (!foundOne) {
-                       Log.warning.println("WARNING: could not find 
beast.jar");
+                       System.err.println("WARNING: could not find beast.jar");
                        // if beast.jar or its classes are not already in the 
class path (as is when launched e.g. as developer)
                        // the next line will fail
                }
@@ -80,6 +85,10 @@ public class BeastLauncher {
 
        private static void createBeastPackage(File jarDir0, String 
pathDelimiter) {
                try {
+               if (jarDir0.toString().toLowerCase().endsWith("lib")) {
+                       jarDir0 = jarDir0.getParentFile();
+               }
+
                        // create package user dir, if it not already exists
                File dir = new File(getPackageUserDir() + pathDelimiter + 
"BEAST" + pathDelimiter + "lib");
                if (!dir.exists()) {
@@ -91,17 +100,17 @@ public class BeastLauncher {
                
                File beastJar = new File(jarDir0 + pathDelimiter + "lib" + 
pathDelimiter + "beast.jar");
                File target = new File(dir + pathDelimiter + "beast.jar");
-               Files.copy(beastJar.toPath(), target.toPath());
+               copyFileUsingStream(beastJar, target);
                
                String version = "<addon name='BEAST' version='" + (new 
BEASTVersion()).getVersion() + "'>\n" +
                                "</addon>";
-               FileWriter outfile = new FileWriter(getPackageUserDir() + 
pathDelimiter + "beast" + pathDelimiter + "version.xml");
+               FileWriter outfile = new FileWriter(getPackageUserDir() + 
pathDelimiter + "BEAST" + pathDelimiter + "version.xml");
                outfile.write(version);
                outfile.close();
 
                File beastSrcJar = new File(jarDir0 + pathDelimiter + "lib" + 
pathDelimiter + "beast.src.jar");
                File srcTarget = new File(dir + pathDelimiter + 
"beast.src.jar");
-               Files.copy(beastSrcJar.toPath(), srcTarget.toPath());
+               copyFileUsingStream(beastSrcJar, srcTarget);
 
                // TODO: include templates?
                // if so, how to prevent clashes with templates in package and 
in installation dir?
@@ -112,9 +121,27 @@ public class BeastLauncher {
                }
 
        }
-
+       
+       // copy files using Java 6 code
+       private static void copyFileUsingStream(File source, File dest) throws 
IOException {
+
+           InputStream is = null;
+           OutputStream os = null;
+           try {
+               is = new FileInputStream(source);
+               os = new FileOutputStream(dest);
+               byte[] buffer = new byte[1024];
+               int length;
+               while ((length = is.read(buffer)) > 0) {
+                   os.write(buffer, 0, length);
+               }
+           } finally {
+               is.close();
+               os.close();
+           }
+       }
        private static boolean checkForBEAST(File jarDir, Object clu) throws 
IOException {
-               Log.warning.println("Checking out " + jarDir.getAbsolutePath());
+               System.err.println("Checking out " + jarDir.getAbsolutePath());
                boolean foundOne = false;
                if (jarDir.exists()) {
                        URL url = new URL("file://" + (isWindows() ? "/" : "") 
+ jarDir.getAbsolutePath() + "/beast.jar");
@@ -127,7 +154,7 @@ public class BeastLauncher {
                                        Method method = 
sysclass.getDeclaredMethod("addURL", parameters);
                                        method.setAccessible(true);
                                        method.invoke(sysLoader, new Object[] { 
url });
-                                       Log.warning.println("Loaded URL " + 
url);
+                                       System.err.println("Loaded URL " + url);
                                        foundOne = true;
                                } catch (Throwable t) {
                                        t.printStackTrace();
@@ -171,7 +198,7 @@ public class BeastLauncher {
                                        } else {
                                                JAVA_VERSION_MSG = 
JAVA_VERSION_MSG.replaceAll("<br>", "\n");
                                                JAVA_VERSION_MSG = 
JAVA_VERSION_MSG.replaceAll("<[^<]*>", "");
-                                               
Log.warning.println(JAVA_VERSION_MSG);
+                                               
System.err.println(JAVA_VERSION_MSG);
                                        }
                                        return true;
                                }
@@ -189,14 +216,13 @@ public class BeastLauncher {
        }
 
     public static String getPackageUserDir() {
-        
         if (System.getProperty("beast.user.package.dir") != null)
             return System.getProperty("beast.user.package.dir");
         
-        if (Utils.isWindows()) {
+        if (Utils6.isWindows()) {
             return System.getProperty("user.home") + "\\BEAST\\" + (new 
BEASTVersion()).getMajorVersion();
         }
-        if (Utils.isMac()) {
+        if (Utils6.isMac()) {
             return System.getProperty("user.home") + "/Library/Application 
Support/BEAST/" + (new BEASTVersion()).getMajorVersion();
         }
         // Linux and unices
diff --git a/src/beast/app/beastapp/BeastMain.java 
b/src/beast/app/beastapp/BeastMain.java
index 51ba2b6..b7f1807 100644
--- a/src/beast/app/beastapp/BeastMain.java
+++ b/src/beast/app/beastapp/BeastMain.java
@@ -257,7 +257,7 @@ public class BeastMain {
                         new Arguments.Option("validate", "Parse the XML, but 
do not run -- useful for debugging XML"),
                         // RRB: not sure what effect this option has
                         new Arguments.IntegerOption("errors", "Specify maximum 
number of numerical errors before stopping"),
-                        new Arguments.IntegerOption("threads", "The number of 
computational threads to use (default auto)"),
+                        new Arguments.IntegerOption("threads", "The number of 
computational threads to use (default 1), -1 for number of cores"),
                         new Arguments.Option("java", "Use Java only, no native 
implementations"),
                         new Arguments.Option("noerr", "Suppress all output to 
standard error"),
                         new Arguments.StringOption("loglevel", "LEVEL", 
"error,warning,info,debug,trace"),
@@ -273,6 +273,7 @@ public class BeastMain {
                         new Arguments.StringOption("beagle_scaling", new 
String[]{"default", "none", "dynamic", "always"},
                                 false, "BEAGLE: specify scaling scheme to 
use"),
                         new Arguments.Option("help", "Print this information 
and stop"),
+                        new Arguments.Option("version", "Print version and 
stop"),
                 });
 
         try {
@@ -285,6 +286,11 @@ public class BeastMain {
             System.exit(1);
         }
 
+        if (arguments.hasOption("version")) {
+               Log.info.println((new BEASTVersion()).getVersionString());
+               System.exit(0);
+        }
+
         if (arguments.hasOption("help")) {
             printUsage(arguments);
             System.exit(0);
@@ -304,7 +310,7 @@ public class BeastMain {
         long seed = Randomizer.getSeed();
         boolean useJava = false;
 
-        int threadCount = 0;
+        int threadCount = 1;
 
         if (arguments.hasOption("java")) {
             useJava = true;
diff --git a/src/beast/app/beauti/AlignmentListInputEditor.java 
b/src/beast/app/beauti/AlignmentListInputEditor.java
index 24cc766..41997cc 100644
--- a/src/beast/app/beauti/AlignmentListInputEditor.java
+++ b/src/beast/app/beauti/AlignmentListInputEditor.java
@@ -711,33 +711,31 @@ public class AlignmentListInputEditor extends 
ListInputEditor {
                                } else {
                                        comp.setBackground(Color.white);
                                }
-                           JComponent jcomp = (JComponent)comp;
-                           if (comp == jcomp) {
-                               switch (Index_col) {
-                               case NAME_COLUMN:                               
        
-                               case CLOCKMODEL_COLUMN: 
-                               case TREE_COLUMN: 
-                               case SITEMODEL_COLUMN: 
-                                       jcomp.setToolTipText("Set " + 
table.getColumnName(Index_col).toLowerCase() + " for this partition");
-                                               break;
-                               case FILE_COLUMN:
-                               case TAXA_COLUMN:
-                               case SITES_COLUMN:
-                               case TYPE_COLUMN:
-                                       jcomp.setToolTipText("Report " + 
table.getColumnName(Index_col).toLowerCase() + " for this partition");
-                                               break;
-                               case USE_AMBIGUITIES_COLUMN: 
-                                               
jcomp.setToolTipText("<html>Flag whether to use ambiguities.<br>" +
-                                                               "If not set, 
the treelikelihood will treat ambiguities in the<br>" +
-                                                               "data as 
unknowns<br>" +
-                                                               "If set, the 
treelikelihood will use ambiguities as equally<br>" +
-                                                               "likely values 
for the tips.<br>" +
-                                                               "This will make 
the computation twice as slow.</html>");
-                                               break;
-                                       default:
-                                       jcomp.setToolTipText(null);
-                               }
-                           }
+                           JComponent jcomp = (JComponent) comp;
+                       switch (Index_col) {
+                       case NAME_COLUMN:                                       
+                       case CLOCKMODEL_COLUMN: 
+                       case TREE_COLUMN: 
+                       case SITEMODEL_COLUMN: 
+                               jcomp.setToolTipText("Set " + 
table.getColumnName(Index_col).toLowerCase() + " for this partition");
+                                       break;
+                       case FILE_COLUMN:
+                       case TAXA_COLUMN:
+                       case SITES_COLUMN:
+                       case TYPE_COLUMN:
+                               jcomp.setToolTipText("Report " + 
table.getColumnName(Index_col).toLowerCase() + " for this partition");
+                                       break;
+                       case USE_AMBIGUITIES_COLUMN: 
+                                       jcomp.setToolTipText("<html>Flag 
whether to use ambiguities.<br>" +
+                                                       "If not set, the 
treelikelihood will treat ambiguities in the<br>" +
+                                                       "data as unknowns<br>" +
+                                                       "If set, the 
treelikelihood will use ambiguities as equally<br>" +
+                                                       "likely values for the 
tips.<br>" +
+                                                       "This will make the 
computation twice as slow.</html>");
+                                       break;
+                               default:
+                               jcomp.setToolTipText(null);
+                       }
                                updateStatus();
                                return comp;
                        }
diff --git a/src/beast/app/beauti/Beauti.java b/src/beast/app/beauti/Beauti.java
index 5137330..3842a55 100644
--- a/src/beast/app/beauti/Beauti.java
+++ b/src/beast/app/beauti/Beauti.java
@@ -81,7 +81,7 @@ public class Beauti extends JTabbedPane implements 
BeautiDocListener {
     static public final String FILE_EXT = ".xml";
     static public final String FILE_EXT2 = ".json";
     static final String fileSep = System.getProperty("file.separator");
-    
+
     /**
      * document in document-view pattern. BTW this class is the view
      */
@@ -318,7 +318,7 @@ public class Beauti extends JTabbedPane implements 
BeautiDocListener {
         @Override
                public void actionPerformed(ActionEvent ae) {
             File file = beast.app.util.Utils.getLoadFile("Load Beast XML File",
-                    new File(g_sDir), "Beast XML files", "xml");
+                    new File(g_sDir), "Beast XML files", "xml");//, "BEAST 
json file", "json");
             // JFileChooser fileChooser = new JFileChooser(g_sDir);
             // fileChooser.addChoosableFileFilter(ef1);
             // fileChooser.setDialogTitle("Load Beast XML File");
@@ -338,6 +338,7 @@ public class Beauti extends JTabbedPane implements 
BeautiDocListener {
                             doc.getFileName().lastIndexOf(fileSep));
                 }
                 try {
+                       // TODO: deal with json files
                     doc.loadXML(new File(doc.getFileName()));
                     a_save.setEnabled(true);
                     a_saveas.setEnabled(true);
@@ -607,7 +608,7 @@ public class Beauti extends JTabbedPane implements 
BeautiDocListener {
             setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
         }
     } // class ActionHelp
-    
+
     class ActionMsgs extends MyAction {
         private static final long serialVersionUID = -1;
 
@@ -629,7 +630,7 @@ public class Beauti extends JTabbedPane implements 
BeautiDocListener {
                        JScrollPane scroller = new JScrollPane(textArea);
                        JOptionPane.showMessageDialog(frame, scroller);
                }
-        }      
+        }
     }
 
     class ActionCitation extends MyAction implements ClipboardOwner {
@@ -964,7 +965,7 @@ public class Beauti extends JTabbedPane implements 
BeautiDocListener {
                                 fileName = fileName.substring(0, 
fileName.length() - 4);
                                 boolean duplicate = false;
                                for (AbstractAction action : actions) {
-                                       String name = 
action.getValue(Action.NAME).toString(); 
+                                       String name = 
action.getValue(Action.NAME).toString();
                                        if (name.equals(fileName)) {
                                                duplicate = true;
                                        }
@@ -990,12 +991,12 @@ public class Beauti extends JTabbedPane implements 
BeautiDocListener {
                if (new File(exampledir).exists()) {
                        AbstractAction action = new AbstractAction() {
                                        private static final long 
serialVersionUID = 1L;
-       
+
                                        @Override
                                        public void actionPerformed(ActionEvent 
e) {
                                                g_sDir = dir;
                                        }
-                       
+
                    };
                    String workDirInfo = "Set working directory to " + dir;
                    String name = dir;
@@ -1085,10 +1086,32 @@ public class Beauti extends JTabbedPane implements 
BeautiDocListener {
        return BEAUtiIntances > 0;
     }
 
+    private static String usage() {
+        return "java Beauti [options]\n" + "where options can be one of the 
following:\n"
+                + "-template [template file] : BEAUti template to be used. 
Default templates/Standard.xml\n"
+                       + "-nex [nexus data file] : nexus file to be read using 
template, multiple -nex arguments are allowed\n"
+                + "-xmldat [beast xml file] : as -nex but with BEAST 1 or 2 
xml file instead of nexus file\n"
+                + "-xml [beast file] : BEAST 2 XML file to be loaded\n"
+                + "-exitaction [writexml|usetemplate|usexml] : what to do 
after processing arguments\n"
+                + "-out [output file name] : file to be written\n"
+                + "-capture : captures stdout and stderr and make them 
available under Help/Messages menu\n"
+                + "-v, -version : print version\n"
+                + "-h, -help : print this help message\n";
+    }
+
+
     public static Beauti main2(String[] args) {
         try {
                ByteArrayOutputStream baos = null;
             for (String arg : args) {
+               if (arg.equals("-v") || arg.equals("-version")) {
+                    System.out.println((new 
BEASTVersion()).getVersionString());
+                    System.exit(0);
+               }
+               if (arg.equals("-h") || arg.equals("-help")) {
+                    System.out.println(usage());
+                    System.exit(0);
+               }
                if (arg.equals("-capture")) {
                        final PrintStream beautiLog = System.err;
                        baos = new ByteArrayOutputStream() {
@@ -1103,26 +1126,26 @@ public class Beauti extends JTabbedPane implements 
BeautiDocListener {
                                        super.write(b);
                                        beautiLog.write(b);
                                };
-                               
+
                                @Override
                                public void write(byte[] b) throws 
java.io.IOException {
                                        super.write(b);
                                        beautiLog.write(b);
                                };
-                               
+
                                @Override
                                public void flush() throws java.io.IOException {
                                        super.flush();
                                        beautiLog.flush();
                                };
-                               
+
                                @Override
                                public void close() throws IOException {
                                        super.close();
                                        beautiLog.close();
                                }
                        };
-                       
+
                        PrintStream p = new PrintStream(baos);
                        System.setOut(p);
                        System.setErr(p);
@@ -1133,7 +1156,7 @@ public class Beauti extends JTabbedPane implements 
BeautiDocListener {
                        Log.trace = p;
                }
             }
-               
+
             AddOnManager.loadExternalJars();
             if (!Utils.isMac()) {
                Utils.loadUIManager();
diff --git a/src/beast/app/beauti/BeautiAlignmentProvider.java 
b/src/beast/app/beauti/BeautiAlignmentProvider.java
index 94a03cb..66e4fac 100644
--- a/src/beast/app/beauti/BeautiAlignmentProvider.java
+++ b/src/beast/app/beauti/BeautiAlignmentProvider.java
@@ -54,7 +54,7 @@ public class BeautiAlignmentProvider extends BEASTObject {
         * return amount to which the provided matches an alignment 
         * The provider with the highest match will be used to edit the 
alignment 
         * */
-       int matches(Alignment alignment) {
+       protected int matches(Alignment alignment) {
                return 1;
        }
        
@@ -161,6 +161,11 @@ public class BeautiAlignmentProvider extends BEASTObject {
                     break;
                        }
         }
+        addAlignments(doc, selectedBEASTObjects);
+        return selectedBEASTObjects;
+    }
+    
+    protected void addAlignments(BeautiDoc doc, List<BEASTInterface> 
selectedBEASTObjects) {
         for (BEASTInterface beastObject : selectedBEASTObjects) {
                // ensure ID of alignment is unique
                int k = 0;
@@ -173,7 +178,6 @@ public class BeautiAlignmentProvider extends BEASTObject {
                sortByTaxonName(((Alignment) beastObject).sequenceInput.get());
             doc.addAlignmentWithSubnet((Alignment) beastObject, 
getStartTemplate());
         }
-        return selectedBEASTObjects;
     }
 
        /** provide GUI for manipulating the alignment **/
@@ -196,11 +200,11 @@ public class BeautiAlignmentProvider extends BEASTObject {
        
        /** return template to apply to this new alignment.
         * By default, the partition template of the current beauti template is 
returned **/
-       BeautiSubTemplate getStartTemplate() {
+       protected BeautiSubTemplate getStartTemplate() {
                return template.get();
        }
 
-    private void sortByTaxonName(List<Sequence> seqs) {
+    protected void sortByTaxonName(List<Sequence> seqs) {
         Collections.sort(seqs, (Sequence o1, Sequence o2) -> {
                 return o1.taxonInput.get().compareTo(o2.taxonInput.get());
             }
diff --git a/src/beast/app/beauti/BeautiDoc.java 
b/src/beast/app/beauti/BeautiDoc.java
index 0574181..b58f7bf 100644
--- a/src/beast/app/beauti/BeautiDoc.java
+++ b/src/beast/app/beauti/BeautiDoc.java
@@ -101,7 +101,7 @@ public class BeautiDoc extends BEASTObject implements 
RequiredInputProvider {
      */
 
     public boolean autoSetClockRate = true;
-        
+
     public boolean autoUpdateOperatorWeights = true;
 
     public boolean autoUpdateFixMeanSubstRate = true;
@@ -159,7 +159,7 @@ public class BeautiDoc extends BEASTObject implements 
RequiredInputProvider {
     public Set<Input<?>> linked;
 
     InputEditorFactory inputEditorFactory;
-    
+
     /** used to capture Stdout and Stderr **/
     static ByteArrayOutputStream baos = null;
 
@@ -186,7 +186,7 @@ public class BeautiDoc extends BEASTObject implements 
RequiredInputProvider {
     public String getTemplateName() {
         return templateName;
     }
-    
+
     public ActionOnExit parseArgs(String[] args) throws XMLParserException, 
SAXException, IOException, ParserConfigurationException  {
         ActionOnExit endState = ActionOnExit.UNKNOWN;
         String outputFileName = "beast.xml";
@@ -200,8 +200,6 @@ public class BeautiDoc extends BEASTObject implements 
RequiredInputProvider {
                 int old = i;
                 if (args[i].equals("")) {
                     i += 1;
-                } else if (args[i].equals("-h") || args[i].equals("-help")) {
-                    showUsageAndExit();
                 } else if (args[i].equals("-capture")) {
                        // capture stderr and stdout
                        // already done in beast.app.beauti.Beauti
@@ -289,16 +287,7 @@ public class BeautiDoc extends BEASTObject implements 
RequiredInputProvider {
         return fileName.substring(0, fileName.length() - 4);
     }
 
-    void showUsageAndExit() {
-        System.out.println(usage());
-        System.exit(0);
-    }
 
-    String usage() {
-        return "java Beauti [options]\n" + "where options can be one of the 
following:\n"
-                + "-template [template file]\n" + "-nex [nexus data file]\n" + 
"-xmldat [beast xml file]\n"
-                + "-xml [beast file]\n" + "-out [output file name]\n" + 
"-exitaction [writexml|usetemplate|usexml]\n";
-    }
 
     private Set<BeautiDocListener> listeners = new HashSet<>();
 
@@ -346,14 +335,14 @@ public class BeautiDoc extends BEASTObject implements 
RequiredInputProvider {
         taxaset.remove(beastObject.getID());
         // directly remove beast object from HashMap
         // relies on hashes of String being unique (which they should be).
-        // is much more efficient (O(1)) than lookup in keySet (O(n)), 
-        // which matter when a lot of partitions are loaded 
+        // is much more efficient (O(1)) than lookup in keySet (O(n)),
+        // which matter when a lot of partitions are loaded
         // but less reliable since ID may have changed.
         String id = reversePluginmap.get(beastObject);
         if (id != null && pluginmap.containsKey(id)) {
             pluginmap.remove(id);
         }
-        
+
 //        String oldID = null;
 //        for (String id : pluginmap.keySet()) {
 //            if (pluginmap.get(id).equals(beastObject)) {
@@ -464,12 +453,12 @@ public class BeautiDoc extends BEASTObject implements 
RequiredInputProvider {
 //
 //                     XMLProducer producer = new XMLProducer();
 //                     producer.toRawXML(alignments.get(0));
-//                     
+//
 //                     Pplugin beastObject =  parser.parseFragment(xml, false);
 //                     int i = xml.indexOf("<data");
 //                     for (BEASTObject beastObject : pluginmap.values()) {
 //                             if (beastObject instanceof Alignment) {
-//                                     
+//
 //                             }
 //                     }
 //                     save(fileName);
@@ -485,7 +474,7 @@ public class BeautiDoc extends BEASTObject implements 
RequiredInputProvider {
     }
 
     /**
-     * public to allow access for unit test 
+     * public to allow access for unit test
      * @throws IOException *
      */
     public String processTemplate(String fileName) throws IOException {
@@ -714,7 +703,7 @@ public class BeautiDoc extends BEASTObject implements 
RequiredInputProvider {
     } // validateModel
 
     /**
-     * save specification in file 
+     * save specification in file
      * @throws IOException *
      */
     public void save(String fileName) throws IOException  {
@@ -722,7 +711,7 @@ public class BeautiDoc extends BEASTObject implements 
RequiredInputProvider {
     } // save
 
     /**
-     * save specification in file 
+     * save specification in file
      * @throws IOException *
      */
     public void save(File file) throws IOException  {
@@ -815,7 +804,7 @@ public class BeautiDoc extends BEASTObject implements 
RequiredInputProvider {
         beauti.allowLinking.setSelected(allowLinking);
         autoUpdateOperatorWeights = 
!beautiStatus.contains("noAutoUpdateOperatorWeights");
         
beauti.autoUpdateOperatorWeights.setSelected(autoUpdateOperatorWeights);
-        autoUpdateFixMeanSubstRate = 
!beautiStatus.contains("noAutoUpdateFixMeanSubstRate"); 
+        autoUpdateFixMeanSubstRate = 
!beautiStatus.contains("noAutoUpdateFixMeanSubstRate");
         
beauti.autoUpdateFixMeanSubstRate.setSelected(autoUpdateFixMeanSubstRate);
 
         // parse file
@@ -875,10 +864,10 @@ public class BeautiDoc extends BEASTObject implements 
RequiredInputProvider {
 
     /**
      * Merge sequence data with xml specification.
-     * @throws ParserConfigurationException 
-     * @throws IOException 
-     * @throws SAXException 
-     * @throws XMLParserException 
+     * @throws ParserConfigurationException
+     * @throws IOException
+     * @throws SAXException
+     * @throws XMLParserException
      */
     void mergeSequences(String xml) throws XMLParserException, SAXException, 
IOException, ParserConfigurationException {
         if (xml == null) {
@@ -1110,17 +1099,17 @@ public class BeautiDoc extends BEASTObject implements 
RequiredInputProvider {
             }
 
             // set estimate flag on tree, only if tree occurs in a partition
-            for (BEASTInterface beastObject : pluginmap.values()) {
-                if (beastObject instanceof Tree) {
-                    Tree tree = (Tree) beastObject;
-                    tree.isEstimatedInput.setValue(false, tree);
-                }
-            }
-            for (BEASTInterface beastObject : pPartition[2]) {
-                // TODO: this might not be a valid type conversion from 
TreeInterface to Tree
-                Tree tree = (Tree) ((GenericTreeLikelihood) 
beastObject).treeInput.get();
-                tree.isEstimatedInput.setValue(true, tree);
-            }
+//            for (BEASTInterface beastObject : pluginmap.values()) {
+//                if (beastObject instanceof Tree) {
+//                    Tree tree = (Tree) beastObject;
+//                    tree.isEstimatedInput.setValue(false, tree);
+//                }
+//            }
+//            for (BEASTInterface beastObject : pPartition[2]) {
+//                // TODO: this might not be a valid type conversion from 
TreeInterface to Tree
+//                Tree tree = (Tree) ((GenericTreeLikelihood) 
beastObject).treeInput.get();
+//                tree.isEstimatedInput.setValue(true, tree);
+//            }
             if (pluginmap.containsKey("Tree.t:Species")) {
                 Tree tree = (Tree) pluginmap.get("Tree.t:Species");
                 tree.isEstimatedInput.setValue(true, tree);
@@ -1200,7 +1189,7 @@ public class BeautiDoc extends BEASTObject implements 
RequiredInputProvider {
         } catch (Exception e) {
             Log.err.println(e.getMessage());
         }
-        
+
         if (autoUpdateOperatorWeights) {
                reweightSpeciesPartitionOperators();
         }
@@ -1213,17 +1202,17 @@ public class BeautiDoc extends BEASTObject implements 
RequiredInputProvider {
         if (pluginmap.containsKey("likelihood")) {
             collectPredecessors(pluginmap.get("likelihood"), 
likelihoodPredecessors);
         }
-        
-                
-        Log.warning.print("InPosterior=");
+
+
+        Log.trace.print("InPosterior=");
         for (BEASTInterface o : posteriorPredecessors) {
                pluginmap.put(o.getID(), o);
-               Log.warning.print(o.getID() + " ");
+               Log.trace.print(o.getID() + " ");
                //if (!pluginmap.containsKey(o)) {
                //      System.err.println("MISSING: " + o.getID());
                //}
         }
-        Log.warning.println();
+        Log.trace.println();
     }
 
     public static String translatePartitionNames(String str, PartitionContext 
partition) {
@@ -1237,18 +1226,18 @@ public class BeautiDoc extends BEASTObject implements 
RequiredInputProvider {
                for (int i = 0; i < len; i++) {
                        char c = str.charAt(i);
                        if (c == '.' && i < len - 6) {
-                               if (str.charAt(i + 2) == ':' && str.charAt(i + 
3) == '$' && 
+                               if (str.charAt(i + 2) == ':' && str.charAt(i + 
3) == '$' &&
                                                str.charAt(i + 4) == '(' && 
str.charAt(i + 5) == 'n' && str.charAt(i + 6) == ')') {
                                        switch (str.charAt(i+1)) {
                                        case 's': // .s:$(n)
                                                
sb.append(".s:").append(partition.siteModel);
                                                i += 6;
                                                break;
-                                       case 'c': 
+                                       case 'c':
                                                
sb.append(".c:").append(partition.clockModel);
                                                i += 6;
                                                break;
-                                       case 't': 
+                                       case 't':
                                                
sb.append(".t:").append(partition.tree);
                                                i += 6;
                                                break;
@@ -1323,7 +1312,7 @@ public class BeautiDoc extends BEASTObject implements 
RequiredInputProvider {
                    }
                }
         }
-       
+
         BEASTInterface likelihood = pluginmap.get("likelihood");
         if (likelihood instanceof CompoundDistribution) {
             int i = 0;
@@ -1494,15 +1483,15 @@ public class BeautiDoc extends BEASTObject implements 
RequiredInputProvider {
     }
 
     /**
-      * Reweight total weight of operators that work on the Species partition 
to 20% 
+      * Reweight total weight of operators that work on the Species partition 
to 20%
       * of total operator weights. This helps *BEAST analyses in convergence. 
For non
-      * *BEAST analyses, this bit of code has no effect. 
+      * *BEAST analyses, this bit of code has no effect.
       */
     private void reweightSpeciesPartitionOperators() {
        if (!(mcmc.get() instanceof MCMC)) {
                return;
        }
-       List<Operator> speciesOperators = new ArrayList<>(); 
+       List<Operator> speciesOperators = new ArrayList<>();
        double totalWeight = 0;
        double speciesWeight = 0;
        for (Operator operator : ((MCMC)mcmc.get()).operatorsInput.get()) {
@@ -1512,7 +1501,7 @@ public class BeautiDoc extends BEASTObject implements 
RequiredInputProvider {
                        }
                        totalWeight += operator.getWeight();
        }
-       
+
        if (speciesWeight > 0 && speciesWeight < totalWeight) {
                // we have a Species-related operator AND an alignment
                // rescale weights so that 20% of operator weights is dedicated 
to Species operators
@@ -1523,7 +1512,7 @@ public class BeautiDoc extends BEASTObject implements 
RequiredInputProvider {
                        operator.m_pWeight.setValue(scale * 
operator.getWeight(), operator);
                }
        }
-               
+
        }
 
        public BEASTInterface addAlignmentWithSubnet(PartitionContext context, 
BeautiSubTemplate template)  {
@@ -1910,7 +1899,7 @@ public class BeautiDoc extends BEASTObject implements 
RequiredInputProvider {
                                Object o2 = 
copy.getInput(input.getName()).get();
                                boolean alreadyInList = false;
                                if (o2 instanceof List) {
-                                       List<?> currentList = (List<?>) o2; 
+                                       List<?> currentList = (List<?>) o2;
                                        for (Object v : currentList) {
                                                if (v == value) {
                                                        alreadyInList = true;
@@ -2419,7 +2408,7 @@ public class BeautiDoc extends BEASTObject implements 
RequiredInputProvider {
     }
 
     /** create taxonset, one taxon for each sequence in the alignment
-     * and assign taxonset to the alignment 
+     * and assign taxonset to the alignment
      * **/
     static void createTaxonSet(Alignment a, BeautiDoc doc) {
                List<String> taxaNames = a.getTaxaNames();
@@ -2436,7 +2425,7 @@ public class BeautiDoc extends BEASTObject implements 
RequiredInputProvider {
                doc.registerPlugin(taxonset);
        }
 
-    /** create Taxon with given name, reuse if a taxon 
+    /** create Taxon with given name, reuse if a taxon
      *  with this name already exists
      **/
        public Taxon getTaxon(String taxaName) {
diff --git a/src/beast/app/beauti/BeautiLauncher.java 
b/src/beast/app/beauti/BeautiLauncher.java
index ad06a68..f326e8c 100644
--- a/src/beast/app/beauti/BeautiLauncher.java
+++ b/src/beast/app/beauti/BeautiLauncher.java
@@ -5,6 +5,7 @@ import java.io.IOException;
 import java.lang.reflect.InvocationTargetException;
 
 import beast.app.beastapp.BeastLauncher;
+import beast.app.util.Utils;
 import beast.app.util.Utils6;
 
 /** 
@@ -19,6 +20,7 @@ public class BeautiLauncher extends BeastLauncher {
                Utils6.startSplashScreen();
                if (javaVersionCheck("BEAUti")) {
                        loadBEASTJars();
+                       Utils.testCudaStatusOnMac();
                        Beauti.main(args);
                }
         Utils6.endSplashScreen();
diff --git a/src/beast/app/beauti/BeautiPanelConfig.java 
b/src/beast/app/beauti/BeautiPanelConfig.java
index 3e7efde..5b52baa 100644
--- a/src/beast/app/beauti/BeautiPanelConfig.java
+++ b/src/beast/app/beauti/BeautiPanelConfig.java
@@ -32,7 +32,7 @@ public class BeautiPanelConfig extends BEASTObject {
             "distribution/distribution[id='posterior']/traitset all posterior 
inputs with name traitset", Validate.REQUIRED);
 
     final public Input<Partition> hasPartitionsInput = new 
Input<>("hasPartitions", "flag to indicate the panel has" +
-            "a partition context (and hence a partition list), deafult none.  
Possible values: " + Partition.values(), Partition.none, Partition.values());
+            "a partition context (and hence a partition list), deafult none.  
Possible values: " + Arrays.toString(Partition.values()), Partition.none, 
Partition.values());
 
     final public Input<Boolean> addButtonsInput = new Input<>("addButtons", 
"flag to indicate buttons should be added, default true", true);
     final public Input<Boolean> isVisibleInput = new Input<>("isVisible", 
"flag to indicate panel is visible on startup, default true", true);
diff --git a/src/beast/app/beauti/GuessPatternDialog.java 
b/src/beast/app/beauti/GuessPatternDialog.java
index 48a54dc..88b61ac 100644
--- a/src/beast/app/beauti/GuessPatternDialog.java
+++ b/src/beast/app/beauti/GuessPatternDialog.java
@@ -540,14 +540,15 @@ public class GuessPatternDialog extends JDialog {
             try {
                 BufferedReader fin = new BufferedReader(new 
FileReader(txtFile.getText()));
                 StringBuffer buf = new StringBuffer();
-                // eat up header
-                fin.readLine();
+                // do not eat up header -- it might contain a useful entry, 
+                // but if not, it will not hurt
+                // fin.readLine();
                 // process data
                 while (fin.ready()) {
                     String str = fin.readLine();
                     str = str.replaceFirst("\t", "=") + ",";
                     // only add entries that are non-empty
-                    if (!str.matches("^\\s+=.*$")) {
+                    if (str.indexOf("=") > 0 && !str.matches("^\\s+=.*$")) {
                         buf.append(str);
                     }
                 }
@@ -556,6 +557,11 @@ public class GuessPatternDialog extends JDialog {
                 while (trait.endsWith(",")) {
                     trait = trait.substring(0, trait.length() - 1).trim();
                 }
+                
+               if (trait.trim().length() == 0) {
+                  JOptionPane.showMessageDialog(m_parent, "Could not find 
traint information in the file. " +
+                                  "Perhaps this is not a tab-delimited but 
space file?");
+               }
             } catch (Exception e) {
                 JOptionPane.showMessageDialog(m_parent, "Loading trait from 
file failed:" + e.getMessage());
                 return Status.canceled;
diff --git a/src/beast/app/beauti/JPackageDialog.java 
b/src/beast/app/beauti/JPackageDialog.java
index 61467c2..ebcae34 100644
--- a/src/beast/app/beauti/JPackageDialog.java
+++ b/src/beast/app/beauti/JPackageDialog.java
@@ -37,13 +37,13 @@ public class JPackageDialog extends JPanel {
     PackageTable dataTable = null;
 
     TreeMap<String, Package> packageMap = new TreeMap<>((s1,s2)->{
-       if (s1.equals(AddOnManager.BEAST_PACKAGE)) {
-               if (s2.equals(AddOnManager.BEAST_PACKAGE)) {
+       if (s1.equals(AddOnManager.BEAST_PACKAGE_NAME)) {
+               if (s2.equals(AddOnManager.BEAST_PACKAGE_NAME)) {
                        return 0;
                }
                return -1;
        }
-       if (s2.equals(AddOnManager.BEAST_PACKAGE)) {
+       if (s2.equals(AddOnManager.BEAST_PACKAGE_NAME)) {
                return 1;
        }
        return s1.compareToIgnoreCase(s2);
diff --git a/src/beast/app/beauti/TaxonSetInputEditor.java 
b/src/beast/app/beauti/TaxonSetInputEditor.java
index baf4dbe..4eda6c9 100644
--- a/src/beast/app/beauti/TaxonSetInputEditor.java
+++ b/src/beast/app/beauti/TaxonSetInputEditor.java
@@ -316,8 +316,7 @@ public class TaxonSetInputEditor extends InputEditor.Base {
         for (Alignment alignment : getDoc().alignments) {
                for (String id : alignment.getTaxaNames()) {
                 if (!taxonIDs.contains(id)) {
-                       Taxon taxon = new Taxon();
-                       taxon.setID(id);
+                       Taxon taxon = getDoc().getTaxon(id);
                        taxa.add(taxon);
                        taxonIDs.add(id);
                        }
@@ -325,12 +324,11 @@ public class TaxonSetInputEditor extends InputEditor.Base 
{
             for (Sequence sequence : alignment.sequenceInput.get()) {
                 String id = sequence.taxonInput.get();
                 if (!taxonIDs.contains(id)) {
-                    Taxon taxon = new Taxon();
+                    Taxon taxon = getDoc().getTaxon(sequence.taxonInput.get());
                     // ensure sequence and taxon do not get same ID
                     if (sequence.getID().equals(sequence.taxonInput.get())) {
                         sequence.setID("_" + sequence.getID());
                     }
-                    taxon.setID(sequence.taxonInput.get());
                     taxa.add(taxon);
                     taxonIDs.add(id);
                 }
@@ -347,8 +345,7 @@ public class TaxonSetInputEditor extends InputEditor.Base {
                             TaxonSet set = map.get(match);
                             set.taxonsetInput.setValue(taxon, set);
                         } else {
-                            TaxonSet set = new TaxonSet();
-                            set.setID(match);
+                               TaxonSet set = newTaxonSet(match);
                             set.taxonsetInput.setValue(taxon, set);
                             map.put(match, set);
                         }
@@ -370,7 +367,23 @@ public class TaxonSetInputEditor extends InputEditor.Base {
         return ignored;
     }
 
-    void parseTrait(String trait) {
+    private TaxonSet newTaxonSet(String match) {
+       if (getDoc().taxaset.containsKey(match)) {
+               Taxon t = doc.taxaset.get(match);
+               if (t instanceof TaxonSet) {
+                       TaxonSet set = (TaxonSet) t;
+                       set.taxonsetInput.get().clear();
+                       return set;
+               } else {
+                       // TODO handle situation where taxon and set have same 
name (issue #135)
+               }
+       }
+        TaxonSet set = new TaxonSet();
+        set.setID(match);
+               return set;
+       }
+
+       void parseTrait(String trait) {
        Map<String,String> traitmap = new HashMap<>();
        for (String line : trait.split(",")) {
                String [] strs = line.split("=");
@@ -390,12 +403,11 @@ public class TaxonSetInputEditor extends InputEditor.Base 
{
             for (Sequence sequence : alignment.sequenceInput.get()) {
                 String id = sequence.taxonInput.get();
                 if (!taxonIDs.contains(id)) {
-                    Taxon taxon = new Taxon();
+                    Taxon taxon = getDoc().getTaxon(sequence.taxonInput.get());
                     // ensure sequence and taxon do not get same ID
                     if (sequence.getID().equals(sequence.taxonInput.get())) {
                         sequence.setID("_" + sequence.getID());
                     }
-                    taxon.setID(sequence.taxonInput.get());
                     taxa.add(taxon);
                     taxonIDs.add(id);
                 }
@@ -412,8 +424,7 @@ public class TaxonSetInputEditor extends InputEditor.Base {
                             TaxonSet set = map.get(match);
                             set.taxonsetInput.setValue(taxon, set);
                         } else {
-                            TaxonSet set = new TaxonSet();
-                            set.setID(match);
+                            TaxonSet set = newTaxonSet(match);
                             set.taxonsetInput.setValue(taxon, set);
                             map.put(match, set);
                         }
@@ -530,8 +541,7 @@ public class TaxonSetInputEditor extends InputEditor.Base {
             // new taxon set?
             if (!m_taxonMap.containsValue(taxonSetID)) {
                 // create new taxon set
-                TaxonSet taxonset = new TaxonSet();
-                taxonset.setID(taxonSetID);
+                TaxonSet taxonset = newTaxonSet(taxonSetID);
                 m_taxonset.add(taxonset);
             }
             m_taxonMap.put(lineageID, taxonSetID);
diff --git a/src/beast/app/beauti/TipDatesInputEditor.java 
b/src/beast/app/beauti/TipDatesInputEditor.java
index 6e611ee..bd656f7 100644
--- a/src/beast/app/beauti/TipDatesInputEditor.java
+++ b/src/beast/app/beauti/TipDatesInputEditor.java
@@ -141,7 +141,7 @@ public class TipDatesInputEditor extends 
BEASTObjectInputEditor {
         samplingBox.add(comboBox);
 
         taxonsets = new ArrayList<>();
-        Taxon allTaxa = new Taxon();
+        Taxon allTaxa = getDoc().getTaxon(ALL_TAXA);
         allTaxa.setID(ALL_TAXA);
         taxonsets.add(allTaxa);
         List<String> taxonSetIDs = new ArrayList<>();
diff --git a/src/beast/app/draw/InputEditorFactory.java 
b/src/beast/app/draw/InputEditorFactory.java
index 711ea6c..10ff44d 100644
--- a/src/beast/app/draw/InputEditorFactory.java
+++ b/src/beast/app/draw/InputEditorFactory.java
@@ -152,7 +152,7 @@ public class InputEditorFactory {
         } else {
                if (input.get() != null && 
!input.get().getClass().equals(inputClass)
                                && !(input.get() instanceof ArrayList)) {
-                       Log.err.println(input.get().getClass() + " != " + 
inputClass);
+                       Log.trace.println(input.get().getClass() + " != " + 
inputClass);
                        inputClass = input.get().getClass();
                }
         }
diff --git a/src/beast/app/draw/ListInputEditor.java 
b/src/beast/app/draw/ListInputEditor.java
index 0e1b93a..803c550 100644
--- a/src/beast/app/draw/ListInputEditor.java
+++ b/src/beast/app/draw/ListInputEditor.java
@@ -462,7 +462,10 @@ public class ListInputEditor extends InputEditor.Base {
                 BEASTInterface beastObject = (BEASTInterface) ((List<?>) 
m_input.get()).get(i);
                 beastObject.validateInputs();
                 m_validateLabels.get(i).setVisible(false);
-            } catch (IllegalArgumentException e) {
+            } catch (IndexOutOfBoundsException e) {
+               // happens when m_validateLabels is not large enough, so there 
is nothing to show 
+            } catch (Exception e) {
+               // something went wrong, so show label if available
                 if (m_validateLabels.size() > i) {
                     m_validateLabels.get(i).setToolTipText(e.getMessage());
                     m_validateLabels.get(i).setVisible(true);
diff --git a/src/beast/app/treeannotator/KernelDensityEstimator2D.java 
b/src/beast/app/treeannotator/KernelDensityEstimator2D.java
index 76a680c..dccb14f 100644
--- a/src/beast/app/treeannotator/KernelDensityEstimator2D.java
+++ b/src/beast/app/treeannotator/KernelDensityEstimator2D.java
@@ -257,7 +257,7 @@ public class KernelDensityEstimator2D implements 
ContourMaker {
 
         KernelDensityEstimator2D kde = new KernelDensityEstimator2D(x, y, 4);
 
-        System.out.println(kde.getXGrid());
+        System.out.println(Arrays.toString(kde.getXGrid()));
 //        System.out.println(new Vector(kde.getYGrid()));
 //        System.out.println(new Matrix(kde.getKDE()));
         System.exit(-1);
diff --git a/src/beast/app/treeannotator/RealNumberField.java 
b/src/beast/app/treeannotator/RealNumberField.java
index 72c65c9..506767c 100644
--- a/src/beast/app/treeannotator/RealNumberField.java
+++ b/src/beast/app/treeannotator/RealNumberField.java
@@ -128,7 +128,7 @@ public class RealNumberField extends JTextField implements 
FocusListener, Docume
         if (value == null && allowEmpty) {
             setText("");
         }
-        if (value == Double.NaN) {
+        if (Double.isNaN(value)) {
             setText(NaN);
         } else if (value == Double.POSITIVE_INFINITY) {
             setText(POSITIVE_INFINITY);
diff --git a/src/beast/app/util/Utils.java b/src/beast/app/util/Utils.java
index e63b6ee..16e571d 100644
--- a/src/beast/app/util/Utils.java
+++ b/src/beast/app/util/Utils.java
@@ -3,6 +3,7 @@ package beast.app.util;
 import java.awt.Component;
 import java.awt.Font;
 import java.awt.Graphics;
+import java.awt.GraphicsEnvironment;
 import java.awt.Image;
 import java.awt.Toolkit;
 import java.io.BufferedReader;
@@ -18,6 +19,7 @@ import java.util.Set;
 
 import javax.swing.ImageIcon;
 import javax.swing.JFileChooser;
+import javax.swing.JOptionPane;
 import javax.swing.LookAndFeel;
 import javax.swing.UIManager;
 import javax.swing.UnsupportedLookAndFeelException;
@@ -26,6 +28,13 @@ import javax.swing.filechooser.FileNameExtensionFilter;
 import beast.app.beauti.BeautiPanel;
 import beast.app.beauti.BeautiPanelConfig;
 import beast.core.util.Log;
+import beast.evolution.alignment.Alignment;
+import beast.evolution.alignment.Sequence;
+import beast.evolution.likelihood.BeagleTreeLikelihood;
+import beast.evolution.sitemodel.SiteModel;
+import beast.evolution.substitutionmodel.JukesCantor;
+import beast.util.AddOnManager;
+import beast.util.TreeParser;
 
 /**
  * @author Andrew Rambaut
@@ -320,4 +329,102 @@ public class Utils {
            }
        
        }
+
+       
+       public static boolean testCudaStatusOnMac() {
+               String cudaStatusOnMac = "<html>It appears you have CUDA 
installed, but your computer hardware does not support it.<br>"
+                               + "You need to remove CUDA before BEAST/BEAUti 
can start.<br>"
+                               + "To remove CUDA, delete the following folders 
by typing in a terminal:<br>"
+                               + "rm -r /Library/Frameworks/CUDA.framework<br>"
+                               + "rm -r /Developer/NVIDIA<br>"
+                               + "rm -r /usr/local/cuda<br>"
+                               + "You may need 'sudo rm' instead of 
'rm'</html>";
+                               
+               if (isMac()) {
+                       // check any of these directories exist
+                       // /Library/Frameworks/CUDA.framework
+                       // /Developer/NVIDIA
+                       // /usr/local/cuda
+                       if (new 
File("/Library/Frameworks/CUDA.framework").exists() ||
+                                       new File("/Developer/NVIDIA").exists() 
||
+                                       new File("/usr/local/cuda").exists()) {
+                               // there is evidence of CUDA being installed on 
this computer
+                               // try to create a BeagleTreeLikelihood using a 
separate process
+                               try {
+                                     String java = System.getenv("java.home");
+                                     if (java == null) {
+                                         java ="/usr/bin/java";
+                                     } else {
+                                         java += "/bin/java";
+                                     }
+                                     String beastJar = 
AddOnManager.getPackageUserDir();
+                                     beastJar += "/" + "BEAST" + "/" + "lib" + 
"/" + "beast.jar";
+                                     if (!new File(beastJar).exists()) {
+                                         Log.debug.println("Could not find 
beast.jar, giving up testCudaStatusOnMac");
+                                         return true;
+                                     }
+                                     //beastJar = "\"" + beastJar + "\"";
+                                     //beastJar = 
"/Users/remco/workspace/beast2/build/dist/beast.jar";
+                                     Process p = Runtime.getRuntime().exec(new 
String[]{java , "-cp" , beastJar , "beast.app.util.Utils"});
+                                     BufferedReader input = new 
BufferedReader(new InputStreamReader(p.getInputStream()));
+                                     String line;
+                                     while ((line = input.readLine()) != null) 
{
+                                       Log.debug.println(line);
+                                     }
+                                     input.close();
+                                     if (p.exitValue() != 0) {
+                                         if (GraphicsEnvironment.isHeadless()) 
{
+                                                 cudaStatusOnMac = 
cudaStatusOnMac.replaceAll("<br>", "\n");
+                                                 cudaStatusOnMac = 
cudaStatusOnMac.replaceAll("<.?html>","\n");
+                                                 Log.warning.println("WARNING: 
" + cudaStatusOnMac);
+                                         } else {
+                                                 
JOptionPane.showMessageDialog(null, cudaStatusOnMac);
+                                         }
+                                         return false;
+                                     }
+                                   }
+                                   catch (Exception err) {
+                                     err.printStackTrace();
+                                   }
+                       }
+                       
+               }
+               return true;
+       }
+       
+       
+    public static void main(String[] args) {
+               try {
+                       Sequence a = new Sequence("A", "A");
+               Sequence b = new Sequence("B", "A");
+               Sequence c = new Sequence("C", "A");
+               Sequence d = new Sequence("D", "A");
+
+               Alignment data = new Alignment();
+               data.initByName("sequence", a, "sequence", b, "sequence", c, 
"sequence", d, "dataType", "nucleotide");
+
+               TreeParser tree = new TreeParser();
+               tree.initByName("taxa", data,
+                       "newick", "(((A:1,B:1):1,C:2):1,D:3)",
+                       "IsLabelledNewick", true);
+
+               JukesCantor JC = new JukesCantor();
+               JC.initAndValidate();
+
+               SiteModel siteModel = new SiteModel();
+               siteModel.initByName("mutationRate", "1.0", 
"gammaCategoryCount", 1, "substModel", JC);
+
+               BeagleTreeLikelihood likelihood = new BeagleTreeLikelihood();
+               likelihood.initByName("data", data, "tree", tree, "siteModel", 
siteModel);
+               } catch (Exception e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+
+       
+       System.out.println("Success");
+       // if we got this far, exit with status 0
+               System.exit(0);
+       }
+
 }
diff --git a/src/beast/app/util/Utils6.java b/src/beast/app/util/Utils6.java
index 8cf4ba5..0f67209 100644
--- a/src/beast/app/util/Utils6.java
+++ b/src/beast/app/util/Utils6.java
@@ -98,4 +98,16 @@ public class Utils6 {
                return null;
            }
        }
+
+    public static boolean isMac() {
+        return System.getProperty("os.name").toLowerCase().startsWith("mac");
+    }
+
+    public static boolean isWindows() {
+        return 
System.getProperty("os.name").toLowerCase().startsWith("windows");
+    }
+
+    public static boolean isLinux() {
+        return System.getProperty("os.name").toLowerCase().startsWith("linux");
+    }
 }
diff --git a/src/beast/core/Input.java b/src/beast/core/Input.java
index 44b4715..bde8d06 100644
--- a/src/beast/core/Input.java
+++ b/src/beast/core/Input.java
@@ -748,5 +748,9 @@ public class Input<T> {
                 break;
         }
     } // validate
+    
+    public String toString() {
+       return String.format("Input(\"%s\")", name);
+    }
 
 } // class Input
diff --git a/src/beast/core/Logger.java b/src/beast/core/Logger.java
index c652f67..7f04e48 100644
--- a/src/beast/core/Logger.java
+++ b/src/beast/core/Logger.java
@@ -38,6 +38,7 @@ import java.io.UnsupportedEncodingException;
 import java.nio.file.Files;
 import java.nio.file.StandardCopyOption;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 
@@ -66,8 +67,8 @@ public class Logger extends BEASTObject {
     final public Input<BEASTObject> modelInput = new Input<>("model", "Model 
to log at the top of the log. " +
             "If specified, XML will be produced for the model, commented out 
by # at the start of a line. " +
             "Alignments are suppressed. This way, the log file documents 
itself. ");
-    final public Input<LOGMODE> modeInput = new Input<>("mode", "logging mode, 
one of " + LOGMODE.values(), LOGMODE.autodetect, LOGMODE.values());
-    final public Input<SORTMODE> sortModeInput = new Input<>("sort", "sort 
items to be logged, one of " + SORTMODE.values(), SORTMODE.none, 
SORTMODE.values());
+    final public Input<LOGMODE> modeInput = new Input<>("mode", "logging mode, 
one of " + Arrays.toString(LOGMODE.values()), LOGMODE.autodetect, 
LOGMODE.values());
+    final public Input<SORTMODE> sortModeInput = new Input<>("sort", "sort 
items to be logged, one of " + Arrays.toString(SORTMODE.values()), 
SORTMODE.none, SORTMODE.values());
     final public Input<Boolean> sanitiseHeadersInput = new 
Input<>("sanitiseHeaders", "whether to remove any clutter introduced by Beauti" 
, false);
 
     final public Input<List<BEASTObject>> loggersInput = new Input<>("log",
@@ -141,7 +142,7 @@ public class Logger extends BEASTObject {
         } else if (mode.equals(LOGMODE.compound)) {
                this.mode = LOGMODE.compound;
         } else {
-            throw new IllegalArgumentException("Mode '" + mode + "' is not 
supported. Choose one of " + LOGMODE.values());
+            throw new IllegalArgumentException("Mode '" + mode + "' is not 
supported. Choose one of " + Arrays.toString(LOGMODE.values()));
         }
 
         if (everyInput.get() != null) {
diff --git a/src/beast/core/OperatorSchedule.java 
b/src/beast/core/OperatorSchedule.java
index a2e191c..20ff8ee 100644
--- a/src/beast/core/OperatorSchedule.java
+++ b/src/beast/core/OperatorSchedule.java
@@ -154,8 +154,6 @@ public class OperatorSchedule extends BEASTObject {
         formatter.format(headerFormat, PR_ACCEPT);
         out.println(": The acceptance probability (" + NUM_ACCEPT + " as a 
fraction of the total proposals for this operator).");
         out.println();
-        
-        formatter.close();
     }
 
     protected static String prettyPrintOperator(
diff --git a/src/beast/evolution/likelihood/BeagleTreeLikelihood.java 
b/src/beast/evolution/likelihood/BeagleTreeLikelihood.java
index 8fd9a67..abd4fc6 100644
--- a/src/beast/evolution/likelihood/BeagleTreeLikelihood.java
+++ b/src/beast/evolution/likelihood/BeagleTreeLikelihood.java
@@ -34,6 +34,7 @@ import beagle.BeagleFlag;
 import beagle.BeagleInfo;
 import beagle.InstanceDetails;
 import beagle.ResourceDetails;
+import beast.core.CalculationNode;
 import beast.core.Description;
 import beast.core.util.Log;
 import beast.evolution.alignment.Alignment;
@@ -82,6 +83,9 @@ public class BeagleTreeLikelihood extends TreeLikelihood {
     int m_nStateCount;
     int m_nNodeCount;
     
+    private double [] currentCategoryRates;
+    private double [] storedCurrentCategoryRates;
+    
     private int invariantCategory = -1;
 
     @Override
@@ -139,6 +143,16 @@ public class BeagleTreeLikelihood extends TreeLikelihood {
                                break;
                        }
                }
+               if (constantPattern.size() > dataInput.get().getPatternCount()) 
{
+                       // if there are many more constant patterns than 
patterns (each pattern can
+                       // have a number of constant patters, one for each 
state) it is less efficient
+                       // to just calculate the TreeLikelihood for constant 
sites than optimising
+                       Log.debug("switch off constant sites optimisiation: 
calculating through separate TreeLikelihood category (as in the olden days)");
+                       invariantCategory = -1;
+                       proportionInvariant = 0;
+                       constantPattern = null;
+                       categoryRates = m_siteModel.getCategoryRates(null);
+               }
         }        
 
         this.categoryCount = m_siteModel.getCategoryCount() - 
(invariantCategory >= 0 ? 1 : 0);
@@ -349,7 +363,9 @@ public class BeagleTreeLikelihood extends TreeLikelihood {
         // set up sitemodel
         
         beagle.setCategoryRates(categoryRates);
-
+        currentCategoryRates = categoryRates;
+        storedCurrentCategoryRates = categoryRates.clone();
+        
         return true;
     }
 
@@ -499,10 +515,30 @@ public class BeagleTreeLikelihood extends TreeLikelihood {
     @Override
     protected boolean requiresRecalculation() {
         hasDirt = Tree.IS_CLEAN;
+        
+        double[] categoryRates = m_siteModel.getCategoryRates(null);
+        if (constantPattern != null) {
+            double [] tmp = new double [categoryRates.length - 1];
+            for (int k = 0; k < invariantCategory; k++) {
+               tmp[k] = categoryRates[k];
+            }
+            for (int k = invariantCategory + 1; k < categoryRates.length; k++) 
{
+               tmp[k-1] = categoryRates[k];
+            }
+            categoryRates = tmp;
+        }
+        for (int i = 0; i < categoryRates.length; i++) {
+               if (categoryRates[i] != currentCategoryRates[i]) {
+                       updateSiteModel = true;
+                       break;
+               }
+        }
+        //updateSiteModel |= m_siteModel.isDirtyCalculation();
 
-        updateSiteModel |= m_siteModel.isDirtyCalculation();
-        updateSubstitutionModel |= substitutionModel.isDirtyCalculation();
-
+        if (substitutionModel instanceof CalculationNode) {
+               updateSubstitutionModel |= ((CalculationNode) 
substitutionModel).isDirtyCalculation();
+        }
+        
         if (dataInput.get().isDirtyCalculation()) {
             hasDirt = Tree.IS_FILTHY;
             return true;
@@ -535,12 +571,21 @@ public class BeagleTreeLikelihood extends TreeLikelihood {
         }
         super.store();
         System.arraycopy(m_branchLengths, 0, storedBranchLengths, 0, 
m_branchLengths.length);
+        System.arraycopy(currentCategoryRates, 0, storedCurrentCategoryRates, 
0, currentCategoryRates.length);
     }
 
     @Override
     public void restore() {
-        updateSiteModel = true; // this is required to upload the 
categoryRates to BEAGLE after the restore
-
+        for (int i = 0; i < currentCategoryRates.length; i++) {
+               if (currentCategoryRates[i] != storedCurrentCategoryRates[i]) {
+                       updateSiteModel = true; // this is required to upload 
the categoryRates to BEAGLE after the restore
+                       break;
+               }
+        }
+        double [] tmp = storedCurrentCategoryRates;
+        storedCurrentCategoryRates = currentCategoryRates;
+        currentCategoryRates = tmp;
+        
         partialBufferHelper.restoreState();
         eigenBufferHelper.restoreState();
         matrixBufferHelper.restoreState();
@@ -642,6 +687,7 @@ public class BeagleTreeLikelihood extends TreeLikelihood {
                    categoryRates = tmp;
                }
             beagle.setCategoryRates(categoryRates);
+            currentCategoryRates = categoryRates;
         }
 
         for (int i = 0; i < eigenCount; i++) {
@@ -724,11 +770,18 @@ public class BeagleTreeLikelihood extends TreeLikelihood {
                 beagle.getSiteLogLikelihoods(patternLogLikelihoods);
                 int [] patternWeights = dataInput.get().getWeights();
                 proportionInvariant = m_siteModel.getProportionInvariant();
-                for (int k : constantPattern) {
-                       int i = k / m_nStateCount;
-                       int j = k % m_nStateCount;
-                       logL += patternWeights[i] * 
(Math.log(Math.exp(patternLogLikelihoods[i]) + proportionInvariant * 
frequencies[j]) - patternLogLikelihoods[i]);
-                }
+                
+                
+               for (int k : constantPattern) {
+                       int i = k / m_nStateCount;
+                       int j = k % m_nStateCount;
+                       patternLogLikelihoods[i] = 
(Math.log(Math.exp(patternLogLikelihoods[i]) + proportionInvariant * 
frequencies[j]));
+               }
+               
+                   logL = 0.0;
+                   for (int i = 0; i < patternCount; i++) {
+                       logL += patternLogLikelihoods[i] * patternWeights[i];
+                   }
             }
 
             if (Double.isNaN(logL) || Double.isInfinite(logL)) {
@@ -971,11 +1024,6 @@ public class BeagleTreeLikelihood extends TreeLikelihood {
 
     
     /**
-     * the pattern likelihoods
-     */
-    protected double[] patternLogLikelihoods = null;
-
-    /**
      * the number of rate categories
      */
     protected int categoryCount;
diff --git a/src/beast/evolution/likelihood/ThreadedTreeLikelihood.java 
b/src/beast/evolution/likelihood/ThreadedTreeLikelihood.java
index f584f82..f485262 100644
--- a/src/beast/evolution/likelihood/ThreadedTreeLikelihood.java
+++ b/src/beast/evolution/likelihood/ThreadedTreeLikelihood.java
@@ -73,7 +73,7 @@ public class ThreadedTreeLikelihood extends 
GenericTreeLikelihood {
     final public Input<Scaling> scalingInput = new Input<>("scaling", "type of 
scaling to use, one of " + Arrays.toString(Scaling.values()) + ". If not 
specified, the -beagle_scaling flag is used.", Scaling._default, 
Scaling.values());
     
     /** private list of likelihoods, to notify framework of TreeLikelihoods 
being created in initAndValidate() **/
-    final private Input<List<TreeLikelihood>> likelihoodsInput = new 
Input<>("xxx","",new ArrayList<>());
+    final private Input<List<TreeLikelihood>> likelihoodsInput = new 
Input<>("*","",new ArrayList<>());
     
     @Override
     public List<Input<?>> listInputs() {
@@ -283,7 +283,7 @@ public class ThreadedTreeLikelihood extends 
GenericTreeLikelihood {
                        try {
                    logPByThread[threadNr] = likelihood.calculateLogP();
                        } catch (Exception e) {
-                               System.err.println("Something went wrong ith 
thread " + threadNr);
+                               System.err.println("Something went wrong in 
thread " + threadNr);
                                e.printStackTrace();
                                System.exit(0);
                        }
diff --git a/src/beast/evolution/likelihood/TreeLikelihood.java 
b/src/beast/evolution/likelihood/TreeLikelihood.java
index c30afbc..fafb5fe 100644
--- a/src/beast/evolution/likelihood/TreeLikelihood.java
+++ b/src/beast/evolution/likelihood/TreeLikelihood.java
@@ -68,7 +68,7 @@ public class TreeLikelihood extends GenericTreeLikelihood {
      * BEASTObject associated with inputs. Since none of the inputs are 
StateNodes, it
      * is safe to link to them only once, during initAndValidate.
      */
-    SubstitutionModel.Base substitutionModel;
+    SubstitutionModel substitutionModel;
     protected SiteModel.Base m_siteModel;
     protected BranchRateModel.Base branchRateModel;
 
diff --git a/src/beast/evolution/operators/DeltaExchangeOperator.java 
b/src/beast/evolution/operators/DeltaExchangeOperator.java
index df55d25..add9f7a 100644
--- a/src/beast/evolution/operators/DeltaExchangeOperator.java
+++ b/src/beast/evolution/operators/DeltaExchangeOperator.java
@@ -137,6 +137,47 @@ public class DeltaExchangeOperator extends Operator {
     @Override
     public final double proposal() {
        int[] parameterWeights = weights();
+       final int dim = parameterWeights.length;
+       
+       // Find the number of weights that are nonzero
+       int nonZeroWeights = 0;
+       for (int i: parameterWeights) {
+               if (i != 0) {
+                       ++nonZeroWeights;
+               }
+       }
+       
+        if (nonZeroWeights <= 1) {
+               // it is impossible to select two distinct entries in this 
case, so there is nothing to propose 
+               return 0.0;
+        }
+       
+        // Generate indices for the values to be modified
+        int dim1 = Randomizer.nextInt(nonZeroWeights);
+        int dim2 = Randomizer.nextInt(nonZeroWeights-1);
+        if (dim2 >= dim1) {
+               ++dim2;
+        }
+        if (nonZeroWeights<dim) {
+               // There are zero weights, so we need to increase dim1 and dim2 
accordingly.
+               int nonZerosBeforeDim1 = dim1;
+               int nonZerosBeforeDim2 = dim2;
+               dim1 = 0;
+               dim2 = 0;
+               while (nonZerosBeforeDim1 > 0 | parameterWeights[dim1] == 0 ) {
+                       if (parameterWeights[dim1] != 0) {
+                               --nonZerosBeforeDim1;
+                       }
+                       ++dim1;
+               }
+               while (nonZerosBeforeDim2 > 0 | parameterWeights[dim2] == 0 ) {
+                       if (parameterWeights[dim2] != 0) {
+                               --nonZerosBeforeDim2;
+                       }
+                       ++dim2;
+               }
+        }
+
         double logq = 0.0;
 
         if (compoundParameter == null) { // one parameter case
@@ -150,18 +191,6 @@ public class DeltaExchangeOperator extends Operator {
                 realparameter = parameterInput.get().get(0);
             }
 
-            final int dim = (realparameter != null ? 
realparameter.getDimension() : intparameter.getDimension());
-            if (dim <= 1) {
-               // it is impossible to select two distinct entries in this 
case, so there is nothing to propose 
-               return 0.0;
-            }
-
-            final int dim1 = Randomizer.nextInt(dim);
-            int dim2 = dim1;
-            while (dim1 == dim2) {
-                dim2 = Randomizer.nextInt(dim);
-            }
-
             if (intparameter == null) {
                 // operate on real parameter
                 double scalar1 = realparameter.getValue(dim1);
@@ -217,19 +246,6 @@ public class DeltaExchangeOperator extends Operator {
 
         } else { // compound parameter case
 
-            // get two dimensions
-            final int dim = compoundParameter.getDimension();
-            if (dim <= 1) {
-               // it is impossible to select two distinct entries in this 
case, so there is nothing to propose 
-               return 0.0;
-            }
-
-            final int dim1 = Randomizer.nextInt(dim);
-            int dim2 = dim1;
-            while (dim1 == dim2) {
-                dim2 = Randomizer.nextInt(dim);
-            }
-
             if (intparameterInput.get().isEmpty()) {
                 // operate on real parameter
                 double scalar1 = (Double) compoundParameter.getValue(dim1);
@@ -315,9 +331,9 @@ public class DeltaExchangeOperator extends Operator {
     public void optimize(final double logAlpha) {
         // must be overridden by operator implementation to have an effect
         if (autoOptimize) {
-            double delta = calcDelta(logAlpha);
-            delta += Math.log(delta);
-            delta = Math.exp(delta);
+            double _delta = calcDelta(logAlpha);
+            _delta += Math.log(delta);
+            delta = Math.exp(_delta);
             if (isIntegerOperator) {
                // when delta < 0.5
                // Randomizer.nextInt((int) Math.round(delta)) becomes
diff --git a/src/beast/evolution/operators/SubtreeSlide.java 
b/src/beast/evolution/operators/SubtreeSlide.java
index 2bb72bc..61e84ce 100644
--- a/src/beast/evolution/operators/SubtreeSlide.java
+++ b/src/beast/evolution/operators/SubtreeSlide.java
@@ -250,7 +250,7 @@ public class SubtreeSlide extends TreeOperator {
      */
     @Override
     public void optimize(final double logAlpha) {
-        if (optimiseInput.get() && ! Double.isInfinite(logAlpha) ) {
+        if (optimiseInput.get()) {
             double delta = calcDelta(logAlpha);
             delta += Math.log(size);
             final double f = Math.exp(delta);
diff --git a/src/beast/evolution/sitemodel/SiteModelInterface.java 
b/src/beast/evolution/sitemodel/SiteModelInterface.java
index a7877c6..16a83b7 100644
--- a/src/beast/evolution/sitemodel/SiteModelInterface.java
+++ b/src/beast/evolution/sitemodel/SiteModelInterface.java
@@ -35,7 +35,7 @@ public interface SiteModelInterface {
 
     @Description(value = "Base implementation of a site model with 
substitution model and rate categories.", isInheritable = false)
     public abstract class Base extends CalculationNode implements 
SiteModelInterface {
-       final public Input<SubstitutionModel.Base> substModelInput =
+       final public Input<SubstitutionModel> substModelInput =
                 new Input<>("substModel", "substitution model along branches 
in the beast.tree", null, Validate.REQUIRED);
 
        /**
diff --git a/src/beast/evolution/substitutionmodel/DefaultEigenSystem.java 
b/src/beast/evolution/substitutionmodel/DefaultEigenSystem.java
index 142405f..f733ba3 100644
--- a/src/beast/evolution/substitutionmodel/DefaultEigenSystem.java
+++ b/src/beast/evolution/substitutionmodel/DefaultEigenSystem.java
@@ -2,6 +2,7 @@ package beast.evolution.substitutionmodel;
 
 import beast.core.util.Log;
 import beast.math.MachineAccuracy;
+import java.util.Arrays;
 
 /**
  * A default Eigen decomposition system
@@ -178,7 +179,10 @@ public class DefaultEigenSystem implements EigenSystem {
                 }
                 if (itn == 0) {
                     /* eigenvalues have not converged */
-                    Log.warning.println("Eigenvalues not converged");
+                    Log.warning.println("Eigenvalues not converged for 
Q-matrix");
+                    for (i = 0; i < n; i++) {
+                       Log.warning.println(Arrays.toString(h[i]));
+                    }
                     throw new ArithmeticException();
                 }
                 y = h[na - 1][na - 1];
diff --git a/src/beast/evolution/substitutionmodel/Frequencies.java 
b/src/beast/evolution/substitutionmodel/Frequencies.java
index 4f06b46..d49221d 100644
--- a/src/beast/evolution/substitutionmodel/Frequencies.java
+++ b/src/beast/evolution/substitutionmodel/Frequencies.java
@@ -73,10 +73,11 @@ public class Frequencies extends CalculationNode {
      * return up to date frequencies *
      */
     public double[] getFreqs() {
-        if (needsUpdate) {
-
-            update();
-        }
+       synchronized (this) {
+            if (needsUpdate) {
+                update();
+            }                  
+               }
 
         return freqs;
     }
diff --git a/src/beast/evolution/tree/RandomTree.java 
b/src/beast/evolution/tree/RandomTree.java
index c5158c1..351f82d 100644
--- a/src/beast/evolution/tree/RandomTree.java
+++ b/src/beast/evolution/tree/RandomTree.java
@@ -420,7 +420,7 @@ public class RandomTree extends Tree implements 
StateNodeInitialiser {
                 final Set<Node> candidates = new HashSet<>();
                 int i = 0;
                 for (String taxon : taxa) {
-                    final Node node = new Node();
+                    final Node node = newNode();
                     node.setNr(i);
                     node.setID(taxon);
                     node.setHeight(0.0);
@@ -560,7 +560,7 @@ public class RandomTree extends Tree implements 
StateNodeInitialiser {
                 int k = nodeList.size() - 1;
                 final Node left = nodeList.remove(k);
                 final Node right = nodeList.get(k-1);
-                final Node newNode = new Node();
+                final Node newNode = newNode();
                 newNode.setNr(nextNodeNr++);   // multiple tries may generate 
an excess of nodes assert(nextNodeNr <= nrOfTaxa*2-1);
                 newNode.setHeight(h + dt);
                 newNode.setLeft(left);
@@ -691,7 +691,7 @@ public class RandomTree extends Tree implements 
StateNodeInitialiser {
         final Node left = nodeList.get(node1);
         final Node right = nodeList.get(node2);
 
-        final Node newNode = new Node();
+        final Node newNode = newNode();
 //             System.err.println(2 * m_taxa.get().getNrTaxa() - 
nodeList.size());
         newNode.setNr(nextNodeNr++);   // multiple tries may generate an 
excess of nodes assert(nextNodeNr <= nrOfTaxa*2-1);
         newNode.setHeight(height);
diff --git a/src/beast/util/AddOnManager.java b/src/beast/util/AddOnManager.java
index 3132022..9f1ab5e 100644
--- a/src/beast/util/AddOnManager.java
+++ b/src/beast/util/AddOnManager.java
@@ -82,10 +82,10 @@ public class AddOnManager {
     public final static String[] IMPLEMENTATION_DIR = {"beast", "snap"};
     public final static String TO_DELETE_LIST_FILE = "toDeleteList";
     public final static String TO_INSTALL_LIST_FILE = "toInstallList";
-    public final static String BEAST_PACKAGE = "BEAST";
+    public final static String BEAST_PACKAGE_NAME = "BEAST";
 
-//    public final static String PACKAGES_XML = 
"https://raw.githubusercontent.com/CompEvol/CBAN/master/packages.xml";;
-    public final static String PACKAGES_XML = 
"file:///Users/remco/workspace/beast2/packages.xml";
+    public final static String PACKAGES_XML = 
"https://raw.githubusercontent.com/CompEvol/CBAN/master/packages.xml";;
+//    public final static String PACKAGES_XML = 
"file:///Users/remco/workspace/beast2/packages.xml";
 
     public static final String INSTALLED = "installed";
     public static final String NOT_INSTALLED = "not installed";
@@ -282,19 +282,23 @@ public class AddOnManager {
             }
         }
 
-        // Manually set currently-installed BEAST 2 version (won't have to do 
this soon!)
-
-//        Package beastPkg;
-//        if (packageMap.containsKey(BEAST_PACKAGE))
-//            beastPkg = packageMap.get(BEAST_PACKAGE);
-//        else {
-//            beastPkg = new Package(BEAST_PACKAGE);
-//            packageMap.put(BEAST_PACKAGE, beastPkg);
-//        }
-//
-//        PackageVersion beastPkgVersion = new 
PackageVersion(beastVersion.getVersion());
-//        Set<PackageDependency> beastPkgDeps = new TreeSet<>();
-//        beastPkg.setInstalled(beastPkgVersion, beastPkgDeps);
+        // Manually set currently-installed BEAST 2 version if not already set
+        // This can happen when the BEAST package is not installed (perhaps 
due to 
+        // file access issues)
+        Package beastPkg;
+        if (packageMap.containsKey(BEAST_PACKAGE_NAME)) {
+            beastPkg = packageMap.get(BEAST_PACKAGE_NAME);
+        } else {
+            beastPkg = new Package(BEAST_PACKAGE_NAME);
+            packageMap.put(BEAST_PACKAGE_NAME, beastPkg);
+        }
+
+        if (!beastPkg.isInstalled()) {
+            PackageVersion beastPkgVersion = new 
PackageVersion(beastVersion.getVersion());
+            Set<PackageDependency> beastPkgDeps = new TreeSet<>();
+            beastPkg.setInstalled(beastPkgVersion, beastPkgDeps);
+        }
+
     }
 
     /**
@@ -437,6 +441,8 @@ public class AddOnManager {
      * @throws IOException if URL cannot be accessed for some reason
      */
     public static Map<String, String> installPackages(Map<Package, 
PackageVersion> packagesToInstall, boolean useAppDir, String customDir) throws 
IOException {
+       closeClassLoader();
+       
         Map<String, String> dirList = new HashMap<>();
 
         for (Map.Entry<Package, PackageVersion> entry : 
packagesToInstall.entrySet()) {
@@ -512,6 +518,7 @@ public class AddOnManager {
      * @throws IOException thrown if packages cannot be deleted and delete 
list file cannot be written
      */
     public static String uninstallPackage(Package pkg, boolean useAppDir, 
String customDir) throws IOException {
+       closeClassLoader();
 
         String dirName = (useAppDir ? getPackageSystemDir() : 
getPackageUserDir()) + "/" + pkg.getName();
         if (customDir != null) {
@@ -534,7 +541,32 @@ public class AddOnManager {
     }
 
 
-    private static void deleteRecursively(File file, List<File> deleteFailed) {
+    /**
+     * Close class loader so that locks on jar files are released, which may 
prevent
+     * files being replaced on Windows.
+     * 
http://docs.oracle.com/javase/7/docs/api/java/net/URLClassLoader.html#close%28%29
+     * 
+     * This allows smooth upgrading of BEAST versions using the package 
manager. Without 
+     * this, there is no way to upgrade BEAST since the AddOnManager is part 
of the 
+     * BEAST.jar file that is loaded and needs to be replaced.
+     * 
+     * Side effect is that after installing a package, opening a new BEAUti 
instance
+     * will fail (Windows only).
+     * 
+     */
+    private static void closeClassLoader() {
+       try {
+               if (Utils.isWindows()) {
+                       URLClassLoader sysLoader = (URLClassLoader) 
AddOnManager.class.getClassLoader();
+                       sysLoader.close();
+               }
+               } catch (IOException e) {
+                       Log.warning.println("Could not close ClassLoader: " + 
e.getMessage());
+               }
+               
+       }
+
+       private static void deleteRecursively(File file, List<File> 
deleteFailed) {
         if (file.isDirectory()) {
             File[] files = file.listFiles();
             for (File f : files) {
@@ -1294,10 +1326,10 @@ public class AddOnManager {
         // sort result
         result.addAll(names);
         Collections.sort(result, (s1, s2) -> {
-               if (s1.equals(BEAST_PACKAGE)) {
+               if (s1.equals(BEAST_PACKAGE_NAME)) {
                        return -1;
                }
-               if (s2.equals(BEAST_PACKAGE)) {
+               if (s2.equals(BEAST_PACKAGE_NAME)) {
                        return 1;
                }
                return s1.compareTo(s2);
@@ -1349,10 +1381,10 @@ public class AddOnManager {
 
         // sort result
         Collections.sort(result, (s1, s2) -> {
-               if (s1.equals(BEAST_PACKAGE)) {
+               if (s1.equals(BEAST_PACKAGE_NAME)) {
                        return -1;
                }
-               if (s2.equals(BEAST_PACKAGE)) {
+               if (s2.equals(BEAST_PACKAGE_NAME)) {
                        return 1;
                }
                return s1.compareTo(s2);
@@ -1433,7 +1465,7 @@ public class AddOnManager {
 
         // Print formatted package information
         for (Package pkg : packageList) {
-               if (pkg.getName().equals(BEAST_PACKAGE)) {
+               if (pkg.getName().equals(BEAST_PACKAGE_NAME)) {
                        ps.printf(nameFormat, pkg.getName()); ps.print(sep);
                        ps.printf(statusFormat, pkg.getStatusString()); 
ps.print(sep);
                        ps.printf(latestFormat, pkg.isAvailable() ? 
pkg.getLatestVersion() : "NA"); ps.print(sep);
@@ -1447,7 +1479,7 @@ public class AddOnManager {
         
         // Print formatted package information
         for (Package pkg : packageList) {
-               if (!pkg.getName().equals(BEAST_PACKAGE)) {
+               if (!pkg.getName().equals(BEAST_PACKAGE_NAME)) {
                    ps.printf(nameFormat, pkg.getName()); ps.print(sep);
                    ps.printf(statusFormat, pkg.getStatusString()); 
ps.print(sep);
                    ps.printf(latestFormat, pkg.isAvailable() ? 
pkg.getLatestVersion() : "NA"); ps.print(sep);
diff --git a/src/beast/util/ClusterTree.java b/src/beast/util/ClusterTree.java
index a02ac4c..72257c0 100644
--- a/src/beast/util/ClusterTree.java
+++ b/src/beast/util/ClusterTree.java
@@ -28,6 +28,7 @@ package beast.util;
 import java.text.DecimalFormat;
 import java.text.DecimalFormatSymbols;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Comparator;
 import java.util.List;
 import java.util.Locale;
@@ -70,7 +71,7 @@ public class ClusterTree extends Tree implements 
StateNodeInitialiser {
     double EPSILON = 1e-10;
 
     final public Input<Type> clusterTypeInput = new Input<>("clusterType", 
"type of clustering algorithm used for generating initial beast.tree. " +
-            "Should be one of " + Type.values() + " (default " + Type.average 
+ ")", Type.average, Type.values());
+            "Should be one of " + Arrays.toString(Type.values()) + " (default 
" + Type.average + ")", Type.average, Type.values());
     final public Input<Alignment> dataInput = new Input<>("taxa", "alignment 
data used for calculating distances for clustering");
 
     final public Input<Distance> distanceInput = new Input<>("distance", 
"method for calculating distance between two sequences (default Jukes Cantor)");
diff --git a/src/beast/util/JSONProducer.java b/src/beast/util/JSONProducer.java
index 22464f6..8309a6f 100644
--- a/src/beast/util/JSONProducer.java
+++ b/src/beast/util/JSONProducer.java
@@ -20,7 +20,10 @@ import beast.app.BEASTVersion;
 import beast.core.BEASTInterface;
 import beast.core.Input;
 import beast.core.State;
+import beast.core.parameter.BooleanParameter;
+import beast.core.parameter.IntegerParameter;
 import beast.core.parameter.Parameter;
+import beast.core.parameter.RealParameter;
 import beast.evolution.alignment.Alignment;
 import beast.evolution.tree.TraitSet;
 
@@ -307,6 +310,10 @@ public class JSONProducer {
                        buf.append(buf2);
                 }
                return;
+            } else if (input.getName().startsWith("*")) {
+                       // this can happen with private inputs, like in 
ThreadedTreeLikelihood
+                       // and * is not a valid XML attribute name
+               return;
             } else if (value instanceof List) {
                 if (!isShort) {
                        StringBuffer buf2 = new StringBuffer();
@@ -338,7 +345,7 @@ public class JSONProducer {
                        
                        // Parameters can use short hand notation if they are 
not in the state 
                        // Note this means lower and upper bounds are lost -- 
no problem for BEAST, but maybe for BEAUti
-                       if (value instanceof Parameter.Base) {
+                       if (value instanceof BooleanParameter || value 
instanceof IntegerParameter || value instanceof RealParameter) {
                                Parameter.Base parameter = (Parameter.Base) 
value;
                                boolean isInState = false;
                                for (Object o : parameter.getOutputs()) {
@@ -347,12 +354,16 @@ public class JSONProducer {
                                                break;
                                        }
                                }
-                               if (!isInState) {
-                                       if (isShort) {
-                                buf.append(" " + input.getName() + ": \"" + 
parameter.getValue() + "\"");
-                                       } else {
-                                               return;
-                                       }
+                               if (!isInState && parameter.getDimension() == 1 
&& parameter.getMinorDimension1() == 1) {
+                                       // if not in state, bounds do not matter
+                                       //if ((parameter instanceof 
RealParameter && parameter.getLower().equals(Double.NEGATIVE_INFINITY) && 
parameter.getUpper().equals(Double.POSITIVE_INFINITY)) ||
+                                       //      (parameter instanceof 
IntegerParameter && parameter.getLower().equals(Integer.MIN_VALUE + 1) && 
parameter.getUpper().equals(Integer.MAX_VALUE - 1))) {
+                                               if (isShort) {
+                                       buf.append(" " + input.getName() + ": 
\"" + parameter.getValue() + "\"");
+                                               } else {
+                                                       return;
+                                               }
+                                       //}
                                }
                        }
                        
diff --git a/src/beast/util/MersenneTwisterFast.java 
b/src/beast/util/MersenneTwisterFast.java
index 5071480..6a73d84 100644
--- a/src/beast/util/MersenneTwisterFast.java
+++ b/src/beast/util/MersenneTwisterFast.java
@@ -585,7 +585,7 @@ public class MersenneTwisterFast implements Serializable {
         // Check for invalid input values
 
         if (a <= 0.0) throw new IllegalArgumentException();
-        if (lambda <= 0.0) new IllegalArgumentException();
+        if (lambda <= 0.0) throw new IllegalArgumentException();
 
         if (a < 1.0) { // CASE A: Acceptance rejection algorithm gs
             b = 1.0 + 0.36788794412 * a;              // Step 1
@@ -750,7 +750,7 @@ public class MersenneTwisterFast implements Serializable {
      * @param lambda mean of Poissonian distribution
      * @return Draw from Pois(lambda). Note: returns a double for historical 
reasons.
      */
-    public double nextPoisson(double lambda) {
+    public long nextPoisson(double lambda) {
         if (lambda<12)
             return poissonian_icdf(lambda);
 
diff --git a/src/beast/util/NexusParser.java b/src/beast/util/NexusParser.java
index bf88ce9..290574e 100644
--- a/src/beast/util/NexusParser.java
+++ b/src/beast/util/NexusParser.java
@@ -435,7 +435,7 @@ public class NexusParser {
         //reading CHARSTATELABELS block
         if (str.toLowerCase().contains("charstatelabels")) {
             if (!alignment.dataTypeInput.get().equals("standard")) {
-                new Exception("If CHARSTATELABELS block is specified then 
DATATYPE has to be Standard");
+                throw new IllegalArgumentException("If CHARSTATELABELS block 
is specified then DATATYPE has to be Standard");
             }
             StandardData standardDataType = 
(StandardData)alignment.userDataTypeInput.get();
             int[] maxNumberOfStates = new int[] {0};
diff --git a/src/beast/util/Package.java b/src/beast/util/Package.java
index d0e6ac8..3c95e0c 100644
--- a/src/beast/util/Package.java
+++ b/src/beast/util/Package.java
@@ -175,7 +175,7 @@ public class Package {
         String depString = "";
         for (PackageDependency packageDependency : 
availableVersionDeps.lastEntry().getValue()) {
             String s = packageDependency.dependencyName;
-            if (!s.equalsIgnoreCase(AddOnManager.BEAST_PACKAGE)) {
+            if (!s.equalsIgnoreCase(AddOnManager.BEAST_PACKAGE_NAME)) {
                 depString +=  s + ", ";
             }
         }
diff --git a/src/beast/util/PackageDependency.java 
b/src/beast/util/PackageDependency.java
index e5c6208..9797843 100644
--- a/src/beast/util/PackageDependency.java
+++ b/src/beast/util/PackageDependency.java
@@ -45,7 +45,7 @@ public class PackageDependency {
                              PackageVersion minimumVersion,
                              PackageVersion maximumVersion) {
        if (dependencyName.equals("beast2")) {
-               dependencyName = AddOnManager.BEAST_PACKAGE;
+               dependencyName = AddOnManager.BEAST_PACKAGE_NAME;
        }
         this.dependencyName = dependencyName;
         
diff --git a/src/beast/util/Randomizer.java b/src/beast/util/Randomizer.java
index 5b83172..522148f 100644
--- a/src/beast/util/Randomizer.java
+++ b/src/beast/util/Randomizer.java
@@ -251,7 +251,7 @@ public class Randomizer {
      * @param lambda mean of Poissonian distribution
      * @return sample (as double for historical reasons)
      */
-    public static double nextPoisson(double lambda) {
+    public static long nextPoisson(double lambda) {
         synchronized (random) {
             return random.nextPoisson(lambda);
         }
diff --git a/src/beast/util/TreeParser.java b/src/beast/util/TreeParser.java
index 4e65d22..daa7cea 100644
--- a/src/beast/util/TreeParser.java
+++ b/src/beast/util/TreeParser.java
@@ -463,8 +463,9 @@ public class TreeParser extends Tree implements 
StateNodeInitialiser {
                                     
attribctx.attribValue().number().getText()));
                         } else if (attribctx.attribValue().STRING() != null) {
                             String stringValue = 
attribctx.attribValue().STRING().getText();
-                            if (stringValue.startsWith("\"") || 
stringValue.startsWith("\'"));
+                            if (stringValue.startsWith("\"") || 
stringValue.startsWith("\'")) {
                                 stringValue = stringValue.substring(1, 
stringValue.length()-1);
+                            }
                             node.setMetaData(key, stringValue);
                         } else {
                             // BEAST doesn't do anything with vectors yet.
diff --git a/src/beast/util/XMLProducer.java b/src/beast/util/XMLProducer.java
index 4d77783..0429ba9 100644
--- a/src/beast/util/XMLProducer.java
+++ b/src/beast/util/XMLProducer.java
@@ -946,6 +946,10 @@ public class XMLProducer extends XMLParser {
                        }
                 }
                return;
+            } else if (input.getName().startsWith("*")) {
+                       // this can happen with private inputs, like in 
ThreadedTreeLikelihood
+                       // and * is not a valid XML attribute name
+                       return;
             } else if (value instanceof List) {
                 if (!isShort) {
                        int k = 0;
diff --git a/src/test/beast/evolution/operator/DeltaExchangeOperatorTest.java 
b/src/test/beast/evolution/operator/DeltaExchangeOperatorTest.java
new file mode 100644
index 0000000..0801d65
--- /dev/null
+++ b/src/test/beast/evolution/operator/DeltaExchangeOperatorTest.java
@@ -0,0 +1,64 @@
+/**
+ * 
+ */
+package test.beast.evolution.operator;
+
+import org.junit.Test;
+
+import beast.core.State;
+import beast.core.parameter.IntegerParameter;
+import beast.core.parameter.RealParameter;
+import beast.evolution.operators.DeltaExchangeOperator;
+
+/**
+ * @author gereon
+ *
+ */
+public class DeltaExchangeOperatorTest extends TestOperator {
+
+       @Test
+       public void testKeepsSum() {
+               DeltaExchangeOperator operator = new DeltaExchangeOperator(); 
+               RealParameter parameter = new RealParameter(new Double[] {1., 
1., 1., 1.});
+               register(operator,
+                               "parameter", parameter);
+               for (int i=0; i<100; ++i) {
+                       operator.proposal();
+               }
+               double i = 0;
+               for (Double p : parameter.getValues()) {
+                       i += p;
+               }
+               assertEquals("The DeltaExchangeOperator should not change the 
sum of a parameter", i, 4, 0.00001);
+       }
+       
+       @Test
+       public void testKeepsWeightedSum() {
+               RealParameter parameter = new RealParameter(new Double[] {1., 
1., 1., 1.});
+               register(new DeltaExchangeOperator(),
+                               "weightvector", new IntegerParameter(new 
Integer[] {0, 1, 2, 1}),
+                               "parameter", parameter);
+               Double[] p = parameter.getValues();
+               assertEquals("The DeltaExchangeOperator should not change the 
sum of a parameter",
+                               0*p[1]+1*p[1]+2*p[2]+1*p[3], 4, 0.00001);
+       }
+       
+       @Test
+       public void testCanOperate() {
+               // Test whether a validly initialised operator may make 
proposals
+               State state = new State();
+               RealParameter parameter = new RealParameter(new Double[] { 1., 
1., 1., 1. });
+               state.initByName("stateNode", parameter);
+               state.initialise();
+               DeltaExchangeOperator d = new DeltaExchangeOperator();
+               // An invalid operator should either fail in initByName or make 
valid
+               // proposals
+               try {
+                       d.initByName("parameter", parameter);
+               } catch (RuntimeException e) {
+                       return;
+               }
+               d.proposal();
+       }
+
+}
diff --git a/src/test/beast/evolution/operator/TestOperator.java 
b/src/test/beast/evolution/operator/TestOperator.java
new file mode 100644
index 0000000..b7352d7
--- /dev/null
+++ b/src/test/beast/evolution/operator/TestOperator.java
@@ -0,0 +1,52 @@
+/**
+ * 
+ */
+package test.beast.evolution.operator;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+
+import beast.core.Operator;
+import beast.core.State;
+import beast.core.StateNode;
+import junit.framework.TestCase;
+
+/**
+ * @author gereon
+ *
+ */
+public abstract class TestOperator extends TestCase {
+
+       static public void register(Operator operator, final Object... 
operands) {
+               HashMap<String, StateNode> operandsMap;
+               operandsMap = new HashMap<String, StateNode>();
+               if (operands.length % 2 == 1) {
+                       throw new RuntimeException("Expected even number of 
arguments, name-value pairs");
+               }
+               for (int i = 0; i < operands.length; i += 2) {
+                       if (operands[i] instanceof String) {
+                               final String name = (String) operands[i];
+                               if (operands[i + 1] instanceof StateNode) {
+                                       final StateNode node = (StateNode) 
operands[i + 1];
+                                       operandsMap.put(name, node);
+                               } else {
+                                       throw new 
IllegalArgumentException("Expected a StateNode in " + (i + 1) + "th argument ");
+                               }
+                       } else {
+                               throw new IllegalArgumentException("Expected a 
String in " + i + "th argument ");
+                       }
+               }
+               State state = new State();
+               state.initByName("stateNode", new 
ArrayList<StateNode>(operandsMap.values()));
+               state.initialise();
+               Object[] operandsAndWeight = new Object[operands.length + 2];
+               for (int i = 0; i < operands.length; ++i) {
+                       operandsAndWeight[i] = operands[i];
+               }
+               operandsAndWeight[operands.length] = "weight";
+               operandsAndWeight[operands.length + 1] = "1";
+               operator.initByName(operandsAndWeight);
+               operator.validateInputs();
+       }
+}
diff --git a/src/test/beast/util/JSONTest.java 
b/src/test/beast/util/JSONTest.java
index 2257ea1..09ffdd8 100644
--- a/src/test/beast/util/JSONTest.java
+++ b/src/test/beast/util/JSONTest.java
@@ -35,7 +35,7 @@ public class JSONTest extends TestCase {
     @Test
     public void testJSONFragmentParsing() throws Exception {
        JSONParser parser = new JSONParser();
-       String json = "{version: \"2.3\",\n" + 
+       String json = "{version: \"2.4\",\n" + 
                        "\n" + 
                        "beast: [\n" + 
                        "{spec:\"beast.core.parameter.RealParameter\",\n" +
@@ -76,7 +76,7 @@ public class JSONTest extends TestCase {
        
        
        // test that default value for param1 comes through
-       String json2 = "{version: \"2.3\",\n" + 
+       String json2 = "{version: \"2.4\",\n" + 
                        "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\",\n"
 + 
                        "\n" + 
                        "beast: [\n" + 
@@ -103,7 +103,7 @@ public class JSONTest extends TestCase {
        
 
        // test that array of doubles comes through in second constructor
-       String json3 = "{version: \"2.3\",\n" + 
+       String json3 = "{version: \"2.4\",\n" + 
                        "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\",\n"
 + 
                        "\n" + 
                        "beast: [\n" + 
diff --git a/templates/ClockModels.xml b/templates/ClockModels.xml
index 7de69b4..80d1860 100644
--- a/templates/ClockModels.xml
+++ b/templates/ClockModels.xml
@@ -83,13 +83,13 @@
                 c:$(n)
             </connect>
             <connect srcID='ExpCategoriesRandomWalk.c:$(n)' targetID='mcmc' 
inputName='operator'
-                     if='inlikelihood(expRateCategories.c:$(n))'>Randomly 
change categories of partition c:$(n)
+                     if='inlikelihood(expRateCategories.c:$(n)) and 
expRateCategories.c:$(n)/estimate=true'>Randomly change categories of partition 
c:$(n)
             </connect>
             <connect srcID='ExpCategoriesSwapOperator.c:$(n)' targetID='mcmc' 
inputName='operator'
-                     if='inlikelihood(expRateCategories.c:$(n))'>Swap 
categories of partition c:$(n)
+                     if='inlikelihood(expRateCategories.c:$(n)) and 
expRateCategories.c:$(n)/estimate=true'>Swap categories of partition c:$(n)
             </connect>
             <connect srcID='ExpCategoriesUniform.c:$(n)' targetID='mcmc' 
inputName='operator'
-                     if='inlikelihood(expRateCategories.c:$(n))'>Uniformly 
draw categories of partition c:$(n)
+                     if='inlikelihood(expRateCategories.c:$(n)) and 
expRateCategories.c:$(n)/estimate=true'>Uniformly draw categories of partition 
c:$(n)
             </connect>
             <connect srcID='relaxedUpDownOperatorExp.c:$(n)' targetID='mcmc' 
inputName='operator'
                      if='nooperator(FixMeanRatesOperator) and 
inlikelihood(ucedMean.c:$(n)) and inlikelihood(Tree.t:$(n)) and 
ucedMean.c:$(n)/estimate=true and Tree.t:$(n)/estimate=true'>
@@ -161,16 +161,16 @@
                 c:$(n)
             </connect>
             <connect srcID='ucldStdevScaler.c:$(n)' targetID='mcmc' 
inputName='operator'
-                     if='inlikelihood(ucldStdev.c:$(n))'>Scale stdev of rate 
of partition c:$(n)
+                     if='inlikelihood(ucldStdev.c:$(n)) and 
ucldStdev.c:$(n)/estimate=true'>Scale stdev of rate of partition c:$(n)
             </connect>
             <connect srcID='CategoriesRandomWalk.c:$(n)' targetID='mcmc' 
inputName='operator'
-                     if='inlikelihood(rateCategories.c:$(n))'>Randomly change 
categories of partition c:$(n)
+                     if='inlikelihood(rateCategories.c:$(n)) and 
rateCategories.c:$(n)/estimate=true'>Randomly change categories of partition 
c:$(n)
             </connect>
             <connect srcID='CategoriesSwapOperator.c:$(n)' targetID='mcmc' 
inputName='operator'
-                     if='inlikelihood(rateCategories.c:$(n))'>Swap categories 
of partition c:$(n)
+                     if='inlikelihood(rateCategories.c:$(n)) and 
rateCategories.c:$(n)/estimate=true'>Swap categories of partition c:$(n)
             </connect>
             <connect srcID='CategoriesUniform.c:$(n)' targetID='mcmc' 
inputName='operator'
-                     if='inlikelihood(rateCategories.c:$(n))'>Uniformly draw 
categories of partition c:$(n)
+                     if='inlikelihood(rateCategories.c:$(n)) and 
rateCategories.c:$(n)/estimate=true'>Uniformly draw categories of partition 
c:$(n)
             </connect>
             <connect srcID='relaxedUpDownOperator.c:$(n)' targetID='mcmc' 
inputName='operator'
                      if='nooperator(FixMeanRatesOperator) and 
inlikelihood(ucldMean.c:$(n)) and ucldMean.c:$(n)/estimate=true and 
Tree.t:$(n)/estimate=true'>
diff --git a/templates/Standard.xml b/templates/Standard.xml
index 4ee839b..e8e79f2 100644
--- a/templates/Standard.xml
+++ b/templates/Standard.xml
@@ -331,7 +331,7 @@
             <distribution spec="CompoundDistribution" id="prior">
                                <mergepoint id='aux-priors'/>
             </distribution>
-            <distribution spec="CompoundDistribution" id="likelihood">
+            <distribution spec="CompoundDistribution" id="likelihood" 
useThreads="true">
                                <mergepoint id='aux-likelihoods'/>
             </distribution>
         </distribution>
diff --git a/templates/StarBeast.xml b/templates/StarBeast.xml
index a32718f..9929c92 100644
--- a/templates/StarBeast.xml
+++ b/templates/StarBeast.xml
@@ -161,7 +161,7 @@
                <alignmentProvider id="Import Alignment" 
spec='BeautiAlignmentProvider' template='@StarBEASTPartitionTemplate'/>
 
 
-        <partitiontemplate id='StarBEASTPartitionTemplate' 
spec='BeautiSubTemplate' class='beast.evolution.likelihood.TreeLikelihood' 
mainid='mcmc'>
+        <partitiontemplate id='StarBEASTPartitionTemplate' 
spec='BeautiSubTemplate' 
class='beast.evolution.likelihood.ThreadedTreeLikelihood' mainid='mcmc'>
 <![CDATA[
 
                    <distribution id='treePrior.t:$(n)' 
spec='GeneTreeForSpeciesTreeDistribution' tree='@Tree.t:$(n)' 
speciesTree='@Tree.t:Species' speciesTreePrior='@SpeciesTreePopSize.Species'/>
@@ -369,7 +369,7 @@
                            <distr spec="beast.math.distributions.OneOnX"/>
                        </distribution>
             </distribution>
-            <distribution spec="CompoundDistribution" id="likelihood">
+            <distribution spec="CompoundDistribution" id="likelihood" 
useThreads="true">
                                <mergepoint id='aux-likelihoods'/>
             </distribution>
         </distribution>
diff --git a/version.xml b/version.xml
index cc9b99b..9af90d5 100644
--- a/version.xml
+++ b/version.xml
@@ -1 +1 @@
-<addon name='BEAST' version='2.4.0' 
url="file:///Users/remco/tmp/BEAST.package.2.4.0.zip"/>
+<addon name='BEAST' version='2.4.0' 
url="https://github.com/CompEvol/beast2/releases/download/2.4.0pre/BEAST.v2.4.0.addon.zip"/>

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

_______________________________________________
debian-med-commit mailing list
[email protected]
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/debian-med-commit

Reply via email to